From 304dcd7a7f5c9ed1e00b11800b421c9eb54a6135 Mon Sep 17 00:00:00 2001 From: adriancole Date: Wed, 17 Apr 2013 18:09:33 -0700 Subject: [PATCH] added code and tests for geo-based write ops in ultradns --- .../ultradns/ws/UltraDNSWSExceptions.java | 11 + .../DirectionalRecordAndGeoGroupToXML.java | 123 +++++++++ .../UpdateDirectionalDNSGroupToXML.java | 73 ++++++ .../ultradns/ws/domain/DirectionalPool.java | 12 - .../ultradns/ws/domain/RoundRobinPool.java | 24 ++ .../ws/domain/TrafficControllerPool.java | 4 + .../ws/features/DirectionalGroupApi.java | 7 +- .../ws/features/DirectionalPoolApi.java | 179 ++++++++++++- .../ws/features/RoundRobinPoolApi.java | 37 +-- .../ws/features/TrafficControllerPoolApi.java | 13 +- .../ws/handlers/UltraDNSWSErrorHandler.java | 21 +- .../DirectionalPoolRecordTypeToString.java | 53 ++++ .../RoundRobinPoolRecordTypeToString.java | 43 ++++ ...afficControllerPoolRecordTypeToString.java | 46 ++++ .../ultradns/ws/xml/ElementTextHandler.java | 12 + .../DirectionalGroupApiExpectTest.java | 2 +- .../features/DirectionalGroupApiLiveTest.java | 13 +- .../DirectionalPoolApiExpectTest.java | 152 ++++++++++- .../features/DirectionalPoolApiLiveTest.java | 235 ++++++++++++++++-- .../features/ResourceRecordApiLiveTest.java | 15 +- .../features/RoundRobinPoolApiExpectTest.java | 13 +- .../features/RoundRobinPoolApiLiveTest.java | 30 +-- .../TrafficControllerPoolApiExpectTest.java | 28 +-- .../TrafficControllerPoolApiLiveTest.java | 15 +- .../ultradns/ws/features/ZoneApiLiveTest.java | 25 +- .../handlers/UltraDNSWSErrorHandlerTest.java | 49 ++++ .../internal/BaseDirectionalApiLiveTest.java | 183 ++++++++++++++ .../internal/BaseUltraDNSWSApiLiveTest.java | 44 ++++ .../test/resources/create_directionalpool.xml | 1 + .../resources/create_directionalrecord.xml | 1 + ...create_directionalrecord_existinggroup.xml | 1 + .../create_directionalrecord_newgroup.xml | 1 + .../resources/delete_directionalrecord.xml | 1 + .../resources/directionalgroup_overlap.xml | 16 ++ .../directionalpool_already_exists.xml | 18 ++ .../resources/directionalpool_created.xml | 8 + .../resources/directionalpool_deleted.xml | 8 + .../directionalrecord_already_exists.xml | 16 ++ .../resources/directionalrecord_created.xml | 9 + .../resources/directionalrecord_deleted.xml | 8 + .../directionalrecord_doesnt_exist.xml | 16 ++ .../resources/directionalrecord_updated.xml | 8 + .../resources/update_directionalrecord.xml | 1 + .../update_directionalrecord_group.xml | 1 + 44 files changed, 1402 insertions(+), 174 deletions(-) create mode 100644 providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/binders/DirectionalRecordAndGeoGroupToXML.java create mode 100644 providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/binders/UpdateDirectionalDNSGroupToXML.java create mode 100644 providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/internal/DirectionalPoolRecordTypeToString.java create mode 100644 providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/internal/RoundRobinPoolRecordTypeToString.java create mode 100644 providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/internal/TrafficControllerPoolRecordTypeToString.java create mode 100644 providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/internal/BaseDirectionalApiLiveTest.java create mode 100644 providers/ultradns-ws/src/test/resources/create_directionalpool.xml create mode 100644 providers/ultradns-ws/src/test/resources/create_directionalrecord.xml create mode 100644 providers/ultradns-ws/src/test/resources/create_directionalrecord_existinggroup.xml create mode 100644 providers/ultradns-ws/src/test/resources/create_directionalrecord_newgroup.xml create mode 100644 providers/ultradns-ws/src/test/resources/delete_directionalrecord.xml create mode 100644 providers/ultradns-ws/src/test/resources/directionalgroup_overlap.xml create mode 100644 providers/ultradns-ws/src/test/resources/directionalpool_already_exists.xml create mode 100644 providers/ultradns-ws/src/test/resources/directionalpool_created.xml create mode 100644 providers/ultradns-ws/src/test/resources/directionalpool_deleted.xml create mode 100644 providers/ultradns-ws/src/test/resources/directionalrecord_already_exists.xml create mode 100644 providers/ultradns-ws/src/test/resources/directionalrecord_created.xml create mode 100644 providers/ultradns-ws/src/test/resources/directionalrecord_deleted.xml create mode 100644 providers/ultradns-ws/src/test/resources/directionalrecord_doesnt_exist.xml create mode 100644 providers/ultradns-ws/src/test/resources/directionalrecord_updated.xml create mode 100644 providers/ultradns-ws/src/test/resources/update_directionalrecord.xml create mode 100644 providers/ultradns-ws/src/test/resources/update_directionalrecord_group.xml diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSExceptions.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSExceptions.java index f9bbf765da..eee59d28c6 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSExceptions.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSExceptions.java @@ -36,4 +36,15 @@ public interface UltraDNSWSExceptions { super(message, cause); } } + + /** + * Error 7021: Geolocation/Source IP overlap(s) found: Region: Utah (Group: US ) + */ + public static class DirectionalGroupOverlapException extends IllegalStateException { + private static final long serialVersionUID = 1L; + + public DirectionalGroupOverlapException(String message, Throwable cause) { + super(message, cause); + } + } } diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/binders/DirectionalRecordAndGeoGroupToXML.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/binders/DirectionalRecordAndGeoGroupToXML.java new file mode 100644 index 0000000000..0358ab2a0d --- /dev/null +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/binders/DirectionalRecordAndGeoGroupToXML.java @@ -0,0 +1,123 @@ +/** + * 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 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 org.jclouds.ultradns.ws.binders; + +import static java.lang.String.format; + +import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; + +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.MapBinder; +import org.jclouds.ultradns.ws.domain.DirectionalGroup; +import org.jclouds.ultradns.ws.domain.DirectionalPoolRecord; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Joiner; + +/** + * + * @author Adrian Cole + */ +public class DirectionalRecordAndGeoGroupToXML implements MapBinder { + + @SuppressWarnings("unchecked") + @Override + public R bindToRequest(R request, Map postParams) { + DirectionalPoolRecord record = DirectionalPoolRecord.class.cast(postParams.get("record")); + DirectionalGroup group = DirectionalGroup.class.cast(postParams.get("group")); + String xml = toXML(postParams.get("poolId"), record, group, postParams.get("dirPoolRecordId"), + postParams.get("groupId")); + return (R) request.toBuilder().payload(xml).build(); + } + + private static final String ADD_TEMPLATE = "%s%s%s"; + private static final String UPDATE_TEMPLATE = "%s%s"; + private static final String NEWGROUP_TEMPLATE = "%s"; + private static final String EXISTINGGROUP_TEMPLATE = "%s"; + + @VisibleForTesting + static String toXML(Object poolId, DirectionalPoolRecord record, DirectionalGroup group, Object recordId, + Object groupId) { + if (poolId == null) { + if (group != null) + return format(UPDATE_TEMPLATE, recordId, updateRecord(record), geo(group)); + return format(UPDATE_TEMPLATE, recordId, updateRecord(record), ""); + } + if (group == null && groupId == null) { + return format( + ADD_TEMPLATE, + format("", poolId), + createRecord(record), ""); + } + String addRecordToPool = format("", poolId); + if (groupId != null) { + return format(ADD_TEMPLATE, addRecordToPool, createRecord(record), format(EXISTINGGROUP_TEMPLATE, groupId, "")); + } + return format(ADD_TEMPLATE, addRecordToPool, createRecord(record), format(NEWGROUP_TEMPLATE, geo(group))); + } + + private static String createRecord(DirectionalPoolRecord record) { + StringBuilder recordConfig = new StringBuilder(); + recordConfig.append(""); + recordConfig.append(values(record)); + recordConfig.append(""); + return recordConfig.toString(); + } + + /** + * don't pass type or is no response when updating + */ + private static String updateRecord(DirectionalPoolRecord record) { + return format("%s", record.getTTL(), + values(record)); + } + + private static String values(DirectionalPoolRecord record) { + StringBuilder values = new StringBuilder(""); + return values.toString(); + } + + private static String geo(DirectionalGroup group) { + StringBuilder groupData = new StringBuilder(); + groupData.append(""); + for (Entry> region : group.asMap().entrySet()) { + groupData.append(""); + } + groupData.append(""); + return groupData.toString(); + } + + @Override + public R bindToRequest(R request, Object input) { + throw new UnsupportedOperationException("use map form"); + } +} diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/binders/UpdateDirectionalDNSGroupToXML.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/binders/UpdateDirectionalDNSGroupToXML.java new file mode 100644 index 0000000000..bd1f81fb22 --- /dev/null +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/binders/UpdateDirectionalDNSGroupToXML.java @@ -0,0 +1,73 @@ +/** + * 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 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 org.jclouds.ultradns.ws.binders; + +import static java.lang.String.format; + +import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; + +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.MapBinder; +import org.jclouds.ultradns.ws.domain.DirectionalGroup; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Joiner; + +/** + * + * @author Adrian Cole + */ +public class UpdateDirectionalDNSGroupToXML implements MapBinder { + + @SuppressWarnings("unchecked") + @Override + public R bindToRequest(R request, Map postParams) { + DirectionalGroup group = DirectionalGroup.class.cast(postParams.get("group")); + String xml = toXML(postParams.get("dirPoolRecordId"), group); + return (R) request.toBuilder().payload(xml).build(); + } + + private static final String template = "%s%s"; + + @VisibleForTesting + static String toXML(Object dirPoolRecordId, DirectionalGroup group) { + return format(template, dirPoolRecordId, geo(group)); + } + + private static String geo(DirectionalGroup group) { + StringBuilder groupData = new StringBuilder(); + groupData.append(""); + for (Entry> region : group.asMap().entrySet()) { + groupData.append(""); + } + groupData.append(""); + return groupData.toString(); + } + + @Override + public R bindToRequest(R request, Object input) { + throw new UnsupportedOperationException("use map form"); + } +} diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/DirectionalPool.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/DirectionalPool.java index b029262230..badf374640 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/DirectionalPool.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/DirectionalPool.java @@ -112,18 +112,6 @@ public final class DirectionalPool { MX(15); - @Override - public String toString() { - switch (this) { - case IPV4: - return "A"; - case IPV6: - return "AAAA"; - default: - return super.toString(); - } - } - private final int code; private RecordType(int code) { diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/RoundRobinPool.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/RoundRobinPool.java index 23cb3d2634..dc4eac3213 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/RoundRobinPool.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/RoundRobinPool.java @@ -68,6 +68,30 @@ public final class RoundRobinPool { return dname; } + /** + * currently supported {@link ResourceRecord#getType() types} for round robin pools. + * + */ + public static enum RecordType { + A(1), + AAAA(28); + + @Override + public String toString() { + return String.valueOf(code); + } + + private final int code; + + private RecordType(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + } + @Override public int hashCode() { return Objects.hashCode(zoneId, id, name, dname); diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/TrafficControllerPool.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/TrafficControllerPool.java index eecc6a50ef..64734f3b94 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/TrafficControllerPool.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/TrafficControllerPool.java @@ -121,6 +121,10 @@ public final class TrafficControllerPool { private RecordType(int code) { this.code = code; } + + public int getCode() { + return code; + } } @Override diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalGroupApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalGroupApi.java index 1517740978..b8b262015f 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalGroupApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalGroupApi.java @@ -36,6 +36,7 @@ import org.jclouds.ultradns.ws.binders.DirectionalGroupCoordinatesToXML; import org.jclouds.ultradns.ws.domain.AccountLevelGroup; import org.jclouds.ultradns.ws.domain.DirectionalGroup; import org.jclouds.ultradns.ws.domain.DirectionalGroupCoordinates; +import org.jclouds.ultradns.ws.domain.DirectionalPool.RecordType; import org.jclouds.ultradns.ws.domain.DirectionalPoolRecordDetail; import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; import org.jclouds.ultradns.ws.xml.AccountLevelGroupsHandler; @@ -103,9 +104,7 @@ public interface DirectionalGroupApi { * @param hostName * fully qualified hostname including the trailing dot. * @param rrType - * type value, with special casing: for {@code A} or {@code CNAME} - * of ipv4 hosts, this is {@code 1}; for {@code AAAA} or - * {@code CNAME} of ipv4 hosts, this is {@code 28} + * {@link RecordType type} value of the existing records. * @return empty if there are not groups for the specified host and type */ @Named("getAvailableGroups") @@ -113,7 +112,7 @@ public interface DirectionalGroupApi { @XMLResponseParser(ItemListHandler.class) @Fallback(EmptyFluentIterableOnNotFoundOr404.class) @Payload("{hostName}{rrType}{accountId}") - FluentIterable listGroupNamesByRecordNameAndType( + FluentIterable listGroupNamesByDNameAndType( @PayloadParam("hostName") String hostName, @PayloadParam("rrType") int rrType); /** diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalPoolApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalPoolApi.java index ce33849be2..1b7457ac25 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalPoolApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalPoolApi.java @@ -18,22 +18,35 @@ */ package org.jclouds.ultradns.ws.features; + import javax.inject.Named; import javax.ws.rs.POST; import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404; +import org.jclouds.Fallbacks.VoidOnNotFoundOr404; import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.MapBinder; +import org.jclouds.rest.annotations.ParamParser; import org.jclouds.rest.annotations.Payload; import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.ultradns.ws.UltraDNSWSApi; +import org.jclouds.ultradns.ws.UltraDNSWSExceptions.DirectionalGroupOverlapException; +import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; +import org.jclouds.ultradns.ws.binders.DirectionalRecordAndGeoGroupToXML; +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.DirectionalPoolRecord; import org.jclouds.ultradns.ws.domain.DirectionalPoolRecordDetail; import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; +import org.jclouds.ultradns.ws.internal.DirectionalPoolRecordTypeToString; import org.jclouds.ultradns.ws.xml.DirectionalPoolListHandler; import org.jclouds.ultradns.ws.xml.DirectionalPoolRecordDetailListHandler; +import org.jclouds.ultradns.ws.xml.ElementTextHandler; import com.google.common.collect.FluentIterable; @@ -62,23 +75,175 @@ public interface DirectionalPoolApi { * Returns all the directional pool records in the zone with the fully * qualified {@link hostName} and {@link rrType} * - * @param hostName + * @param dname * fully qualified hostname including the trailing dot. * @param rrType - * type value, with special casing: for {@code A} or {@code CNAME} - * of ipv4 hosts, this is {@code 1}; for {@code AAAA} or - * {@code CNAME} of ipv4 hosts, this is {@code 28} + * {@link RecordType type} value of the existing records. * @return empty if there are not pools for the specified host or no records * exist for the type. * @throws ResourceNotFoundException * if the zone doesn't exist + * @see RecordType#getCode() */ @Named("getDirectionalDNSRecordsForHost") @POST @XMLResponseParser(DirectionalPoolRecordDetailListHandler.class) @Fallback(EmptyFluentIterableOnNotFoundOr404.class) @Payload("{zoneName}{hostName}{poolRecordType}") - FluentIterable listRecordsByNameAndType( - @PayloadParam("hostName") String dname, @PayloadParam("poolRecordType") int type) - throws ResourceNotFoundException; + FluentIterable listRecordsByDNameAndType(@PayloadParam("hostName") String dname, + @PayloadParam("poolRecordType") int rrType) throws ResourceNotFoundException; + + /** + * creates a directional pool for {@code A} and {@code CNAME} (ipv4) records + * + * @param name + * {@link DirectionalPool#getName() description} of the Geo pool + * @param dname + * {@link DirectionalPool#getDName() dname} of the Geo pool {ex. + * www.jclouds.org.} + * @param rrType + * {@link RecordType type} value for the records added to this + * pool.. + * @return the {@link DirectionalPool#getId() id} of the new pool + * @throws ResourceAlreadyExistsException + * if a pool already exists with the same attrs + */ + @Named("addDirectionalPool") + @POST + @XMLResponseParser(ElementTextHandler.DirPoolID.class) + @Payload("") + String createForDNameAndType(@PayloadParam("description") String name, @PayloadParam("hostName") String dname, + @PayloadParam("poolRecordType") @ParamParser(DirectionalPoolRecordTypeToString.class) int rrType) + throws ResourceAlreadyExistsException; + + /** + * creates a resource record in the pool. + * + * @param poolId + * pool to create the record in. + * @param toCreate + * the new record to create. + * @param group + * geo groups associated. Use the + * {@link UltraDNSWSApi#getRegionsByIdAndName()} to obtain the + * regionName and territoryNames. To specify all of a region’s + * territories, use + * {@link DirectionalGroup.Builder#mapRegion(String)} + * @return the {@link DirectionalPoolRecordDetail#getId() id} of the new record + * @throws ResourceAlreadyExistsException + * if a record already exists with the same attrs + */ + @Named("addDirectionalPoolRecord") + @POST + @XMLResponseParser(ElementTextHandler.DirectionalPoolRecordID.class) + @MapBinder(DirectionalRecordAndGeoGroupToXML.class) + String addRecordIntoNewGroup(@PayloadParam("poolId") String poolId, + @PayloadParam("record") DirectionalPoolRecord toCreate, @PayloadParam("group") DirectionalGroup group) + throws ResourceAlreadyExistsException; + + /** + * creates a resource record in the pool. + * + * @param poolId + * pool to create the record in. + * @param toCreate + * the new record to create. + * @param groupId + * existing group from another record of the same dname and type. + * For example + * {@link DirectionalPoolRecordDetail#getGeolocationGroup()} or + * {@link DirectionalPoolRecordDetail#getGroup()}. + * @return the {@link DirectionalPoolRecordDetail#getId() id} of the new record + * @throws ResourceAlreadyExistsException + * if a record already exists with the same attrs + */ + @Named("addDirectionalPoolRecord") + @POST + @XMLResponseParser(ElementTextHandler.DirectionalPoolRecordID.class) + @MapBinder(DirectionalRecordAndGeoGroupToXML.class) + String addRecordIntoExistingGroup(@PayloadParam("poolId") String poolId, + @PayloadParam("record") DirectionalPoolRecord toCreate, @PayloadParam("groupId") String groupId) + throws ResourceAlreadyExistsException; + + /** + * creates a resource record in the pool, creating and assigning it to the + * special "non configured group". + * + * @param poolId + * pool to create the record in. + * @param toCreate + * the new record to create. + * @return the {@link DirectionalPoolRecordDetail#getId() id} of the new record + * @throws ResourceAlreadyExistsException + * if a record already exists with the same attrs + */ + @Named("addDirectionalPoolRecord") + @POST + @XMLResponseParser(ElementTextHandler.DirectionalPoolRecordID.class) + @MapBinder(DirectionalRecordAndGeoGroupToXML.class) + String addFirstRecordInNonConfiguredGroup(@PayloadParam("poolId") String poolId, + @PayloadParam("record") DirectionalPoolRecord toCreate) throws ResourceAlreadyExistsException; + + /** + * updates such as ttl or rdata for an existing directional record. + * + * @param recordId + * id of the record to update + * @param update + * the updated record. + * @throws ResourceNotFoundException + * if the record doesn't exist + */ + @Named("updateDirectionalPoolRecord") + @POST + @MapBinder(DirectionalRecordAndGeoGroupToXML.class) + void updateRecord(@PayloadParam("dirPoolRecordId") String recordId, + @PayloadParam("record") DirectionalPoolRecord update) throws ResourceNotFoundException; + + /** + * updates the geo groups of an existing directional record. + * + * @param recordId + * id of the record to update + * @param update + * the updated record. + * @param group + * geo groups associated. + * @throws ResourceNotFoundException + * if the record doesn't exist + * @throws DirectionalGroupOverlapException + * if there's an overlap with another record in the pool. (ex. + * have the same territories) + */ + @Named("updateDirectionalPoolRecord") + @POST + @MapBinder(DirectionalRecordAndGeoGroupToXML.class) + void updateRecordAndGroup(@PayloadParam("dirPoolRecordId") String recordId, + @PayloadParam("record") DirectionalPoolRecord update, @PayloadParam("group") DirectionalGroup group) + throws ResourceNotFoundException, DirectionalGroupOverlapException; + + /** + * deletes a specific directional pool record + * + * @param id + * the {@link DirectionalPoolRecordDetail#getId() id} of the + * record. + */ + @Named("deleteResourceRecord") + @POST + @Payload("{dirPoolRecordId}") + @Fallback(VoidOnNotFoundOr404.class) + void deleteRecord(@PayloadParam("dirPoolRecordId") String id); + + /** + * removes a pool and all its records + * + * @param id + * the {@link DirectionalPool#getId() id} + */ + @Named("deleteDirectionalPool") + @POST + @Payload("{dirPoolID}") + @Fallback(VoidOnNotFoundOr404.class) + void delete(@PayloadParam("dirPoolID") String id); } diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApi.java index fedf379117..74590b89cd 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApi.java @@ -24,6 +24,7 @@ import javax.ws.rs.POST; import org.jclouds.Fallbacks.VoidOnNotFoundOr404; import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.ParamParser; import org.jclouds.rest.annotations.Payload; import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; @@ -34,6 +35,7 @@ import org.jclouds.ultradns.ws.domain.ResourceRecord; import org.jclouds.ultradns.ws.domain.ResourceRecordDetail; import org.jclouds.ultradns.ws.domain.RoundRobinPool; import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; +import org.jclouds.ultradns.ws.internal.RoundRobinPoolRecordTypeToString; import org.jclouds.ultradns.ws.xml.ElementTextHandler; import org.jclouds.ultradns.ws.xml.ResourceRecordListHandler; import org.jclouds.ultradns.ws.xml.RoundRobinPoolListHandler; @@ -75,13 +77,15 @@ public interface RoundRobinPoolApi { throws ResourceNotFoundException; /** - * creates a round robin pool for {@code A} (ipv4) records + * creates a round robin pool. * * @param name * {@link RoundRobinPool#getName() name} of the RR pool * @param dname * {@link RoundRobinPool#getDName() dname} of the RR pool {ex. * www.jclouds.org.} + * @param rrType + * the {@link RoundRobinPool.RecordType record type} supported. * @return the {@code guid} of the new pool * @throws ResourceAlreadyExistsException * if a pool already exists with the same attrs @@ -89,9 +93,10 @@ public interface RoundRobinPoolApi { @Named("addRRLBPool") @POST @XMLResponseParser(ElementTextHandler.RRPoolID.class) - @Payload("{zoneName}{hostName}{description}1") - String createAPoolForDName(@PayloadParam("description") String name, - @PayloadParam("hostName") String dname) throws ResourceAlreadyExistsException; + @Payload("{zoneName}{hostName}{description}{poolRecordType}") + String createForDNameAndType(@PayloadParam("description") String name, @PayloadParam("hostName") String dname, + @PayloadParam("poolRecordType") @ParamParser(RoundRobinPoolRecordTypeToString.class) int rrType) + throws ResourceAlreadyExistsException; /** * adds a new {@code A} record to the pool @@ -133,9 +138,8 @@ public interface RoundRobinPoolApi { @Named("updateRecordOfRRPool") @POST @Payload("") - void updateRecordWithAddressAndTTL(@PayloadParam("lbPoolID") String lbPoolID, - @PayloadParam("guid") String guid, @PayloadParam("address") String ipv4Address, - @PayloadParam("ttl") int ttl) throws ResourceNotFoundException; + void updateRecordWithAddressAndTTL(@PayloadParam("lbPoolID") String lbPoolID, @PayloadParam("guid") String guid, + @PayloadParam("address") String ipv4Address, @PayloadParam("ttl") int ttl) throws ResourceNotFoundException; /** * deletes a specific pooled resource record @@ -150,25 +154,6 @@ public interface RoundRobinPoolApi { @Fallback(VoidOnNotFoundOr404.class) void deleteRecord(@PayloadParam("guid") String guid); - /** - * creates a round robin pool for {@code AAAA} (ipv6) records - * - * @param name - * {@link RoundRobinPool#getName() name} of the RR pool - * @param dname - * {@link RoundRobinPool#getDName() dname} {ex. - * www.jclouds.org.} - * @return the {@code guid} of the new record - * @throws ResourceAlreadyExistsException - * if a pool already exists with the same attrs - */ - @Named("addRRLBPool") - @POST - @XMLResponseParser(ElementTextHandler.RRPoolID.class) - @Payload("{zoneName}{hostName}{description}28") - String createAAAAPoolForDName(@PayloadParam("description") String name, - @PayloadParam("hostName") String dname) throws ResourceAlreadyExistsException; - /** * adds a new {@code AAAA} record to the pool * diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApi.java index 713bc2f0ba..a257391f49 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApi.java @@ -27,6 +27,7 @@ import org.jclouds.javax.annotation.Nullable; import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.rest.annotations.Fallback; import org.jclouds.rest.annotations.MapBinder; +import org.jclouds.rest.annotations.ParamParser; import org.jclouds.rest.annotations.Payload; import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; @@ -36,10 +37,10 @@ import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsExcepti import org.jclouds.ultradns.ws.binders.UpdatePoolRecordToXML; import org.jclouds.ultradns.ws.domain.PoolRecordSpec; import org.jclouds.ultradns.ws.domain.TrafficControllerPool; -import org.jclouds.ultradns.ws.domain.TrafficControllerPool.RecordType; import org.jclouds.ultradns.ws.domain.TrafficControllerPoolRecordDetail; import org.jclouds.ultradns.ws.domain.UpdatePoolRecord; import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; +import org.jclouds.ultradns.ws.internal.TrafficControllerPoolRecordTypeToString; import org.jclouds.ultradns.ws.xml.AttributeHandler; import org.jclouds.ultradns.ws.xml.ElementTextHandler; import org.jclouds.ultradns.ws.xml.PoolRecordSpecHandler; @@ -65,8 +66,9 @@ public interface TrafficControllerPoolApi { * @param dname * {@link TrafficControllerPool#getDName() dname} of the TC pool * {ex. www.jclouds.org.} - * @param type - * the record types supported. + * @param rrType + * the {@link TrafficControllerPool.RecordType record type} + * supported. * @return the {@code guid} of the new record * @throws ResourceAlreadyExistsException * if a pool already exists with the same attrs @@ -75,8 +77,9 @@ public interface TrafficControllerPoolApi { @POST @XMLResponseParser(ElementTextHandler.TCPoolID.class) @Payload("{zoneName}{hostName}{description}{poolRecordType}EnabledEnabled0") - String createPoolForDNameAndType(@PayloadParam("description") String name, @PayloadParam("hostName") String dname, - @PayloadParam("poolRecordType") RecordType type) throws ResourceAlreadyExistsException; + String createForDNameAndType(@PayloadParam("description") String name, @PayloadParam("hostName") String dname, + @PayloadParam("poolRecordType") @ParamParser(TrafficControllerPoolRecordTypeToString.class) int rrType) + throws ResourceAlreadyExistsException; /** * Returns all traffic controller pools in the zone. diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandler.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandler.java index dc0f4daafd..647db520b0 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandler.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandler.java @@ -31,6 +31,7 @@ import org.jclouds.http.HttpResponseException; import org.jclouds.http.functions.ParseSax.Factory; import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.ultradns.ws.UltraDNSWSError; +import org.jclouds.ultradns.ws.UltraDNSWSExceptions.DirectionalGroupOverlapException; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; import org.jclouds.ultradns.ws.UltraDNSWSResponseException; import org.jclouds.ultradns.ws.xml.UltraWSExceptionHandler; @@ -97,11 +98,15 @@ public class UltraDNSWSErrorHandler implements HttpErrorHandler { /** * No Pool or Multiple pools of same type exists for the PoolName */ - static final int DIRECTIONAL_POOL_NOT_FOUND = 2142; + static final int DIRECTIONALPOOL_NOT_FOUND = 2142; /** * Account not found in the system. */ static final int ACCOUNT_NOT_FOUND = 2401; + /** + * Directional Pool Record does not exist in the system + */ + static final int DIRECTIONALPOOL_RECORD_NOT_FOUND = 2705; /** * Pool does not exist in the system. */ @@ -118,6 +123,14 @@ public class UltraDNSWSErrorHandler implements HttpErrorHandler { * Group does not exist. */ static final int GROUP_NOT_FOUND = 4003; + /** + * Resource Record already exists. + */ + static final int POOL_RECORD_ALREADY_EXISTS = 4009; + /** + * Geolocation/Source IP overlap(s) found + */ + static final int DIRECTIONALPOOL_OVERLAP = 7021; } private Exception refineException(UltraDNSWSResponseException exception) { @@ -132,14 +145,18 @@ public class UltraDNSWSErrorHandler implements HttpErrorHandler { case ErrorCodes.RESOURCE_RECORD_NOT_FOUND: case ErrorCodes.ACCOUNT_NOT_FOUND: case ErrorCodes.POOL_NOT_FOUND: - case ErrorCodes.DIRECTIONAL_POOL_NOT_FOUND: + case ErrorCodes.DIRECTIONALPOOL_NOT_FOUND: + case ErrorCodes.DIRECTIONALPOOL_RECORD_NOT_FOUND: case ErrorCodes.POOL_RECORD_NOT_FOUND: case ErrorCodes.GROUP_NOT_FOUND: return new ResourceNotFoundException(message, exception); case ErrorCodes.ZONE_ALREADY_EXISTS: case ErrorCodes.RESOURCE_RECORD_ALREADY_EXISTS: case ErrorCodes.POOL_ALREADY_EXISTS: + case ErrorCodes.POOL_RECORD_ALREADY_EXISTS: return new ResourceAlreadyExistsException(message, exception); + case ErrorCodes.DIRECTIONALPOOL_OVERLAP: + return new DirectionalGroupOverlapException(message, exception); } return exception; } diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/internal/DirectionalPoolRecordTypeToString.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/internal/DirectionalPoolRecordTypeToString.java new file mode 100644 index 0000000000..475acf67a7 --- /dev/null +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/internal/DirectionalPoolRecordTypeToString.java @@ -0,0 +1,53 @@ +/** + * 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 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 org.jclouds.ultradns.ws.internal; + +import java.util.EnumSet; + +import javax.inject.Inject; + +import org.jclouds.ultradns.ws.domain.DirectionalPool.RecordType; + +import com.google.common.base.Function; + +/** + * pools use the address type also for cnames. + */ +public class DirectionalPoolRecordTypeToString implements Function { + @Inject + private DirectionalPoolRecordTypeToString() { + } + + public String apply(Object in) { + int rrType = Integer.class.cast(in); + for (RecordType type : EnumSet.allOf(RecordType.class)) { + if (type.getCode() == rrType) { + switch (type) { + case IPV4: + return "A"; + case IPV6: + return "AAAA"; + default: + return type.toString(); + } + } + } + throw new IllegalArgumentException("unsupported rrType " + rrType + " please see " + RecordType.class.getName()); + } +} diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/internal/RoundRobinPoolRecordTypeToString.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/internal/RoundRobinPoolRecordTypeToString.java new file mode 100644 index 0000000000..ae4aa5d4c6 --- /dev/null +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/internal/RoundRobinPoolRecordTypeToString.java @@ -0,0 +1,43 @@ +/** + * 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 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 org.jclouds.ultradns.ws.internal; + +import java.util.EnumSet; + +import javax.inject.Inject; + +import org.jclouds.ultradns.ws.domain.RoundRobinPool.RecordType; + +import com.google.common.base.Function; + +public class RoundRobinPoolRecordTypeToString implements Function { + @Inject + private RoundRobinPoolRecordTypeToString() { + } + + public String apply(Object in) { + int rrType = Integer.class.cast(in); + for (RecordType type : EnumSet.allOf(RecordType.class)) { + if (type.getCode() == rrType) { + return Integer.toString(rrType); + } + } + throw new IllegalArgumentException("unsupported rrType " + rrType + " please see " + RecordType.class.getName()); + } +} diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/internal/TrafficControllerPoolRecordTypeToString.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/internal/TrafficControllerPoolRecordTypeToString.java new file mode 100644 index 0000000000..39cab08ffd --- /dev/null +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/internal/TrafficControllerPoolRecordTypeToString.java @@ -0,0 +1,46 @@ +/** + * 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 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 org.jclouds.ultradns.ws.internal; + +import java.util.EnumSet; + +import javax.inject.Inject; + +import org.jclouds.ultradns.ws.domain.TrafficControllerPool.RecordType; + +import com.google.common.base.Function; + +/** + * pools use the address type also for cnames. + */ +public class TrafficControllerPoolRecordTypeToString implements Function { + @Inject + private TrafficControllerPoolRecordTypeToString() { + } + + public String apply(Object in) { + int rrType = Integer.class.cast(in); + for (RecordType type : EnumSet.allOf(RecordType.class)) { + if (type.getCode() == rrType) { + return Integer.toString(rrType); + } + } + throw new IllegalArgumentException("unsupported rrType " + rrType + " please see " + RecordType.class.getName()); + } +} diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/ElementTextHandler.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/ElementTextHandler.java index 3fa4fa939d..66fc90ca83 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/ElementTextHandler.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/ElementTextHandler.java @@ -54,6 +54,18 @@ public abstract class ElementTextHandler extends ParseSax.HandlerForGeneratedReq } } + public static class DirPoolID extends ElementTextHandler { + public DirPoolID() { + super("DirPoolID"); + } + } + + public static class DirectionalPoolRecordID extends ElementTextHandler { + public DirectionalPoolRecordID() { + super("DirectionalPoolRecordID"); + } + } + private final String textElement; private StringBuilder currentText = new StringBuilder(); diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalGroupApiExpectTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalGroupApiExpectTest.java index c65bb42dcf..fb0b7cc66a 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalGroupApiExpectTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalGroupApiExpectTest.java @@ -51,7 +51,7 @@ public class DirectionalGroupApiExpectTest extends BaseUltraDNSWSApiExpectTest { public void testListGroupNamesByRecordNameAndTypeWhenResponseIs2xx() { UltraDNSWSApi success = requestSendsResponse(listGroupNamesByRecordNameAndType, listGroupNamesByRecordNameAndTypeResponse); - assertEquals(success.getDirectionalGroupApiForAccount("accountid").listGroupNamesByRecordNameAndType("www.jclouds.org.", 1).toString(), + assertEquals(success.getDirectionalGroupApiForAccount("accountid").listGroupNamesByDNameAndType("www.jclouds.org.", 1).toString(), new GetAvailableGroupsResponseTest().expected().toString()); } diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalGroupApiLiveTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalGroupApiLiveTest.java index 2413789ba5..689e36afca 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalGroupApiLiveTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalGroupApiLiveTest.java @@ -32,10 +32,8 @@ import org.jclouds.ultradns.ws.domain.DirectionalGroupCoordinates; import org.jclouds.ultradns.ws.domain.DirectionalPool; import org.jclouds.ultradns.ws.domain.DirectionalPool.RecordType; 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.BaseUltraDNSWSApiLiveTest; -import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import com.google.common.collect.Sets; @@ -46,15 +44,6 @@ import com.google.common.collect.Sets; @Test(groups = "live", singleThreaded = true, testName = "DirectionalGroupApiLiveTest") public class DirectionalGroupApiLiveTest extends BaseUltraDNSWSApiLiveTest { - private IdAndName account; - - @Override - @BeforeClass(groups = { "integration", "live" }) - public void setup() { - super.setup(); - account = api.getCurrentAccount(); - } - @Test public void testListAccountLevelGroups() { for (AccountLevelGroup group : api().listAccountLevelGroups()) { @@ -94,7 +83,7 @@ public class DirectionalGroupApiLiveTest extends BaseUltraDNSWSApiLiveTest { for (Zone zone : api.getZoneApi().listByAccount(account.getId())) { for (DirectionalPool pool : api.getDirectionalPoolApiForZone(zone.getName()).list()) { for (RecordType type : EnumSet.allOf(RecordType.class)) { - for (String groupName : api().listGroupNamesByRecordNameAndType(pool.getDName(), type.getCode())) { + for (String groupName : api().listGroupNamesByDNameAndType(pool.getDName(), type.getCode())) { allGroups.add(DirectionalGroupCoordinates.builder() .zoneName(zone.getName()) .recordName(pool.getDName()) diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalPoolApiExpectTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalPoolApiExpectTest.java index 72a9814cde..9788e4464b 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalPoolApiExpectTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalPoolApiExpectTest.java @@ -19,22 +19,169 @@ package org.jclouds.ultradns.ws.features; import static com.google.common.net.HttpHeaders.HOST; import static javax.ws.rs.HttpMethod.POST; +import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; import static javax.ws.rs.core.Response.Status.OK; +import static org.jclouds.ultradns.ws.domain.DirectionalPool.RecordType.IPV4; import static org.testng.Assert.assertEquals; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; +import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.ultradns.ws.UltraDNSWSApi; +import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; +import org.jclouds.ultradns.ws.domain.DirectionalGroup; +import org.jclouds.ultradns.ws.domain.DirectionalPoolRecord; import org.jclouds.ultradns.ws.internal.BaseUltraDNSWSApiExpectTest; import org.jclouds.ultradns.ws.parse.GetDirectionalDNSRecordsForHostResponseTest; import org.jclouds.ultradns.ws.parse.GetDirectionalPoolsByZoneResponseTest; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSet; + /** * @author Adrian Cole */ @Test(groups = "unit", testName = "DirectionalPoolApiExpectTest") public class DirectionalPoolApiExpectTest extends BaseUltraDNSWSApiExpectTest { + HttpRequest create = HttpRequest.builder().method(POST) + .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") + .addHeader(HOST, "ultra-api.ultradns.com:8443") + .payload(payloadFromResourceWithContentType("/create_directionalpool.xml", "application/xml")).build(); + + HttpResponse createResponse = HttpResponse.builder().statusCode(OK.getStatusCode()) + .payload(payloadFromResourceWithContentType("/directionalpool_created.xml", "application/xml")).build(); + + public void testCreateWhenResponseIs2xx() { + UltraDNSWSApi success = requestSendsResponse(create, createResponse); + assertEquals( + success.getDirectionalPoolApiForZone("jclouds.org.").createForDNameAndType("foo", + "www.jclouds.org.", IPV4.getCode()), "06063DC355055E68"); + } + + HttpResponse alreadyCreated = HttpResponse.builder().statusCode(INTERNAL_SERVER_ERROR.getStatusCode()) + .payload(payloadFromResourceWithContentType("/directionalpool_already_exists.xml", "application/xml")) + .build(); + + @Test(expectedExceptions = ResourceAlreadyExistsException.class, expectedExceptionsMessageRegExp = "Pool already created for this host name : www.jclouds.org.") + public void testCreateWhenResponseError2912() { + UltraDNSWSApi already = requestSendsResponse(create, alreadyCreated); + already.getDirectionalPoolApiForZone("jclouds.org.").createForDNameAndType("foo", "www.jclouds.org.", + IPV4.getCode()); + } + + HttpRequest addFirstRecordInNonConfiguredGroup = HttpRequest.builder().method(POST) + .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") + .addHeader(HOST, "ultra-api.ultradns.com:8443") + .payload(payloadFromResourceWithContentType("/create_directionalrecord.xml", "application/xml")).build(); + + HttpResponse recordCreatedResponse = HttpResponse.builder().statusCode(OK.getStatusCode()) + .payload(payloadFromResourceWithContentType("/directionalrecord_created.xml", "application/xml")).build(); + + DirectionalPoolRecord record = DirectionalPoolRecord.drBuilder() + .type("A") + .ttl(300) + .rdata("1.1.0.1").build(); + + public void testAddFirstRecordInNonConfiguredGroupWhenResponseIs2xx() { + UltraDNSWSApi success = requestSendsResponse(addFirstRecordInNonConfiguredGroup, recordCreatedResponse); + assertEquals( + success.getDirectionalPoolApiForZone("jclouds.org.").addFirstRecordInNonConfiguredGroup("06063DC355055E68", + record), "06063DC355058294"); + } + + HttpResponse recordAlreadyCreated = HttpResponse.builder().statusCode(INTERNAL_SERVER_ERROR.getStatusCode()) + .payload(payloadFromResourceWithContentType("/directionalrecord_already_exists.xml", "application/xml")) + .build(); + + @Test(expectedExceptions = ResourceAlreadyExistsException.class, expectedExceptionsMessageRegExp = "Resource Record already exists.") + public void testAddFirstRecordInNonConfiguredGroupWhenResponseError1802() { + UltraDNSWSApi already = requestSendsResponse(addFirstRecordInNonConfiguredGroup, recordAlreadyCreated); + already.getDirectionalPoolApiForZone("jclouds.org.").addFirstRecordInNonConfiguredGroup("06063DC355055E68", + record); + } + + HttpRequest addRecordIntoNewGroup = HttpRequest.builder().method(POST) + .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") + .addHeader(HOST, "ultra-api.ultradns.com:8443") + .payload(payloadFromResourceWithContentType("/create_directionalrecord_newgroup.xml", "application/xml")) + .build(); + + DirectionalGroup group = DirectionalGroup.builder() + .name("Mexas") + .description("Clients we classify as being in US") + .mapRegionToTerritories("United States (US)", + ImmutableSet.of("Maryland", "Texas")) + .build(); + + public void testAddRecordIntoNewGroupWhenResponseIs2xx() { + UltraDNSWSApi success = requestSendsResponse(addRecordIntoNewGroup, recordCreatedResponse); + assertEquals( + success.getDirectionalPoolApiForZone("jclouds.org.").addRecordIntoNewGroup("06063DC355055E68", record, + group), "06063DC355058294"); + } + + HttpRequest addRecordIntoExistingGroup = HttpRequest.builder().method(POST) + .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") + .addHeader(HOST, "ultra-api.ultradns.com:8443") + .payload(payloadFromResourceWithContentType("/create_directionalrecord_existinggroup.xml", "application/xml")) + .build(); + + public void testAddRecordIntoExistingGroupWhenResponseIs2xx() { + UltraDNSWSApi success = requestSendsResponse(addRecordIntoExistingGroup, recordCreatedResponse); + assertEquals( + success.getDirectionalPoolApiForZone("jclouds.org.").addRecordIntoExistingGroup("06063DC355055E68", + record, "AAABBBCCCDDDEEE"), "06063DC355058294"); + } + + HttpRequest updateRecord = HttpRequest.builder().method(POST) + .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") + .addHeader(HOST, "ultra-api.ultradns.com:8443") + .payload(payloadFromResourceWithContentType("/update_directionalrecord.xml", "application/xml")).build(); + + HttpResponse updateRecordResponse = HttpResponse.builder().statusCode(OK.getStatusCode()) + .payload(payloadFromResourceWithContentType("/directionalrecord_updated.xml", "application/xml")).build(); + + public void testUpdateRecordWhenResponseIs2xx() { + UltraDNSWSApi success = requestSendsResponse(updateRecord, updateRecordResponse); + success.getDirectionalPoolApiForZone("jclouds.org.").updateRecord("04053D8E57C7931F", record); + } + + HttpResponse recordDoesntExist = HttpResponse.builder().message("Server Error").statusCode(INTERNAL_SERVER_ERROR.getStatusCode()) + .payload(payloadFromResource("/directionalrecord_doesnt_exist.xml")).build(); + + @Test(expectedExceptions = ResourceNotFoundException.class, expectedExceptionsMessageRegExp = "Directional Pool Record does not exist in the system") + public void testUpdateRecordWhenResponseNotFound() { + UltraDNSWSApi notFound = requestSendsResponse(updateRecord, recordDoesntExist); + notFound.getDirectionalPoolApiForZone("jclouds.org.").updateRecord("04053D8E57C7931F", record); + } + + HttpRequest updateRecordAndGroup = HttpRequest.builder().method(POST) + .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") + .addHeader(HOST, "ultra-api.ultradns.com:8443") + .payload(payloadFromResourceWithContentType("/update_directionalrecord_group.xml", "application/xml")).build(); + + public void testUpdateRecordAndGroupWhenResponseIs2xx() { + UltraDNSWSApi success = requestSendsResponse(updateRecordAndGroup, updateRecordResponse); + success.getDirectionalPoolApiForZone("jclouds.org.").updateRecordAndGroup("04053D8E57C7931F", record, group); + } + + HttpRequest deleteRecord = HttpRequest.builder().method(POST) + .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") + .addHeader(HOST, "ultra-api.ultradns.com:8443") + .payload(payloadFromResourceWithContentType("/delete_directionalrecord.xml", "application/xml")).build(); + + HttpResponse deleteRecordResponse = HttpResponse.builder().statusCode(404) + .payload(payloadFromResourceWithContentType("/directionalrecord_deleted.xml", "application/xml")).build(); + + public void testDeleteRecordWhenResponseIs2xx() { + UltraDNSWSApi success = requestSendsResponse(deleteRecord, deleteRecordResponse); + success.getDirectionalPoolApiForZone("jclouds.org.").deleteRecord("04053D8E57C7931F"); + } + + public void testDeleteRecordWhenResponseNotFound() { + UltraDNSWSApi notFound = requestSendsResponse(deleteRecord, recordDoesntExist); + notFound.getDirectionalPoolApiForZone("jclouds.org.").deleteRecord("04053D8E57C7931F"); + } HttpRequest list = HttpRequest.builder().method(POST) .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") @@ -64,8 +211,7 @@ public class DirectionalPoolApiExpectTest extends BaseUltraDNSWSApiExpectTest { public void testListRecordsWhenResponseIs2xx() { UltraDNSWSApi success = requestSendsResponse(listRecords, listRecordsResponse); - assertEquals( - success.getDirectionalPoolApiForZone("jclouds.org.").listRecordsByNameAndType("www.jclouds.org.", 1).toString(), - new GetDirectionalDNSRecordsForHostResponseTest().expected().toString()); + assertEquals(success.getDirectionalPoolApiForZone("jclouds.org.").listRecordsByDNameAndType("www.jclouds.org.", 1) + .toString(), new GetDirectionalDNSRecordsForHostResponseTest().expected().toString()); } } diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalPoolApiLiveTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalPoolApiLiveTest.java index 6c778abd9e..1c166b86d6 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalPoolApiLiveTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/DirectionalPoolApiLiveTest.java @@ -18,44 +18,47 @@ */ 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.BaseUltraDNSWSApiLiveTest; -import org.testng.annotations.BeforeClass; +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.Iterables; -import com.google.common.collect.Sets; +import com.google.common.collect.Multimap; /** * @author Adrian Cole */ @Test(groups = "live", singleThreaded = true, testName = "DirectionalPoolApiLiveTest") -public class DirectionalPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest { - - private IdAndName account; - - @Override - @BeforeClass(groups = { "integration", "live" }) - public void setup() { - super.setup(); - account = api.getCurrentAccount(); - } +public class DirectionalPoolApiLiveTest extends BaseDirectionalApiLiveTest { @Test public void testListDirectionalPools() { @@ -75,7 +78,7 @@ public class DirectionalPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest { assertNotNull(pool.getTieBreak(), "TieBreak cannot be null " + pool); } - Set allDirectionalGroups = Sets.newLinkedHashSet(); + Set allDirectionalGroups = newLinkedHashSet(); @Test public void testListDirectionalRecords() { @@ -83,11 +86,11 @@ public class DirectionalPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest { for (DirectionalPool pool : api(zone.getName()).list()) { for (RecordType type : EnumSet.allOf(RecordType.class)) { for (DirectionalPoolRecordDetail rr : api(zone.getName()) - .listRecordsByNameAndType(pool.getDName(), type.getCode())) { + .listRecordsByDNameAndType(pool.getDName(), type.getCode())) { checkDirectionalRecordDetail(rr); Iterable groups = Optional.presentInstances(ImmutableSet.of(rr.getGroup(), rr.getGeolocationGroup(), rr.getGeolocationGroup())); - assertFalse(Iterables.isEmpty(groups), "No groups " + rr); + assertFalse(isEmpty(groups), "No groups " + rr); for (IdAndName group : groups) { allDirectionalGroups.add(group); assertNotNull(group.getId(), "Id cannot be null " + group); @@ -122,12 +125,13 @@ public class DirectionalPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest { assertNotNull(rr.getRData(), "InfoValues cannot be null " + rr); } - static void checkDirectionalRecordDetail(DirectionalPoolRecordDetail 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.") @@ -135,7 +139,202 @@ public class DirectionalPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest { 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 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 minusUtah = ImmutableMultimap.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()); + } } diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiLiveTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiLiveTest.java index 9a7f62e913..75586fd917 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiLiveTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiLiveTest.java @@ -31,7 +31,6 @@ import java.util.concurrent.atomic.AtomicLong; import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; -import org.jclouds.ultradns.ws.domain.IdAndName; import org.jclouds.ultradns.ws.domain.ResourceRecord; import org.jclouds.ultradns.ws.domain.ResourceRecordDetail; import org.jclouds.ultradns.ws.domain.Zone; @@ -52,23 +51,11 @@ import com.google.common.collect.FluentIterable; @Test(groups = "live", singleThreaded = true, testName = "ResourceRecordApiLiveTest") public class ResourceRecordApiLiveTest extends BaseUltraDNSWSApiLiveTest { - private String zoneName = System.getProperty("user.name").replace('.', '-') + ".rr.ultradnstest.jclouds.org."; - private IdAndName account; - @Override @BeforeClass(groups = { "integration", "live" }) public void setup() { super.setup(); - api.getZoneApi().delete(zoneName); - account = api.getCurrentAccount(); - api.getZoneApi().createInAccount(zoneName, account.getId()); - } - - @Override - @AfterClass(groups = { "integration", "live" }) - protected void tearDown() { - api.getZoneApi().delete(zoneName); - super.tearDown(); + createZone(); } static void checkResourceRecord(ResourceRecord rr) { diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApiExpectTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApiExpectTest.java index 2d83e75f88..a1950e51da 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApiExpectTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApiExpectTest.java @@ -21,6 +21,8 @@ import static com.google.common.net.HttpHeaders.HOST; import static javax.ws.rs.HttpMethod.POST; import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; import static javax.ws.rs.core.Response.Status.OK; +import static org.jclouds.ultradns.ws.domain.RoundRobinPool.RecordType.A; +import static org.jclouds.ultradns.ws.domain.RoundRobinPool.RecordType.AAAA; import static org.testng.Assert.assertEquals; import org.jclouds.http.HttpRequest; @@ -52,12 +54,16 @@ public class RoundRobinPoolApiExpectTest extends BaseUltraDNSWSApiExpectTest { public void testCreateAWhenResponseIs2xx() { UltraDNSWSApi success = requestSendsResponse(createA, createResponse); - assertEquals(success.getRoundRobinPoolApiForZone("jclouds.org.").createAPoolForDName("www.jclouds.org.", "foo"), "060339AA04175655"); + assertEquals( + success.getRoundRobinPoolApiForZone("jclouds.org.").createForDNameAndType("www.jclouds.org.", "foo", + A.getCode()), "060339AA04175655"); } public void testCreateAAAAWhenResponseIs2xx() { UltraDNSWSApi success = requestSendsResponse(createAAAA, createResponse); - assertEquals(success.getRoundRobinPoolApiForZone("jclouds.org.").createAAAAPoolForDName("www.jclouds.org.", "foo"), "060339AA04175655"); + assertEquals( + success.getRoundRobinPoolApiForZone("jclouds.org.").createForDNameAndType("www.jclouds.org.", "foo", + AAAA.getCode()), "060339AA04175655"); } HttpResponse alreadyCreated = HttpResponse.builder().statusCode(INTERNAL_SERVER_ERROR.getStatusCode()) @@ -66,7 +72,8 @@ public class RoundRobinPoolApiExpectTest extends BaseUltraDNSWSApiExpectTest { @Test(expectedExceptions = ResourceAlreadyExistsException.class, expectedExceptionsMessageRegExp = "Pool already created for this host name : www.rrpool.adrianc.rrpool.ultradnstest.jclouds.org.") public void testCreateWhenResponseError2912() { UltraDNSWSApi already = requestSendsResponse(createA, alreadyCreated); - already.getRoundRobinPoolApiForZone("jclouds.org.").createAPoolForDName("www.jclouds.org.", "foo"); + already.getRoundRobinPoolApiForZone("jclouds.org.").createForDNameAndType("www.jclouds.org.", "foo", + A.getCode()); } HttpRequest list = HttpRequest.builder().method(POST) diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApiLiveTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApiLiveTest.java index dc6294a08e..581185833d 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApiLiveTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApiLiveTest.java @@ -21,6 +21,8 @@ package org.jclouds.ultradns.ws.features; import static com.google.common.base.Predicates.equalTo; import static java.util.logging.Logger.getAnonymousLogger; import static org.jclouds.ultradns.ws.domain.ResourceRecord.rrBuilder; +import static org.jclouds.ultradns.ws.domain.RoundRobinPool.RecordType.A; +import static org.jclouds.ultradns.ws.domain.RoundRobinPool.RecordType.AAAA; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; @@ -29,13 +31,11 @@ import static org.testng.Assert.fail; import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; -import org.jclouds.ultradns.ws.domain.IdAndName; import org.jclouds.ultradns.ws.domain.ResourceRecord; import org.jclouds.ultradns.ws.domain.ResourceRecordDetail; import org.jclouds.ultradns.ws.domain.RoundRobinPool; import org.jclouds.ultradns.ws.domain.Zone; import org.jclouds.ultradns.ws.internal.BaseUltraDNSWSApiLiveTest; -import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -49,16 +49,11 @@ import com.google.common.collect.FluentIterable; @Test(groups = "live", singleThreaded = true, testName = "RoundRobinPoolApiLiveTest") public class RoundRobinPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest { - private String zoneName = System.getProperty("user.name").replace('.', '-') + ".rrpool.ultradnstest.jclouds.org."; - private IdAndName account; - @Override @BeforeClass(groups = { "integration", "live" }) public void setup() { super.setup(); - api.getZoneApi().delete(zoneName); - account = api.getCurrentAccount(); - api.getZoneApi().createInAccount(zoneName, account.getId()); + createZone(); } private void checkRRPool(RoundRobinPool pool) { @@ -103,10 +98,10 @@ public class RoundRobinPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest { @Test public void testCreateAPool() { - aPoolId = api(zoneName).createAPoolForDName("A pool", dname); + aPoolId = api(zoneName).createForDNameAndType("A pool", dname, A.getCode()); getAnonymousLogger().info("created A rr pool: " + aPoolId); try { - api(zoneName).createAPoolForDName("A pool", dname); + api(zoneName).createForDNameAndType("A pool", dname, A.getCode()); fail(); } catch (ResourceAlreadyExistsException e) { @@ -170,10 +165,10 @@ public class RoundRobinPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest { @Test public void testCreateAAAAPool() { - aaaaPoolId = api(zoneName).createAAAAPoolForDName("AAAA pool", dname); + aaaaPoolId = api(zoneName).createForDNameAndType("AAAA pool", dname, AAAA.getCode()); getAnonymousLogger().info("created AAAA rr pool: " + aaaaPoolId); try { - api(zoneName).createAAAAPoolForDName("AAAA pool", dname); + api(zoneName).createForDNameAndType("AAAA pool", dname, AAAA.getCode()); fail(); } catch (ResourceAlreadyExistsException e) { @@ -241,15 +236,4 @@ public class RoundRobinPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest { private RoundRobinPoolApi api(String zoneName) { return api.getRoundRobinPoolApiForZone(zoneName); } - - @Override - @AfterClass(groups = { "integration", "live" }) - protected void tearDown() { - if (aPoolId != null) - api(zoneName).delete(aPoolId); - if (aaaaPoolId != null) - api(zoneName).delete(aaaaPoolId); - api.getZoneApi().delete(zoneName); - super.tearDown(); - } } diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApiExpectTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApiExpectTest.java index 7bf93f4604..2b31199df9 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApiExpectTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApiExpectTest.java @@ -52,8 +52,8 @@ public class TrafficControllerPoolApiExpectTest extends BaseUltraDNSWSApiExpectT public void testCreateWhenResponseIs2xx() { UltraDNSWSApi success = requestSendsResponse(create, createResponse); assertEquals( - success.getTrafficControllerPoolApiForZone("jclouds.org.").createPoolForDNameAndType("foo", - "www.jclouds.org.", IPV4), "060339AA0417567A"); + success.getTrafficControllerPoolApiForZone("jclouds.org.").createForDNameAndType("foo", + "www.jclouds.org.", IPV4.getCode()), "060339AA0417567A"); } HttpResponse alreadyCreated = HttpResponse.builder().statusCode(INTERNAL_SERVER_ERROR.getStatusCode()) @@ -62,8 +62,8 @@ public class TrafficControllerPoolApiExpectTest extends BaseUltraDNSWSApiExpectT @Test(expectedExceptions = ResourceAlreadyExistsException.class, expectedExceptionsMessageRegExp = "Pool already created for this host name : www.rrpool.adrianc.rrpool.ultradnstest.jclouds.org.") public void testCreateWhenResponseError2912() { UltraDNSWSApi already = requestSendsResponse(create, alreadyCreated); - already.getTrafficControllerPoolApiForZone("jclouds.org.").createPoolForDNameAndType("foo", "www.jclouds.org.", - IPV4); + already.getTrafficControllerPoolApiForZone("jclouds.org.").createForDNameAndType("foo", "www.jclouds.org.", + IPV4.getCode()); } HttpRequest list = HttpRequest.builder().method(POST) @@ -148,7 +148,16 @@ public class TrafficControllerPoolApiExpectTest extends BaseUltraDNSWSApiExpectT UltraDNSWSApi success = requestSendsResponse(createRecord, createRecordResponse); assertEquals(success.getTrafficControllerPoolApiForZone("jclouds.org.").addRecordToPoolWithTTL("1.2.3.4", "04053D8E57C7931F", 300), "06063DAC54F8D3D9"); } - + + HttpResponse recordAlreadyCreated = HttpResponse.builder().statusCode(INTERNAL_SERVER_ERROR.getStatusCode()) + .payload(payloadFromResourceWithContentType("/tcrecord_already_exists.xml", "application/xml")).build(); + + @Test(expectedExceptions = ResourceAlreadyExistsException.class, expectedExceptionsMessageRegExp = "Resource Record of type 1 with these attributes already exists in the system.") + public void testCreateWhenResponseError1802() { + UltraDNSWSApi already = requestSendsResponse(createRecord, recordAlreadyCreated); + already.getTrafficControllerPoolApiForZone("jclouds.org.").addRecordToPoolWithTTL("1.2.3.4", "04053D8E57C7931F", 300); + } + HttpRequest createRecordWithWeight = HttpRequest.builder().method(POST) .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") .addHeader(HOST, "ultra-api.ultradns.com:8443") @@ -161,15 +170,6 @@ public class TrafficControllerPoolApiExpectTest extends BaseUltraDNSWSApiExpectT "04053D8E57C7931F", 300, 0), "06063DAC54F8D3D9"); } - HttpResponse recordAlreadyCreated = HttpResponse.builder().statusCode(INTERNAL_SERVER_ERROR.getStatusCode()) - .payload(payloadFromResourceWithContentType("/tcrecord_already_exists.xml", "application/xml")).build(); - - @Test(expectedExceptions = ResourceAlreadyExistsException.class, expectedExceptionsMessageRegExp = "Resource Record of type 1 with these attributes already exists in the system.") - public void testCreateWhenResponseError1802() { - UltraDNSWSApi already = requestSendsResponse(createRecord, recordAlreadyCreated); - already.getTrafficControllerPoolApiForZone("jclouds.org.").addRecordToPoolWithTTL("1.2.3.4", "04053D8E57C7931F", 300); - } - HttpRequest getRecordSpec = HttpRequest.builder().method(POST) .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") .addHeader(HOST, "ultra-api.ultradns.com:8443") diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApiLiveTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApiLiveTest.java index ecd8b2e4ea..67538feac8 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApiLiveTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApiLiveTest.java @@ -32,7 +32,6 @@ import static org.testng.Assert.fail; import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; -import org.jclouds.ultradns.ws.domain.IdAndName; import org.jclouds.ultradns.ws.domain.PoolRecordSpec; import org.jclouds.ultradns.ws.domain.TrafficControllerPool; import org.jclouds.ultradns.ws.domain.TrafficControllerPoolRecord; @@ -54,16 +53,11 @@ import com.google.common.collect.ImmutableSet; @Test(groups = "live", singleThreaded = true, testName = "TrafficControllerPoolApiLiveTest") public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest { - private String zoneName = System.getProperty("user.name").replace('.', '-') + ".tcpool.ultradnstest.jclouds.org."; - private IdAndName account; - @Override @BeforeClass(groups = { "integration", "live" }) public void setup() { super.setup(); - api.getZoneApi().delete(zoneName); - account = api.getCurrentAccount(); - api.getZoneApi().createInAccount(zoneName, account.getId()); + createZone(); } private void checkTCPool(TrafficControllerPool pool) { @@ -166,17 +160,17 @@ public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest @Test public void testCreatePool() { - poolId = api(zoneName).createPoolForDNameAndType("pool", dname, IPV4); + poolId = api(zoneName).createForDNameAndType("pool", dname, IPV4.getCode()); getAnonymousLogger().info("created tc pool: " + poolId); try { - api(zoneName).createPoolForDNameAndType("pool", dname, IPV4); + api(zoneName).createForDNameAndType("pool", dname, IPV4.getCode()); fail(); } catch (ResourceAlreadyExistsException e) { } // ensure there's only one pool for a dname try { - api(zoneName).createPoolForDNameAndType("pool1", dname, IPV4); + api(zoneName).createForDNameAndType("pool1", dname, IPV4.getCode()); fail(); } catch (ResourceAlreadyExistsException e) { @@ -285,7 +279,6 @@ public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest protected void tearDown() { if (poolId != null) api(zoneName).delete(poolId); - api.getZoneApi().delete(zoneName); super.tearDown(); } } diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ZoneApiLiveTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ZoneApiLiveTest.java index af31d52cdc..f0a5c2f0cc 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ZoneApiLiveTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ZoneApiLiveTest.java @@ -29,12 +29,10 @@ import static org.testng.Assert.fail; import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; -import org.jclouds.ultradns.ws.domain.IdAndName; import org.jclouds.ultradns.ws.domain.Zone; import org.jclouds.ultradns.ws.domain.Zone.Type; import org.jclouds.ultradns.ws.domain.ZoneProperties; import org.jclouds.ultradns.ws.internal.BaseUltraDNSWSApiLiveTest; -import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import com.google.common.collect.FluentIterable; @@ -45,15 +43,6 @@ import com.google.common.collect.FluentIterable; @Test(groups = "live", testName = "ZoneApiLiveTest") public class ZoneApiLiveTest extends BaseUltraDNSWSApiLiveTest { - private IdAndName account; - - @Override - @BeforeClass(groups = { "integration", "live" }) - public void setup() { - super.setup(); - account = api.getCurrentAccount(); - } - private void checkZone(Zone zone) { assertNotNull(zone.getId(), "Id cannot be null for " + zone); assertNotNull(zone.getName(), "Name cannot be null for " + zone); @@ -111,32 +100,30 @@ public class ZoneApiLiveTest extends BaseUltraDNSWSApiLiveTest { @Test(expectedExceptions = ResourceNotFoundException.class, expectedExceptionsMessageRegExp = "Account not found in the system. ID: AAAAAAAAAAAAAAAA") public void testCreateZoneBadAccountId() { - api().createInAccount(name, "AAAAAAAAAAAAAAAA"); + api().createInAccount(zoneName, "AAAAAAAAAAAAAAAA"); } - String name = System.getProperty("user.name").replace('.', '-') + ".zone.ultradnstest.jclouds.org."; - @Test public void testCreateAndDeleteZone() { try { - api().createInAccount(name, account.getId()); - ZoneProperties newZone = api().get(name); + api().createInAccount(zoneName, account.getId()); + ZoneProperties newZone = api().get(zoneName); getAnonymousLogger().info("created zone: " + newZone); try { - api().createInAccount(name, account.getId()); + api().createInAccount(zoneName, account.getId()); fail(); } catch (ResourceAlreadyExistsException e) { } - assertEquals(newZone.getName(), name); + assertEquals(newZone.getName(), zoneName); assertEquals(newZone.getType(), Type.PRIMARY); assertEquals(newZone.getTypeCode(), Type.PRIMARY.getCode()); assertNotNull(newZone.getModified(), "Modified cannot be null for " + newZone); assertEquals(newZone.getResourceRecordCount(), 5); } finally { - api().delete(name); + api().delete(zoneName); } } diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandlerTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandlerTest.java index bc71fee0da..91d3c946a2 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandlerTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandlerTest.java @@ -33,6 +33,7 @@ import org.jclouds.http.HttpResponse; import org.jclouds.http.functions.config.SaxParserModule; import org.jclouds.io.Payload; import org.jclouds.rest.ResourceNotFoundException; +import org.jclouds.ultradns.ws.UltraDNSWSExceptions.DirectionalGroupOverlapException; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; import org.jclouds.ultradns.ws.UltraDNSWSResponseException; import org.testng.annotations.Test; @@ -339,6 +340,54 @@ public class UltraDNSWSErrorHandlerTest { assertEquals(exception.getError().getCode(), 4003); } + @Test + public void testCode2705SetsResourceNotFoundException() throws IOException { + HttpRequest request = HttpRequest.builder().method(POST) + .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") + .addHeader(HOST, "ultra-api.ultradns.com:8443") + .payload(payloadFromResource("/delete_directionalrecord.xml")).build(); + HttpCommand command = new HttpCommand(request); + HttpResponse response = HttpResponse.builder() + .message(INTERNAL_SERVER_ERROR.getReasonPhrase()) + .statusCode(INTERNAL_SERVER_ERROR.getStatusCode()) + .payload(payloadFromResource("/directionalrecord_doesnt_exist.xml")).build(); + + function.handleError(command, response); + + assertEquals(command.getException().getClass(), ResourceNotFoundException.class); + assertEquals(command.getException().getMessage(), "Directional Pool Record does not exist in the system"); + + UltraDNSWSResponseException exception = UltraDNSWSResponseException.class.cast(command.getException().getCause()); + + assertEquals(exception.getMessage(), "Error 2705: Directional Pool Record does not exist in the system"); + assertEquals(exception.getError().getDescription().get(), "Directional Pool Record does not exist in the system"); + assertEquals(exception.getError().getCode(), 2705); + } + + @Test + public void testCode7021SetsDirectionalGroupOverlapException() throws IOException { + HttpRequest request = HttpRequest.builder().method(POST) + .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") + .addHeader(HOST, "ultra-api.ultradns.com:8443") + .payload(payloadFromResource("/create_directionalrecord_newgroup.xml")).build(); + HttpCommand command = new HttpCommand(request); + HttpResponse response = HttpResponse.builder() + .message(INTERNAL_SERVER_ERROR.getReasonPhrase()) + .statusCode(INTERNAL_SERVER_ERROR.getStatusCode()) + .payload(payloadFromResource("/directionalgroup_overlap.xml")).build(); + + function.handleError(command, response); + + assertEquals(command.getException().getClass(), DirectionalGroupOverlapException.class); + assertEquals(command.getException().getMessage(), "Geolocation/Source IP overlap(s) found: Region: Utah (Group: US )"); + + UltraDNSWSResponseException exception = UltraDNSWSResponseException.class.cast(command.getException().getCause()); + + assertEquals(exception.getMessage(), "Error 7021: Geolocation/Source IP overlap(s) found: Region: Utah (Group: US )"); + assertEquals(exception.getError().getDescription().get(), "Geolocation/Source IP overlap(s) found: Region: Utah (Group: US )"); + assertEquals(exception.getError().getCode(), 7021); + } + private Payload payloadFromResource(String resource) { try { return payloadFromStringWithContentType(toStringAndClose(getClass().getResourceAsStream(resource)), diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/internal/BaseDirectionalApiLiveTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/internal/BaseDirectionalApiLiveTest.java new file mode 100644 index 0000000000..b46952b19f --- /dev/null +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/internal/BaseDirectionalApiLiveTest.java @@ -0,0 +1,183 @@ +/** + * 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.internal; + +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.Multimaps.filterKeys; +import static org.jclouds.ultradns.ws.domain.DirectionalPool.RecordType.IPV4; +import static org.jclouds.ultradns.ws.predicates.DirectionalPoolPredicates.recordIdEqualTo; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import org.jclouds.ultradns.ws.domain.DirectionalGroup; +import org.jclouds.ultradns.ws.domain.DirectionalPool; +import org.jclouds.ultradns.ws.domain.DirectionalPoolRecord; +import org.jclouds.ultradns.ws.domain.DirectionalPoolRecordDetail; +import org.jclouds.ultradns.ws.domain.IdAndName; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.Multimap; + +/** + * @author Adrian Cole + */ +@Test(groups = "live") +public class BaseDirectionalApiLiveTest extends BaseUltraDNSWSApiLiveTest { + + protected String dname = "www." + zoneName; + + @Override + @BeforeClass(groups = { "integration", "live" }) + public void setup() { + super.setup(); + setupGroups(); + createZone(); + } + + protected String cnamePoolId; + + protected String cnameEU; + protected DirectionalGroup eu = null; + protected DirectionalPoolRecord cnameRecordEU = DirectionalPoolRecord.drBuilder() + .type("CNAME") + .ttl(8600) + .rdata("eu." + dname).build(); + + /** + * lower ttl as plan to accept territories from canary + */ + protected String cnameUS; + protected DirectionalGroup us = null; + protected DirectionalPoolRecord cnameRecordUS = DirectionalPoolRecord.drBuilder() + .type("CNAME") + .ttl(300) + .rdata("us." + dname).build(); + + /** + * lower ttl as plan to move territories into recordUS + */ + /** + * a test state. + */ + protected String cnameCanary; + protected DirectionalGroup nebraska = null; + protected DirectionalPoolRecord cnameRecordCanary = DirectionalPoolRecord.drBuilder() + .type("CNAME") + .ttl(300) + .rdata("canary." + dname).build(); + protected String cname2Canary; + protected DirectionalPoolRecord cname2RecordCanary = cnameRecordCanary.toBuilder().rdata("parrot." + dname).build(); + + protected String aPoolId; + + /** + * Uses all non-configured group to support all clients + */ + protected String a1Prod; + protected DirectionalPoolRecord a1RecordProd = DirectionalPoolRecord.drBuilder() + .type("A") + .ttl(300) + .rdata("1.1.0.1").build(); + /** + * contains territories currently being tested. + */ + protected String a1Canary; + protected DirectionalPoolRecord a1RecordCanary = DirectionalPoolRecord.drBuilder() + .type("A") + .ttl(300) + .rdata("1.1.1.1").build(); + + public static final String REGION_US = "United States (US)"; + + void setupGroups() { + // all territories in EU + eu = DirectionalGroup.builder() + .name("EU") + .description("Clients we classify as being in Europe") + .mapRegion("Europe").build(); + nebraska = DirectionalGroup.builder() + .name("Canary") + .description("Clients who are testing our service") + .mapRegionToTerritory(REGION_US, "Nebraska").build(); + + // in order to pick certain territories, we need to know what they are + Multimap availableRegions = api.getRegionsByIdAndName(); + + // find the us Territories + Iterable usTerritories = filterKeys(availableRegions, + IdAndName.nameEqualTo(REGION_US)).values(); + + us = DirectionalGroup.builder() + .name("US") + .description("Clients we classify as being in US") + .mapRegionToTerritories(REGION_US, + filter(usTerritories, not(equalTo("Nebraska")))).build(); + } + + protected void checkGroupByDNameAndIdContainsTerritory(String dname, String poolRecordId, String territory) { + DirectionalGroup regions = getGroup(dname, poolRecordId); + assertTrue(regions.values().contains(territory), poolRecordId + " doesn't contain " + territory); + } + + protected void checkGroupByDNameAndIdDoesntContainTerritory(String dname, String poolRecordId, String territory) { + DirectionalGroup regions = getGroup(dname, poolRecordId); + assertFalse(regions.values().contains(territory), poolRecordId + " contains " + territory); + } + + /** + * gets the geo group or the non-configured group. + */ + private DirectionalGroup getGroup(String dname, String poolRecordId) { + DirectionalPoolRecordDetail record = getRecordByDNameAndId(dname, poolRecordId).get(); + return api.getDirectionalGroupApiForAccount(account.getId()) + .get(record.getGeolocationGroup().or(record.getGroup()).get().getId()); + } + + protected Optional getPoolById(final String cnamePoolId) { + return api.getDirectionalPoolApiForZone(zoneName) + .list() + .firstMatch(new Predicate() { + public boolean apply(DirectionalPool in) { + return in.getId().equals(cnamePoolId); + } + }); + } + + protected Optional getRecordByDNameAndId(String dname, String recordId) { + return api.getDirectionalPoolApiForZone(zoneName) + .listRecordsByDNameAndType(dname, IPV4.getCode()) + .firstMatch(recordIdEqualTo(recordId)); + } + + @Override + @AfterClass(groups = { "integration", "live" }) + protected void tearDown() { + if (cnamePoolId != null) + api.getDirectionalPoolApiForZone(zoneName).delete(cnamePoolId); + if (aPoolId != null) + api.getDirectionalPoolApiForZone(zoneName).delete(aPoolId); + super.tearDown(); + } +} diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/internal/BaseUltraDNSWSApiLiveTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/internal/BaseUltraDNSWSApiLiveTest.java index 9dbc33f823..fd5c09f3f9 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/internal/BaseUltraDNSWSApiLiveTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/internal/BaseUltraDNSWSApiLiveTest.java @@ -18,17 +18,61 @@ */ package org.jclouds.ultradns.ws.internal; +import static com.google.common.base.CaseFormat.LOWER_HYPHEN; +import static com.google.common.base.CaseFormat.UPPER_CAMEL; + import org.jclouds.apis.BaseApiLiveTest; import org.jclouds.ultradns.ws.UltraDNSWSApi; +import org.jclouds.ultradns.ws.domain.IdAndName; +import org.jclouds.ultradns.ws.domain.Zone; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; +import com.google.common.base.Optional; +import com.google.common.base.Predicate; + /** * * @author Adrian Cole */ @Test(groups = "live") public class BaseUltraDNSWSApiLiveTest extends BaseApiLiveTest { + protected String zoneName = String.format("%s-%s.ultradnstest.jclouds.org.", System.getProperty("user.name") + .replace('.', '-'), UPPER_CAMEL.to(LOWER_HYPHEN, getClass().getSimpleName())); + protected String zoneId; + protected IdAndName account; + public BaseUltraDNSWSApiLiveTest() { provider = "ultradns-ws"; } + + @Override + @BeforeClass(groups = { "integration", "live" }) + public void setup() { + super.setup(); + account = api.getCurrentAccount(); + } + + protected void createZone() { + api.getZoneApi().delete(zoneName); + api.getZoneApi().createInAccount(zoneName, account.getId()); + zoneId = getZoneByName(zoneName).get().getId(); + } + + protected Optional getZoneByName(final String zoneName) { + return api.getZoneApi().listByAccount(account.getId()).firstMatch(new Predicate() { + public boolean apply(Zone in) { + return in.getName().equals(zoneName); + } + }); + } + + @Override + @AfterClass(groups = { "integration", "live" }) + protected void tearDown() { + if (zoneId != null) + api.getZoneApi().delete(zoneName); + super.tearDown(); + } } diff --git a/providers/ultradns-ws/src/test/resources/create_directionalpool.xml b/providers/ultradns-ws/src/test/resources/create_directionalpool.xml new file mode 100644 index 0000000000..3f21359af7 --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/create_directionalpool.xml @@ -0,0 +1 @@ +identitycredential \ No newline at end of file diff --git a/providers/ultradns-ws/src/test/resources/create_directionalrecord.xml b/providers/ultradns-ws/src/test/resources/create_directionalrecord.xml new file mode 100644 index 0000000000..cbf141bee2 --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/create_directionalrecord.xml @@ -0,0 +1 @@ +identitycredential \ No newline at end of file diff --git a/providers/ultradns-ws/src/test/resources/create_directionalrecord_existinggroup.xml b/providers/ultradns-ws/src/test/resources/create_directionalrecord_existinggroup.xml new file mode 100644 index 0000000000..d5f16dede0 --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/create_directionalrecord_existinggroup.xml @@ -0,0 +1 @@ +identitycredential \ No newline at end of file diff --git a/providers/ultradns-ws/src/test/resources/create_directionalrecord_newgroup.xml b/providers/ultradns-ws/src/test/resources/create_directionalrecord_newgroup.xml new file mode 100644 index 0000000000..c345845799 --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/create_directionalrecord_newgroup.xml @@ -0,0 +1 @@ +identitycredential \ No newline at end of file diff --git a/providers/ultradns-ws/src/test/resources/delete_directionalrecord.xml b/providers/ultradns-ws/src/test/resources/delete_directionalrecord.xml new file mode 100644 index 0000000000..d3c62ee42b --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/delete_directionalrecord.xml @@ -0,0 +1 @@ +identitycredential04053D8E57C7931F \ No newline at end of file diff --git a/providers/ultradns-ws/src/test/resources/directionalgroup_overlap.xml b/providers/ultradns-ws/src/test/resources/directionalgroup_overlap.xml new file mode 100644 index 0000000000..0615bdafcc --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/directionalgroup_overlap.xml @@ -0,0 +1,16 @@ + + + + soap:Server + Fault occurred while processing. + + + 7021 + Geolocation/Source IP overlap(s) found: Region: Utah (Group: US ) + + + + + diff --git a/providers/ultradns-ws/src/test/resources/directionalpool_already_exists.xml b/providers/ultradns-ws/src/test/resources/directionalpool_already_exists.xml new file mode 100644 index 0000000000..941cf17c6f --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/directionalpool_already_exists.xml @@ -0,0 +1,18 @@ + + + + soap:Server + + Fault occurred while processing. + + + + 2912 + Pool already created for this host name : www.jclouds.org. + + + + + diff --git a/providers/ultradns-ws/src/test/resources/directionalpool_created.xml b/providers/ultradns-ws/src/test/resources/directionalpool_created.xml new file mode 100644 index 0000000000..76c830f532 --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/directionalpool_created.xml @@ -0,0 +1,8 @@ + + + + 06063DC355055E68 + + + diff --git a/providers/ultradns-ws/src/test/resources/directionalpool_deleted.xml b/providers/ultradns-ws/src/test/resources/directionalpool_deleted.xml new file mode 100644 index 0000000000..df46a1a97f --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/directionalpool_deleted.xml @@ -0,0 +1,8 @@ + + + + Successful + + + diff --git a/providers/ultradns-ws/src/test/resources/directionalrecord_already_exists.xml b/providers/ultradns-ws/src/test/resources/directionalrecord_already_exists.xml new file mode 100644 index 0000000000..d0e9453af0 --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/directionalrecord_already_exists.xml @@ -0,0 +1,16 @@ + + + + soap:Server + Fault occurred while processing. + + + 4009 + Resource Record already exists. + + + + + diff --git a/providers/ultradns-ws/src/test/resources/directionalrecord_created.xml b/providers/ultradns-ws/src/test/resources/directionalrecord_created.xml new file mode 100644 index 0000000000..6d4088131b --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/directionalrecord_created.xml @@ -0,0 +1,9 @@ + + + + 06063DC355058294 + + + diff --git a/providers/ultradns-ws/src/test/resources/directionalrecord_deleted.xml b/providers/ultradns-ws/src/test/resources/directionalrecord_deleted.xml new file mode 100644 index 0000000000..0e0c244b78 --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/directionalrecord_deleted.xml @@ -0,0 +1,8 @@ + + + + Successful + + + diff --git a/providers/ultradns-ws/src/test/resources/directionalrecord_doesnt_exist.xml b/providers/ultradns-ws/src/test/resources/directionalrecord_doesnt_exist.xml new file mode 100644 index 0000000000..c4e4808afe --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/directionalrecord_doesnt_exist.xml @@ -0,0 +1,16 @@ + + + + soap:Server + Fault occurred while processing. + + + 2705 + Directional Pool Record does not exist in the system + + + + + diff --git a/providers/ultradns-ws/src/test/resources/directionalrecord_updated.xml b/providers/ultradns-ws/src/test/resources/directionalrecord_updated.xml new file mode 100644 index 0000000000..adb6f09e17 --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/directionalrecord_updated.xml @@ -0,0 +1,8 @@ + + + + Successful + + + diff --git a/providers/ultradns-ws/src/test/resources/update_directionalrecord.xml b/providers/ultradns-ws/src/test/resources/update_directionalrecord.xml new file mode 100644 index 0000000000..ae4c43219c --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/update_directionalrecord.xml @@ -0,0 +1 @@ +identitycredential \ No newline at end of file diff --git a/providers/ultradns-ws/src/test/resources/update_directionalrecord_group.xml b/providers/ultradns-ws/src/test/resources/update_directionalrecord_group.xml new file mode 100644 index 0000000000..b61c2eedfb --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/update_directionalrecord_group.xml @@ -0,0 +1 @@ +identitycredential \ No newline at end of file