diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/PoolRecordSpec.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/PoolRecordSpec.java new file mode 100644 index 0000000000..f9d3b8a385 --- /dev/null +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/PoolRecordSpec.java @@ -0,0 +1,236 @@ +/** + * 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.domain; + +import static com.google.common.base.Objects.equal; +import static com.google.common.base.Objects.toStringHelper; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Objects; + +/** + * specifications and status of a current record in the pool. + * + * @author Adrian Cole + */ +public final class PoolRecordSpec { + private final String description; + private final String state; + private final boolean probingEnabled; + private final boolean allFailEnabled; + private final int weight; + private final int failOverDelay; + private final int threshold; + private final int ttl; + + private PoolRecordSpec(String description, String state, boolean probingEnabled, boolean allFailEnabled, int weight, + int failOverDelay, int threshold, int ttl) { + this.description = checkNotNull(description, "description"); + this.state = checkNotNull(state, "state for %s", description); + this.probingEnabled = probingEnabled; + this.allFailEnabled = allFailEnabled; + this.weight = weight; + checkArgument(weight >= 0, "weight of %s must be unsigned", description); + this.failOverDelay = failOverDelay; + checkArgument(failOverDelay >= 0, "failOverDelay of %s must be unsigned", description); + this.threshold = threshold; + checkArgument(threshold >= 0, "threshold of %s must be unsigned", description); + this.ttl = ttl; + checkArgument(ttl >= 0, "ttl of %s must be unsigned", description); + } + + /** + * correlates to {@link TrafficControllerPoolRecord#getDescription()} + */ + public String getDescription() { + return description; + } + + /** + * known values include {@code Normal} and {@code Normal-NoTest} + */ + public String getState() { + return state; + } + + /** + * correlates to {@link TrafficControllerPoolRecord#isProbingEnabled()} + */ + public boolean isProbingEnabled() { + return probingEnabled; + } + + /** + * undocumented + */ + public boolean isAllFailEnabled() { + return allFailEnabled; + } + + /** + * correlates to {@link TrafficControllerPoolRecord#getWeight()} + */ + public int getWeight() { + return weight; + } + + /** + * at the time of writing, between 0–30 (minutes). + */ + public int getFailOverDelay() { + return failOverDelay; + } + + /** + * how many probes in a region must fail in order for this to fail. + */ + public int getThreshold() { + return threshold; + } + + /** + * The resource record cache time to live (TTL), in seconds. + */ + public int getTTL() { + return ttl; + } + + @Override + public int hashCode() { + return Objects + .hashCode(description, state, probingEnabled, allFailEnabled, weight, failOverDelay, threshold, ttl); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PoolRecordSpec that = PoolRecordSpec.class.cast(obj); + return equal(this.description, that.description) && equal(this.state, that.state) + && equal(this.probingEnabled, that.probingEnabled) && equal(this.allFailEnabled, that.allFailEnabled) + && equal(this.weight, that.weight) && equal(this.failOverDelay, that.failOverDelay) + && equal(this.threshold, that.threshold) && equal(this.ttl, that.ttl); + } + + @Override + public String toString() { + return toStringHelper(this).add("description", description).add("state", state) + .add("probingEnabled", probingEnabled).add("allFailEnabled", allFailEnabled).add("weight", weight) + .add("failOverDelay", failOverDelay).add("threshold", threshold).add("ttl", ttl).toString(); + } + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return builder().from(this); + } + + public final static class Builder { + private String description; + private String state; + private boolean probingEnabled; + private boolean allFailEnabled; + private int weight; + private int failOverDelay; + private int threshold; + private int ttl; + + /** + * @see PoolRecordSpec#getDescription() + */ + public Builder description(String description) { + this.description = description; + return this; + } + + /** + * @see PoolRecordSpec#getState() + */ + public Builder state(String state) { + this.state = state; + return this; + } + + /** + * @see PoolRecordSpec#isProbingEnabled() + */ + public Builder probingEnabled(boolean probingEnabled) { + this.probingEnabled = probingEnabled; + return this; + } + + /** + * @see PoolRecordSpec#isAllFailEnabled() + */ + public Builder allFailEnabled(boolean allFailEnabled) { + this.allFailEnabled = allFailEnabled; + return this; + } + + /** + * @see PoolRecordSpec#getWeight() + */ + public Builder weight(int weight) { + this.weight = weight; + return this; + } + + /** + * @see PoolRecordSpec#getFailOverDelay() + */ + public Builder failOverDelay(int failOverDelay) { + this.failOverDelay = failOverDelay; + return this; + } + + /** + * @see PoolRecordSpec#getThreshold() + */ + public Builder threshold(int threshold) { + this.threshold = threshold; + return this; + } + + /** + * @see PoolRecordSpec#getTTL() + */ + public Builder ttl(int ttl) { + this.ttl = ttl; + return this; + } + + public PoolRecordSpec build() { + return new PoolRecordSpec(description, state, probingEnabled, allFailEnabled, weight, failOverDelay, + threshold, ttl); + } + + public Builder from(PoolRecordSpec in) { + return this.description(in.description).state(in.state).probingEnabled(in.probingEnabled) + .allFailEnabled(in.allFailEnabled).weight(in.weight).failOverDelay(in.failOverDelay) + .threshold(in.threshold).ttl(in.ttl); + } + } +} diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordAsyncApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordAsyncApi.java index 2fee1d8524..d8fab3688e 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordAsyncApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordAsyncApi.java @@ -35,7 +35,7 @@ import org.jclouds.ultradns.ws.binders.ZoneAndResourceRecordToXML; import org.jclouds.ultradns.ws.domain.ResourceRecord; import org.jclouds.ultradns.ws.domain.ResourceRecordMetadata; import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; -import org.jclouds.ultradns.ws.xml.IDHandler; +import org.jclouds.ultradns.ws.xml.TextHandler; import org.jclouds.ultradns.ws.xml.ResourceRecordListHandler; import com.google.common.collect.FluentIterable; @@ -56,7 +56,7 @@ public interface ResourceRecordAsyncApi { */ @Named("createResourceRecord") @POST - @XMLResponseParser(IDHandler.Guid.class) + @XMLResponseParser(TextHandler.Guid.class) @MapBinder(ZoneAndResourceRecordToXML.class) ListenableFuture create(@PayloadParam("resourceRecord") ResourceRecord toCreate) throws ResourceAlreadyExistsException; diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolAsyncApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolAsyncApi.java index e7087f525d..ab27999f81 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolAsyncApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolAsyncApi.java @@ -33,7 +33,7 @@ import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsExcepti import org.jclouds.ultradns.ws.domain.ResourceRecord; import org.jclouds.ultradns.ws.domain.RoundRobinPool; import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; -import org.jclouds.ultradns.ws.xml.IDHandler; +import org.jclouds.ultradns.ws.xml.TextHandler; import org.jclouds.ultradns.ws.xml.ResourceRecordListHandler; import org.jclouds.ultradns.ws.xml.RoundRobinPoolListHandler; @@ -74,7 +74,7 @@ public interface RoundRobinPoolAsyncApi { */ @Named("addRRLBPool") @POST - @XMLResponseParser(IDHandler.RRPool.class) + @XMLResponseParser(TextHandler.RRPoolID.class) @Payload("{zoneName}{hostName}{description}1") ListenableFuture createAPoolForHostname(@PayloadParam("description") String name, @PayloadParam("hostName") String hostname) throws ResourceAlreadyExistsException; @@ -84,7 +84,7 @@ public interface RoundRobinPoolAsyncApi { */ @Named("addRecordToRRPool") @POST - @XMLResponseParser(IDHandler.Guid.class) + @XMLResponseParser(TextHandler.Guid.class) @Payload("") ListenableFuture addARecordWithAddressAndTTL(@PayloadParam("lbPoolID") String lbPoolID, @PayloadParam("address") String ipv4Address, @PayloadParam("ttl") int ttl) @@ -114,7 +114,7 @@ public interface RoundRobinPoolAsyncApi { */ @Named("addRRLBPool") @POST - @XMLResponseParser(IDHandler.RRPool.class) + @XMLResponseParser(TextHandler.RRPoolID.class) @Payload("{zoneName}{hostName}{description}28") ListenableFuture createAAAAPoolForHostname(@PayloadParam("description") String name, @PayloadParam("hostName") String hostname) throws ResourceAlreadyExistsException; @@ -124,7 +124,7 @@ public interface RoundRobinPoolAsyncApi { */ @Named("addRecordToRRPool") @POST - @XMLResponseParser(IDHandler.Guid.class) + @XMLResponseParser(TextHandler.Guid.class) @Payload("") ListenableFuture addAAAARecordWithAddressAndTTL(@PayloadParam("lbPoolID") String lbPoolID, @PayloadParam("address") String ipv6Address, @PayloadParam("ttl") int ttl) diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskAsyncApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskAsyncApi.java index 654c9ef1be..919c37e472 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskAsyncApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskAsyncApi.java @@ -31,7 +31,7 @@ import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.ultradns.ws.domain.Task; import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; -import org.jclouds.ultradns.ws.xml.IDHandler; +import org.jclouds.ultradns.ws.xml.TextHandler; import org.jclouds.ultradns.ws.xml.TaskHandler; import org.jclouds.ultradns.ws.xml.TaskListHandler; @@ -52,7 +52,7 @@ public interface TaskAsyncApi { */ @Named("runTest") @POST - @XMLResponseParser(IDHandler.Guid.class) + @XMLResponseParser(TextHandler.Guid.class) @Payload("{value}") ListenableFuture runTest(@PayloadParam("value") String value); 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 006cecb5b0..da0c80f14e 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 @@ -18,8 +18,10 @@ */ package org.jclouds.ultradns.ws.features; +import org.jclouds.javax.annotation.Nullable; import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; +import org.jclouds.ultradns.ws.domain.PoolRecordSpec; import org.jclouds.ultradns.ws.domain.ResourceRecord; import org.jclouds.ultradns.ws.domain.TrafficControllerPool; import org.jclouds.ultradns.ws.domain.TrafficControllerPoolRecord; @@ -54,6 +56,16 @@ public interface TrafficControllerPoolApi { */ String createPoolForHostname(String name, String hostname) throws ResourceAlreadyExistsException; + /** + * Retrieves the name of the specified pool by dname. + * + * @param dname + * {@see TrafficControllerPool#getDName()} ex. {@code jclouds.org.} + * @return null if not found + */ + @Nullable + String getNameByDName(String dname); + /** * removes a pool and all its records and probes * @@ -86,6 +98,16 @@ public interface TrafficControllerPoolApi { */ String addRecordToPoolWithTTL(String pointsTo, String lbPoolID, int ttl) throws ResourceAlreadyExistsException; + /** + * Retrieves information about the specified pool record + * + * @param poolRecordID + * {@see TrafficControllerPoolRecord#getId()} + * @return null if not found + */ + @Nullable + PoolRecordSpec getRecordSpec(String poolRecordID); + /** * deletes a specific pooled resource record * diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolAsyncApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolAsyncApi.java index c719f899ef..6127b3495c 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolAsyncApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolAsyncApi.java @@ -21,6 +21,7 @@ package org.jclouds.ultradns.ws.features; import javax.inject.Named; import javax.ws.rs.POST; +import org.jclouds.Fallbacks.NullOnNotFoundOr404; import org.jclouds.Fallbacks.VoidOnNotFoundOr404; import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.rest.annotations.Fallback; @@ -30,10 +31,13 @@ import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; +import org.jclouds.ultradns.ws.domain.PoolRecordSpec; import org.jclouds.ultradns.ws.domain.TrafficControllerPool; import org.jclouds.ultradns.ws.domain.TrafficControllerPoolRecord; import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; -import org.jclouds.ultradns.ws.xml.IDHandler; +import org.jclouds.ultradns.ws.xml.AttributeHandler; +import org.jclouds.ultradns.ws.xml.PoolRecordSpecHandler; +import org.jclouds.ultradns.ws.xml.TextHandler; import org.jclouds.ultradns.ws.xml.TrafficControllerPoolListHandler; import org.jclouds.ultradns.ws.xml.TrafficControllerPoolRecordListHandler; @@ -55,7 +59,7 @@ public interface TrafficControllerPoolAsyncApi { */ @Named("addTCLBPool") @POST - @XMLResponseParser(IDHandler.TCPool.class) + @XMLResponseParser(TextHandler.TCPoolID.class) @Payload("{zoneName}{hostName}{description}1EnabledEnabled0") ListenableFuture createPoolForHostname(@PayloadParam("description") String name, @PayloadParam("hostName") String hostname) throws ResourceAlreadyExistsException; @@ -79,6 +83,16 @@ public interface TrafficControllerPoolAsyncApi { ListenableFuture> listRecords(@PayloadParam("poolId") String poolId) throws ResourceNotFoundException; + /** + * @see TrafficControllerPoolApi#getByDName(String) + */ + @Named("getPoolForPoolHostName>") + @POST + @Payload("{hostName}") + @XMLResponseParser(AttributeHandler.PoolName.class) + @Fallback(NullOnNotFoundOr404.class) + ListenableFuture getNameByDName(@PayloadParam("hostName") String dname); + /** * @see TrafficControllerPoolApi#delete(String) */ @@ -93,11 +107,21 @@ public interface TrafficControllerPoolAsyncApi { */ @Named("addPoolRecord") @POST - @XMLResponseParser(IDHandler.PoolRecord.class) + @XMLResponseParser(TextHandler.PoolRecordID.class) @Payload("{poolID}{pointsTo}{ttl}") ListenableFuture addRecordToPoolWithTTL(@PayloadParam("pointsTo") String pointsTo, @PayloadParam("poolID") String lbPoolID, @PayloadParam("ttl") int ttl) throws ResourceAlreadyExistsException; + /** + * @see TrafficControllerPoolApi#getRecordSpec(String) + */ + @Named("getPoolRecordSpec>") + @POST + @Payload("{poolRecordId}") + @XMLResponseParser(PoolRecordSpecHandler.class) + @Fallback(NullOnNotFoundOr404.class) + ListenableFuture getRecordSpec(@PayloadParam("poolRecordId") String poolRecordID); + /** * @see TrafficControllerPoolApi#deleteRecord(String) */ diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneApi.java index a2260ce829..ad631f6cd4 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneApi.java @@ -58,10 +58,9 @@ public interface ZoneApi { /** * Lists all zones in the specified account. * - * @throws ResourceNotFoundException - * if the account doesn't exist + * @returns empty if no zones, or account doesn't exist */ - FluentIterable listByAccount(String accountId) throws ResourceNotFoundException; + FluentIterable listByAccount(String accountId); /** * Lists all zones in the specified account of type diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneAsyncApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneAsyncApi.java index 3da2d0a7ab..d8d955bd9c 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneAsyncApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneAsyncApi.java @@ -77,8 +77,7 @@ public interface ZoneAsyncApi { @POST @XMLResponseParser(ZoneListHandler.class) @Payload("{accountId}all") - ListenableFuture> listByAccount(@PayloadParam("accountId") String accountId) - throws ResourceNotFoundException; + ListenableFuture> listByAccount(@PayloadParam("accountId") String accountId); /** * @see ZoneApi#listByAccountAndType(String, Type) 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 b336591946..47f5cb0f36 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 @@ -17,7 +17,7 @@ * under the License. */ package org.jclouds.ultradns.ws.handlers; - +import static org.jclouds.ultradns.ws.handlers.UltraDNSWSErrorHandler.ErrorCodes.*; import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream; import static org.jclouds.http.HttpUtils.releasePayload; @@ -74,17 +74,60 @@ public class UltraDNSWSErrorHandler implements HttpErrorHandler { } } + /** + * there are 51002 potential codes. This defines the ones we are handling. + */ + static final class ErrorCodes { + /** + * Cannot find task with guid. + */ + static final int TASK_NOT_FOUND = 0; + /** + * Zone does not exist in the system. + */ + static final int ZONE_NOT_FOUND = 1801; + /** + * Zone already exists in the system. + */ + static final int ZONE_ALREADY_EXISTS = 1802; + /** + * No resource record with GUID found in the system. + */ + static final int RESOURCE_RECORD_NOT_FOUND = 2103; + /** + * Resource record exists with the same name and type. + */ + static final int RESOURCE_RECORD_ALREADY_EXISTS = 2111; + /** + * Account not found in the system. + */ + static final int ACCOUNT_NOT_FOUND = 2401; + /** + * Pool does not exist in the system. + */ + static final int POOL_NOT_FOUND = 2911; + /** + * Pool already created for the given rrGUID. + */ + static final int POOL_ALREADY_EXISTS = 2912; + /** + * Pool Record does not exist. + */ + static final int POOL_RECORD_NOT_FOUND = 3101; + } + private Exception refineException(UltraDNSWSResponseException exception) { switch (exception.getError().getCode()) { - case 0: - case 1801: - case 2103: - case 2401: - case 2911: + case TASK_NOT_FOUND: + case ZONE_NOT_FOUND: + case RESOURCE_RECORD_NOT_FOUND: + case ACCOUNT_NOT_FOUND: + case POOL_NOT_FOUND: + case POOL_RECORD_NOT_FOUND: return new ResourceNotFoundException(exception.getError().getDescription(), exception); - case 1802: - case 2111: - case 2912: + case ZONE_ALREADY_EXISTS: + case RESOURCE_RECORD_ALREADY_EXISTS: + case POOL_ALREADY_EXISTS: return new ResourceAlreadyExistsException(exception.getError().getDescription(), exception); } return exception; diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/predicates/TrafficControllerPoolPredicates.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/predicates/TrafficControllerPoolPredicates.java new file mode 100644 index 0000000000..89067ab839 --- /dev/null +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/predicates/TrafficControllerPoolPredicates.java @@ -0,0 +1,100 @@ +/** + * 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.predicates; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.jclouds.ultradns.ws.domain.TrafficControllerPool; +import org.jclouds.ultradns.ws.domain.TrafficControllerPoolRecord; + +import com.google.common.base.Predicate; + +/** + * Predicates handy when working with TrafficControllerPool Types + * + * @author Adrian Cole + */ +public class TrafficControllerPoolPredicates { + + /** + * evaluates to true if the input {@link TrafficControllerPool} exists + * with {@link TrafficControllerPool#getId() id} corresponding to the + * {@code id} parameter. + * + * @param id + * the {@link TrafficControllerPool#getId() id} of the + * desired pool record + */ + public static Predicate idEqualTo(String id) { + return new IdEqualToPredicate(id); + } + + private static final class IdEqualToPredicate implements Predicate { + private final String id; + + public IdEqualToPredicate(String id) { + this.id = checkNotNull(id, "id"); + } + + @Override + public boolean apply(TrafficControllerPool input) { + if (input == null) + return false; + return id.equals(input.getId()); + } + + @Override + public String toString() { + return "IdEqualTo(" + id + ")"; + } + } + + /** + * evaluates to true if the input {@link TrafficControllerPoolRecord} exists + * with {@link TrafficControllerPoolRecord#getId() id} corresponding to the + * {@code recordId} parameter. + * + * @param recordId + * the {@link TrafficControllerPoolRecord#getId() id} of the + * desired pool record + */ + public static Predicate recordIdEqualTo(String recordId) { + return new RecordIdEqualToPredicate(recordId); + } + + private static final class RecordIdEqualToPredicate implements Predicate { + private final String id; + + public RecordIdEqualToPredicate(String id) { + this.id = checkNotNull(id, "recordId"); + } + + @Override + public boolean apply(TrafficControllerPoolRecord input) { + if (input == null) + return false; + return id.equals(input.getId()); + } + + @Override + public String toString() { + return "RecordIdEqualTo(" + id + ")"; + } + } +} diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/AttributeHandler.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/AttributeHandler.java new file mode 100644 index 0000000000..5dc9b32d86 --- /dev/null +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/AttributeHandler.java @@ -0,0 +1,63 @@ +/** + * 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.xml; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.util.SaxUtils.cleanseAttributes; + +import java.util.Map; + +import org.jclouds.http.functions.ParseSax; +import org.xml.sax.Attributes; + +/** + * @author Adrian Cole + */ +public abstract class AttributeHandler extends ParseSax.HandlerForGeneratedRequestWithResult { + + public static class PoolName extends AttributeHandler { + public PoolName() { + super("PoolName"); + } + } + + private String attributeName; + private String attribute = null; + + private AttributeHandler(String attributeName) { + this.attributeName = checkNotNull(attributeName, "attributeName"); + } + + @Override + public String getResult() { + try { + return checkNotNull(attribute, "%s not present in the response", attributeName); + } finally { + attribute = null; + } + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attrs) { + Map attributes = cleanseAttributes(attrs); + if (attribute == null && attributes.containsKey(attributeName)) { + attribute = attributes.get(attributeName); + } + } +} diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/PoolRecordSpecHandler.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/PoolRecordSpecHandler.java new file mode 100644 index 0000000000..8b31452a9a --- /dev/null +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/PoolRecordSpecHandler.java @@ -0,0 +1,71 @@ +/** + * 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.xml; +import static com.google.common.base.Preconditions.checkNotNull; +import static java.lang.Integer.parseInt; +import static org.jclouds.util.SaxUtils.cleanseAttributes; +import static org.jclouds.util.SaxUtils.equalsOrSuffix; + +import java.util.Map; + +import org.jclouds.http.functions.ParseSax; +import org.jclouds.ultradns.ws.domain.PoolRecordSpec; +import org.xml.sax.Attributes; + +/** + * + * @author Adrian Cole + */ +public class PoolRecordSpecHandler extends ParseSax.HandlerForGeneratedRequestWithResult { + + private final PoolRecordSpec.Builder builder = PoolRecordSpec.builder(); + + @Override + public PoolRecordSpec getResult() { + return builder.build(); + } + + @Override + public void startElement(String url, String name, String qName, Attributes attrs) { + if (!equalsOrSuffix(qName, "PoolRecordSpecData")) { + return; + } + + Map attributes = cleanseAttributes(attrs); + + builder.description(attributes.get("description")) + .state(attributes.get("recordState")); + + builder.probingEnabled(trueIfEnabled(attributes, "probing")) + .allFailEnabled(trueIfEnabled(attributes, "allFail")); + + builder.weight(asInt(attributes, "weight")) + .failOverDelay(asInt(attributes, "failOverDelay")) + .threshold(asInt(attributes, "threshold")) + .ttl(asInt(attributes, "ttl")); + } + + private boolean trueIfEnabled(Map attributes, String name) { + return "ENABLED".equalsIgnoreCase(attributes.get(name)); + } + + private int asInt(Map attributes, String name) { + return parseInt(checkNotNull(attributes.get(name), name)); + } +} diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/IDHandler.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/TextHandler.java similarity index 68% rename from providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/IDHandler.java rename to providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/TextHandler.java index 541bb07baf..ce59512213 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/IDHandler.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/TextHandler.java @@ -28,54 +28,54 @@ import org.jclouds.http.functions.ParseSax; * * @author Adrian Cole */ -public abstract class IDHandler extends ParseSax.HandlerForGeneratedRequestWithResult { +public abstract class TextHandler extends ParseSax.HandlerForGeneratedRequestWithResult { - public static class Guid extends IDHandler { + public static class Guid extends TextHandler { public Guid() { super("guid"); } } - public static class RRPool extends IDHandler { - public RRPool() { + public static class RRPoolID extends TextHandler { + public RRPoolID() { super("RRPoolID"); } } - public static class TCPool extends IDHandler { - public TCPool() { + public static class TCPoolID extends TextHandler { + public TCPoolID() { super("TCPoolID"); } } - public static class PoolRecord extends IDHandler { - public PoolRecord() { + public static class PoolRecordID extends TextHandler { + public PoolRecordID() { super("poolRecordID"); } } - private String idElement; + private String textElement; private StringBuilder currentText = new StringBuilder(); - private String id = null; + private String text = null; - private IDHandler(String idElement) { - this.idElement = checkNotNull(idElement, "idElement"); + private TextHandler(String textElement) { + this.textElement = checkNotNull(textElement, "textElement"); } @Override public String getResult() { try { - return checkNotNull(id, "%s not present in the response", idElement); + return checkNotNull(text, "%s not present in the response", textElement); } finally { - id = null; + text = null; } } @Override public void endElement(String uri, String name, String qName) { - if (equalsOrSuffix(qName, idElement)) { - id = currentOrNull(currentText); + if (equalsOrSuffix(qName, textElement)) { + text = currentOrNull(currentText); } currentText = new StringBuilder(); } 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 e2288d3cd6..fc8833bbc8 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 @@ -19,12 +19,14 @@ package org.jclouds.ultradns.ws.features; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.ultradns.ws.UltraDNSWSApi; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; import org.jclouds.ultradns.ws.internal.BaseUltraDNSWSApiExpectTest; +import org.jclouds.ultradns.ws.parse.GetPoolRecordSpecResponseTest; import org.jclouds.ultradns.ws.parse.GetTCLoadBalancingPoolsByZoneResponseTest; import org.jclouds.ultradns.ws.parse.GetTCPoolRecordsResponseTest; import org.testng.annotations.Test; @@ -87,6 +89,27 @@ public class TrafficControllerPoolApiExpectTest extends BaseUltraDNSWSApiExpectT new GetTCPoolRecordsResponseTest().expected().toString()); } + HttpRequest getNameByDName = HttpRequest.builder().method("POST") + .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") + .addHeader("Host", "ultra-api.ultradns.com:8443") + .payload(payloadFromResourceWithContentType("/get_tcpool_by_dname.xml", "application/xml")).build(); + + HttpResponse getNameByDNameResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/tcpool_name.xml", "application/xml")).build(); + + public void testGetNameByDNameWhenResponseIs2xx() { + UltraDNSWSApi success = requestSendsResponse(getNameByDName, getNameByDNameResponse); + assertEquals(success.getTrafficControllerPoolApiForZone("jclouds.org.").getNameByDName("www.foo.com."), "foo"); + } + + HttpResponse poolDoesntExist = HttpResponse.builder().message("Server Epoolor").statusCode(500) + .payload(payloadFromResource("/lbpool_doesnt_exist.xml")).build(); + + public void testGetNameByDNameWhenResponseNotFound() { + UltraDNSWSApi notFound = requestSendsResponse(getNameByDName, poolDoesntExist); + assertNull(notFound.getTrafficControllerPoolApiForZone("jclouds.org.").getNameByDName("www.foo.com.")); + } + HttpRequest delete = HttpRequest.builder().method("POST") .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") .addHeader("Host", "ultra-api.ultradns.com:8443") @@ -100,10 +123,7 @@ public class TrafficControllerPoolApiExpectTest extends BaseUltraDNSWSApiExpectT success.getTrafficControllerPoolApiForZone("jclouds.org.").delete("04053D8E57C7931F"); } - HttpResponse poolDoesntExist = HttpResponse.builder().message("Server Epoolor").statusCode(500) - .payload(payloadFromResource("/lbpool_doesnt_exist.xml")).build(); - - public void testDeleteWhenResponseRRNotFound() { + public void testDeleteWhenResponseNotFound() { UltraDNSWSApi notFound = requestSendsResponse(delete, poolDoesntExist); notFound.getTrafficControllerPoolApiForZone("jclouds.org.").delete("04053D8E57C7931F"); } @@ -129,4 +149,44 @@ public class TrafficControllerPoolApiExpectTest extends BaseUltraDNSWSApiExpectT 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") + .payload(payloadFromResourceWithContentType("/get_poolrecordspec.xml", "application/xml")).build(); + + HttpResponse getRecordSpecResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/poolrecordspec.xml", "application/xml")).build(); + + public void testGetRecordSpecWhenResponseIs2xx() { + UltraDNSWSApi success = requestSendsResponse(getRecordSpec, getRecordSpecResponse); + assertEquals(success.getTrafficControllerPoolApiForZone("jclouds.org.").getRecordSpec("04053D8E57C7931F"), + new GetPoolRecordSpecResponseTest().expected()); + } + + HttpResponse recordDoesntExist = HttpResponse.builder().message("Server Error").statusCode(500) + .payload(payloadFromResource("/tcrecord_doesnt_exist.xml")).build(); + + public void testGetRecordSpecWhenResponseNotFound() { + UltraDNSWSApi notFound = requestSendsResponse(getRecordSpec, recordDoesntExist); + assertNull(notFound.getTrafficControllerPoolApiForZone("jclouds.org.").getRecordSpec("04053D8E57C7931F")); + } + + 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_tcrecord.xml", "application/xml")).build(); + + HttpResponse deleteRecordResponse = HttpResponse.builder().statusCode(404) + .payload(payloadFromResourceWithContentType("/tcrecord_deleted.xml", "application/xml")).build(); + + public void testDeleteRecordWhenResponseIs2xx() { + UltraDNSWSApi success = requestSendsResponse(deleteRecord, deleteRecordResponse); + success.getTrafficControllerPoolApiForZone("jclouds.org.").deleteRecord("04053D8E57C7931F"); + } + + public void testDeleteRecordWhenResponseNotFound() { + UltraDNSWSApi notFound = requestSendsResponse(deleteRecord, recordDoesntExist); + notFound.getTrafficControllerPoolApiForZone("jclouds.org.").deleteRecord("04053D8E57C7931F"); + } } 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 103cb2a699..11d1fb1cd2 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 @@ -20,14 +20,18 @@ package org.jclouds.ultradns.ws.features; import static com.google.common.base.Preconditions.checkNotNull; import static java.util.logging.Logger.getAnonymousLogger; +import static org.jclouds.ultradns.ws.predicates.TrafficControllerPoolPredicates.idEqualTo; +import static org.jclouds.ultradns.ws.predicates.TrafficControllerPoolPredicates.recordIdEqualTo; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; import org.jclouds.ultradns.ws.domain.Account; +import org.jclouds.ultradns.ws.domain.PoolRecordSpec; import org.jclouds.ultradns.ws.domain.TrafficControllerPool; import org.jclouds.ultradns.ws.domain.TrafficControllerPoolRecord; import org.jclouds.ultradns.ws.domain.TrafficControllerPoolRecord.Status; @@ -39,7 +43,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.google.common.base.Optional; -import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; /** * @author Adrian Cole @@ -64,6 +68,7 @@ public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest checkNotNull(pool.getId(), "Id cannot be null for %s", pool); checkNotNull(pool.getName(), "Name cannot be null for %s", pool); checkNotNull(pool.getDName(), "DName cannot be null for %s", pool); + assertEquals(api(zoneName).getNameByDName(pool.getDName()), pool.getName()); } @Test @@ -80,13 +85,24 @@ public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest for (Zone zone : context.getApi().getZoneApi().listByAccount(account.getId())) { for (TrafficControllerPool pool : api(zone.getName()).list()) { for (TrafficControllerPoolRecord record : api(zone.getName()).listRecords(pool.getId())) { - checkTrafficControllerPoolRecord(record); + checkPoolRecordConsistent(zone.getName(), record); } } } } - static void checkTrafficControllerPoolRecord(TrafficControllerPoolRecord record) { + private TrafficControllerPoolRecord checkPoolRecordConsistent(String zoneName, TrafficControllerPoolRecord record) { + Optional pool = getPoolByZoneAndId(zoneName, record.getPoolId()); + assertTrue(pool.isPresent(), "could not get pool for " + record); + assertEquals(record.getDescription(), pool.get().getName()); + PoolRecordSpec spec = checkPoolRecordSpec(api(zoneName).getRecordSpec(record.getId())); + assertEquals(record.getDescription(), spec.getDescription()); + assertEquals(record.getWeight(), spec.getWeight()); + assertEquals(record.isProbingEnabled(), spec.isProbingEnabled()); + return checkTrafficControllerPoolRecord(record); + } + + static TrafficControllerPoolRecord checkTrafficControllerPoolRecord(TrafficControllerPoolRecord record) { checkNotNull(record.getId(), "Id cannot be null for %s", record); checkNotNull(record.getPoolId(), "PoolId cannot be null for %s", record); checkNotNull(record.getPointsTo(), "PointsTo cannot be null for %s", record); @@ -96,6 +112,19 @@ public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest checkNotNull(record.getStatus(), "Status cannot be null for %s", record); assertTrue(record.getStatus() != Status.UNRECOGNIZED, "unrecognized status for " + record); checkNotNull(record.getDescription(), "Description cannot be null for %s", record); + return record; + } + + static PoolRecordSpec checkPoolRecordSpec(PoolRecordSpec record) { + checkNotNull(record.getDescription(), "Description cannot be null for %s", record); + checkNotNull(record.getState(), "State cannot be null for %s", record); + // TODO: collect all possible states then consider enum + assertTrue(ImmutableSet.of("Normal", "Normal-NoTest").contains(record.getState()), "Unknown State for " + record); + assertTrue(record.getWeight() >= 0, "Weight must be unsigned for " + record); + assertTrue(record.getFailOverDelay() >= 0, "failOverDelay must be unsigned for " + record); + assertTrue(record.getThreshold() >= 0, "threshold must be unsigned for " + record); + assertTrue(record.getTTL() >= 0, "ttl must be unsigned for " + record); + return record; } @Test(expectedExceptions = ResourceNotFoundException.class, expectedExceptionsMessageRegExp = "Zone does not exist in the system.") @@ -108,6 +137,21 @@ public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest api(zoneName).delete("06063D9C54C5AE09"); } + @Test + public void testDeleteRecordWhenNotFound() { + api(zoneName).deleteRecord("06063D9C54C5AE09"); + } + + @Test + public void testGetNameByDNameWhenNotFound() { + assertNull(api(zoneName).getNameByDName("www.razzledazzle.cn.")); + } + + @Test + public void testGetRecordSpecWhenNotFound() { + assertNull(api(zoneName).getRecordSpec("06063D9C54C5AE09")); + } + String hostname = "www.tcpool." + zoneName; String poolId; @@ -121,8 +165,16 @@ public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest } catch (ResourceAlreadyExistsException e) { } - Optional pool = getPoolById(poolId); + // ensure there's only one pool for a hostname + try { + api(zoneName).createPoolForHostname("pool1", hostname); + fail(); + } catch (ResourceAlreadyExistsException e) { + + } + Optional pool = getPoolByZoneAndId(zoneName, poolId); assertTrue(pool.isPresent()); + assertEquals(pool.get().getId(), poolId); assertEquals(pool.get().getName(), "pool"); assertEquals(pool.get().getDName(), hostname); checkTCPool(pool.get()); @@ -130,25 +182,27 @@ public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest @DataProvider(name = "records") public Object[][] createRecords() { - Object[][] records = new Object[2][2]; + Object[][] records = new Object[2][3]; records[0][0] = "1.2.3.4"; records[0][1] = "A"; + records[0][2] = 60; records[1][0] = "5.6.7.8"; records[1][1] = "A"; + records[1][2] = 60; return records; } @Test(dependsOnMethods = "testCreatePool", dataProvider = "records") - public void addRecordsToPool(final String pointsTo, final String type) { - final String record = api(zoneName).addRecordToPoolWithTTL(pointsTo, poolId, 30); - - getAnonymousLogger().info("created " + type + " record: " + record); - - assertTrue(api(zoneName).listRecords(poolId).anyMatch(new Predicate() { - public boolean apply(TrafficControllerPoolRecord in) { - return record.equals(in.getId()) && pointsTo.equals(in.getPointsTo()) && type.equals(in.getType()); - } - })); + public TrafficControllerPoolRecord addRecordToPool(final String pointsTo, final String type, final int ttl) { + String recordId = api(zoneName).addRecordToPoolWithTTL(pointsTo, poolId, ttl); + getAnonymousLogger().info("created " + type + " record: " + recordId); + TrafficControllerPoolRecord record = checkPoolRecordConsistent(zoneName, getRecordById(recordId).get()); + PoolRecordSpec recordSpec = checkPoolRecordSpec(api(zoneName).getRecordSpec(recordId)); + assertEquals(record.getPointsTo(), pointsTo); + assertEquals(record.getType(), type); + assertEquals(record.getWeight(), 2); + assertEquals(recordSpec.getTTL(), ttl); + return record; } String cname1; @@ -156,15 +210,7 @@ public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest @Test(dependsOnMethods = "testCreatePool") public void addCNAMERecordsToPool() { - cname1 = api(zoneName).addRecordToPoolWithTTL("www.foo.com.", poolId, 30); - - getAnonymousLogger().info("created CNAME record: " + cname1); - - assertTrue(api(zoneName).listRecords(poolId).anyMatch(new Predicate() { - public boolean apply(TrafficControllerPoolRecord in) { - return cname1.equals(in.getId()) && "www.foo.com.".equals(in.getPointsTo()) && "CNAME".equals(in.getType()); - } - })); + cname1 = addRecordToPool("www.foo.com.", "CNAME", 30).getId(); try { api(zoneName).addRecordToPoolWithTTL("www.foo.com.", poolId, 30); @@ -173,46 +219,28 @@ public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest } - cname2 = api(zoneName).addRecordToPoolWithTTL("www.bar.com.", poolId, 30); - - getAnonymousLogger().info("created CNAME record: " + cname2); - - assertTrue(api(zoneName).listRecords(poolId).anyMatch(new Predicate() { - public boolean apply(TrafficControllerPoolRecord in) { - return cname2.equals(in.getId()) && "www.bar.com.".equals(in.getPointsTo()) && "CNAME".equals(in.getType()); - } - })); - + cname2 = addRecordToPool("www.bar.com.", "CNAME", 30).getId(); } @Test(dependsOnMethods = "addCNAMERecordsToPool") public void testDeleteRecord() { api(zoneName).deleteRecord(cname1); - assertTrue(api(zoneName).listRecords(poolId).anyMatch(new Predicate() { - public boolean apply(TrafficControllerPoolRecord in) { - return cname2.equals(in.getId()); - } - })); - - assertFalse(api(zoneName).listRecords(poolId).anyMatch(new Predicate() { - public boolean apply(TrafficControllerPoolRecord in) { - return cname1.equals(in.getId()); - } - })); + assertFalse(getRecordById(cname1).isPresent()); + assertTrue(getRecordById(cname2).isPresent()); } @Test(dependsOnMethods = "testDeleteRecord") public void testDeletePool() { api(zoneName).delete(poolId); - assertFalse(getPoolById(poolId).isPresent()); + assertFalse(getPoolByZoneAndId(zoneName, poolId).isPresent()); } - protected Optional getPoolById(final String poolId) { - return api(zoneName).list().firstMatch(new Predicate() { - public boolean apply(TrafficControllerPool in) { - return in.getId().equals(poolId); - } - }); + private Optional getRecordById(String recordId) { + return api(zoneName).listRecords(poolId).firstMatch(recordIdEqualTo(recordId)); + } + + private Optional getPoolByZoneAndId(String zoneName, final String poolId) { + return api(zoneName).list().firstMatch(idEqualTo(poolId)); } private TrafficControllerPoolApi api(String zoneName) { 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 6d0416a8e4..e30acf7c7a 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 @@ -82,9 +82,9 @@ public class ZoneApiLiveTest extends BaseUltraDNSWSApiLiveTest { } } - @Test(expectedExceptions = ResourceNotFoundException.class, expectedExceptionsMessageRegExp = "Account not found in the system. ID: AAAAAAAAAAAAAAAA") + @Test public void testListZonesByAccountWhenAccountIdNotFound() { - api().listByAccount("AAAAAAAAAAAAAAAA"); + assertTrue(api().listByAccount("AAAAAAAAAAAAAAAA").isEmpty()); } @Test 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 8423a1842a..720566e622 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 @@ -221,6 +221,27 @@ public class UltraDNSWSErrorHandlerTest { assertEquals(exception.getError().getCode(), 2912); } + @Test + public void testCode3101SetsResourceNotFoundException() 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_tcrecord.xml")).build(); + HttpCommand command = new HttpCommand(request); + HttpResponse response = HttpResponse.builder().message("Server Error").statusCode(500) + .payload(payloadFromResource("/tcrecord_doesnt_exist.xml")).build(); + + function.handleError(command, response); + + assertEquals(command.getException().getClass(), ResourceNotFoundException.class); + assertEquals(command.getException().getMessage(), "Pool Record does not exist."); + + UltraDNSWSResponseException exception = UltraDNSWSResponseException.class.cast(command.getException().getCause()); + + assertEquals(exception.getMessage(), "Error 3101: Pool Record does not exist."); + assertEquals(exception.getError().getDescription(), "Pool Record does not exist."); + assertEquals(exception.getError().getCode(), 3101); + } + 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/parse/GetPoolForPoolHostNameResponseTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/GetPoolForPoolHostNameResponseTest.java new file mode 100644 index 0000000000..4103756400 --- /dev/null +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/GetPoolForPoolHostNameResponseTest.java @@ -0,0 +1,40 @@ +/** + * 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.parse; + +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; + +import org.jclouds.http.functions.BaseHandlerTest; +import org.jclouds.ultradns.ws.xml.AttributeHandler; +import org.testng.annotations.Test; + +/** + * @author Adrian Cole + */ +@Test(testName = "GetPoolForPoolHostNameResponseTest") +public class GetPoolForPoolHostNameResponseTest extends BaseHandlerTest { + + public void test() { + InputStream is = getClass().getResourceAsStream("/tcpool_name.xml"); + AttributeHandler.PoolName handler = injector.getInstance(AttributeHandler.PoolName.class); + assertEquals(factory.create(handler).parse(is), "foo"); + } +} diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/GetPoolRecordSpecResponseTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/GetPoolRecordSpecResponseTest.java new file mode 100644 index 0000000000..64f896100a --- /dev/null +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/GetPoolRecordSpecResponseTest.java @@ -0,0 +1,61 @@ +/** + * 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.parse; + +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; + +import org.jclouds.http.functions.BaseHandlerTest; +import org.jclouds.ultradns.ws.domain.PoolRecordSpec; +import org.jclouds.ultradns.ws.xml.PoolRecordSpecHandler; +import org.testng.annotations.Test; + +/** + * @author Adrian Cole + */ +@Test(testName = "GetPoolRecordSpecResponseTest") +public class GetPoolRecordSpecResponseTest extends BaseHandlerTest { + + public void test() { + InputStream is = getClass().getResourceAsStream("/poolrecordspec.xml"); + + PoolRecordSpec expected = expected(); + + PoolRecordSpecHandler handler = injector.getInstance(PoolRecordSpecHandler.class); + PoolRecordSpec result = factory.create(handler).parse(is); + + assertEquals(result, expected); + assertEquals(result.hashCode(), expected.hashCode()); + assertEquals(result.toString(), expected.toString()); + } + + public PoolRecordSpec expected() { + return PoolRecordSpec.builder() + .description("foo") + .state("Normal-NoTest") + .probingEnabled(false) + .allFailEnabled(false) + .weight(2) + .failOverDelay(0) + .threshold(1) + .ttl(120).build(); + } + +} \ No newline at end of file diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/RunTestResponseTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/RunTestResponseTest.java index f818089f62..70b6edbee0 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/RunTestResponseTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/RunTestResponseTest.java @@ -23,7 +23,7 @@ import static org.testng.Assert.assertEquals; import java.io.InputStream; import org.jclouds.http.functions.BaseHandlerTest; -import org.jclouds.ultradns.ws.xml.IDHandler; +import org.jclouds.ultradns.ws.xml.TextHandler; import org.testng.annotations.Test; /** @@ -35,7 +35,7 @@ public class RunTestResponseTest extends BaseHandlerTest { public void test() { InputStream is = getClass().getResourceAsStream("/taskid.xml"); - IDHandler.Guid handler = injector.getInstance(IDHandler.Guid.class); + TextHandler.Guid handler = injector.getInstance(TextHandler.Guid.class); assertEquals(factory.create(handler).parse(is), "8d7a1725-4f4a-4b70-affa-f01dcce1526e"); } } diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/predicates/TrafficControllerPoolPredicatesTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/predicates/TrafficControllerPoolPredicatesTest.java new file mode 100644 index 0000000000..0ffadd663a --- /dev/null +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/predicates/TrafficControllerPoolPredicatesTest.java @@ -0,0 +1,76 @@ +/** + * 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.predicates; + +import static org.jclouds.ultradns.ws.predicates.TrafficControllerPoolPredicates.idEqualTo; +import static org.jclouds.ultradns.ws.predicates.TrafficControllerPoolPredicates.recordIdEqualTo; + +import org.jclouds.ultradns.ws.domain.TrafficControllerPool; +import org.jclouds.ultradns.ws.domain.TrafficControllerPoolRecord; +import org.jclouds.ultradns.ws.domain.TrafficControllerPoolRecord.Status; +import org.testng.annotations.Test; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "TrafficControllerPoolPredicatesTest") +public class TrafficControllerPoolPredicatesTest { + TrafficControllerPool pool = TrafficControllerPool.builder() + .zoneId("0000000000000001") + .id("000000000000002") + .name("us-west-1c.discovery.jclouds.org.") + .dname("us-west-1c.discovery.jclouds.org.") + .statusCode(1) + .failOverEnabled(true) + .probingEnabled(true).build(); + + @Test + public void testIdEqualToWhenEqual() { + assert idEqualTo("000000000000002").apply(pool); + } + + @Test + public void testIdEqualToWhenNotEqual() { + assert !idEqualTo("000000000000003").apply(pool); + } + + TrafficControllerPoolRecord record = TrafficControllerPoolRecord.builder() + .id("0000000000000001") + .poolId("0000000000000001") + .pointsTo("canary.jclouds.org.") + .weight(2) + .priority(2) + .type("CNAME") + .forceAnswer("Normal") + .probingEnabled(true) + .status(Status.OK) + .serving(true) + .description("canary app").build(); + + @Test + public void testRecordIdEqualToWhenEqual() { + assert recordIdEqualTo("0000000000000001").apply(record); + } + + @Test + public void testRecordIdEqualToWhenNotEqual() { + assert !recordIdEqualTo("0000000000000002").apply(record); + } +} diff --git a/providers/ultradns-ws/src/test/resources/delete_tcrecord.xml b/providers/ultradns-ws/src/test/resources/delete_tcrecord.xml new file mode 100644 index 0000000000..f25589ddcf --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/delete_tcrecord.xml @@ -0,0 +1 @@ +identitycredential04053D8E57C7931F \ No newline at end of file diff --git a/providers/ultradns-ws/src/test/resources/get_poolrecordspec.xml b/providers/ultradns-ws/src/test/resources/get_poolrecordspec.xml new file mode 100644 index 0000000000..2b742047af --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/get_poolrecordspec.xml @@ -0,0 +1 @@ +identitycredential04053D8E57C7931F \ No newline at end of file diff --git a/providers/ultradns-ws/src/test/resources/get_tcpool_by_dname.xml b/providers/ultradns-ws/src/test/resources/get_tcpool_by_dname.xml new file mode 100644 index 0000000000..272b94f4bd --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/get_tcpool_by_dname.xml @@ -0,0 +1 @@ +identitycredentialwww.foo.com. \ No newline at end of file diff --git a/providers/ultradns-ws/src/test/resources/poolrecordspec.xml b/providers/ultradns-ws/src/test/resources/poolrecordspec.xml new file mode 100644 index 0000000000..fa058f1fbb --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/poolrecordspec.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/providers/ultradns-ws/src/test/resources/tcpool_name.xml b/providers/ultradns-ws/src/test/resources/tcpool_name.xml new file mode 100644 index 0000000000..e7c3adbbb2 --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/tcpool_name.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/providers/ultradns-ws/src/test/resources/tcrecord_deleted.xml b/providers/ultradns-ws/src/test/resources/tcrecord_deleted.xml new file mode 100644 index 0000000000..b3624cbecd --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/tcrecord_deleted.xml @@ -0,0 +1 @@ +Successful \ No newline at end of file diff --git a/providers/ultradns-ws/src/test/resources/tcrecord_doesnt_exist.xml b/providers/ultradns-ws/src/test/resources/tcrecord_doesnt_exist.xml new file mode 100644 index 0000000000..aecfa68d22 --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/tcrecord_doesnt_exist.xml @@ -0,0 +1 @@ +soap:ServerFault occurred while processing.3101Pool Record does not exist. \ No newline at end of file