diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/binders/UpdatePoolRecordToXML.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/binders/UpdatePoolRecordToXML.java
new file mode 100644
index 0000000000..670a9ca06c
--- /dev/null
+++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/binders/UpdatePoolRecordToXML.java
@@ -0,0 +1,62 @@
+/**
+ * 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.Map;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.rest.MapBinder;
+import org.jclouds.ultradns.ws.domain.UpdatePoolRecord;
+
+/**
+ *
+ * @author Adrian Cole
+ */
+public class UpdatePoolRecordToXML implements MapBinder {
+ private static final String HEADER = "%s";
+ private static final String FOOTER = "";
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public R bindToRequest(R request, Map postParams) {
+
+ StringBuilder xml = new StringBuilder();
+ xml.append(format(HEADER, postParams.get("poolRecordID")));
+
+ UpdatePoolRecord update = UpdatePoolRecord.class.cast(postParams.get("update"));
+
+ xml.append("").append(update.getPointsTo()).append("");
+ xml.append("").append(update.getPriority()).append("");
+ xml.append("").append(update.getFailOverDelay()).append("");
+ xml.append("").append(update.getTTL()).append("");
+ xml.append("").append(update.getWeight()).append("");
+ xml.append("").append(update.getMode()).append("");
+ xml.append("").append(update.getThreshold()).append("");
+
+ xml.append(FOOTER);
+ return (R) request.toBuilder().payload(xml.toString()).build();
+ }
+
+ @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/UpdatePoolRecord.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/UpdatePoolRecord.java
new file mode 100644
index 0000000000..a7883b4e30
--- /dev/null
+++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/UpdatePoolRecord.java
@@ -0,0 +1,232 @@
+/**
+ * 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;
+
+/**
+ * holds updates for a record
+ *
+ * @author Adrian Cole
+ */
+public final class UpdatePoolRecord {
+
+ /**
+ * @param spec what to prime updates from
+ * @param pointsTo new value to point to.
+ */
+ public static UpdatePoolRecord pointingTo(PoolRecordSpec spec, String pointsTo) {
+ return new Builder().from(spec).pointsTo(pointsTo).build();
+ }
+
+ private final String pointsTo;
+ private final String mode;
+ private final int priority;
+ private final int weight;
+ private final int failOverDelay;
+ private final int threshold;
+ private final int ttl;
+
+ private UpdatePoolRecord(String pointsTo, String mode, int priority, int weight, int failOverDelay, int threshold,
+ int ttl) {
+ this.pointsTo = checkNotNull(pointsTo, "pointsTo");
+ this.mode = checkNotNull(mode, "mode for %s", pointsTo);
+ this.priority = priority;
+ this.weight = weight;
+ checkArgument(weight >= 0, "weight of %s must be unsigned", pointsTo);
+ this.failOverDelay = failOverDelay;
+ checkArgument(failOverDelay >= 0, "failOverDelay of %s must be unsigned", pointsTo);
+ this.threshold = threshold;
+ checkArgument(threshold >= 0, "threshold of %s must be unsigned", pointsTo);
+ this.ttl = ttl;
+ checkArgument(ttl >= 0, "ttl of %s must be unsigned", pointsTo);
+ }
+
+ /**
+ * correlates to {@link TrafficControllerPoolRecord#getPointsTo()}
+ */
+ public String getPointsTo() {
+ return pointsTo;
+ }
+
+ /**
+ * correlates to {@link PoolRecordSpec#getState()}
+ */
+ public String getMode() {
+ return mode;
+ }
+
+ /**
+ * correlates to {@link PoolRecordSpec#getPriority()}
+ */
+ public int getPriority() {
+ return priority;
+ }
+
+ /**
+ * correlates to {@link PoolRecordSpec#getWeight()}
+ */
+ public int getWeight() {
+ return weight;
+ }
+
+ /**
+ * correlates to {@link PoolRecordSpec#getFailOverDelay()}
+ */
+ public int getFailOverDelay() {
+ return failOverDelay;
+ }
+
+ /**
+ * correlates to {@link PoolRecordSpec#getThreshold()}
+ */
+ public int getThreshold() {
+ return threshold;
+ }
+
+ /**
+ * correlates to {@link PoolRecordSpec#getTTL()}
+ */
+ public int getTTL() {
+ return ttl;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(pointsTo, mode, priority, 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;
+ UpdatePoolRecord that = UpdatePoolRecord.class.cast(obj);
+ return equal(this.pointsTo, that.pointsTo) && equal(this.mode, that.mode) && equal(this.priority, that.priority)
+ && 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("pointsTo", pointsTo).add("mode", mode).add("priority", priority)
+ .add("weight", weight).add("failOverDelay", failOverDelay).add("threshold", threshold).add("ttl", ttl)
+ .toString();
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public Builder toBuilder() {
+ return new Builder().from(this);
+ }
+
+ public final static class Builder {
+ private String pointsTo;
+ private String mode;
+ private int priority;
+ private int weight;
+ private int failOverDelay;
+ private int threshold;
+ private int ttl;
+
+ /**
+ * @see UpdatePoolRecord#getPointsTo()
+ */
+ public Builder pointsTo(String pointsTo) {
+ this.pointsTo = pointsTo;
+ return this;
+ }
+
+ /**
+ * @see UpdatePoolRecord#getMode()
+ */
+ public Builder mode(String mode) {
+ this.mode = mode;
+ return this;
+ }
+
+ /**
+ * @see UpdatePoolRecord#getPriority()
+ */
+ public Builder priority(int priority) {
+ this.priority = priority;
+ return this;
+ }
+
+ /**
+ * @see UpdatePoolRecord#getWeight()
+ */
+ public Builder weight(int weight) {
+ this.weight = weight;
+ return this;
+ }
+
+ /**
+ * @see UpdatePoolRecord#getFailOverDelay()
+ */
+ public Builder failOverDelay(int failOverDelay) {
+ this.failOverDelay = failOverDelay;
+ return this;
+ }
+
+ /**
+ * @see UpdatePoolRecord#getThreshold()
+ */
+ public Builder threshold(int threshold) {
+ this.threshold = threshold;
+ return this;
+ }
+
+ /**
+ * @see UpdatePoolRecord#getTTL()
+ */
+ public Builder ttl(int ttl) {
+ this.ttl = ttl;
+ return this;
+ }
+
+ public UpdatePoolRecord build() {
+ return new UpdatePoolRecord(pointsTo, mode, priority, weight, failOverDelay, threshold, ttl);
+ }
+
+ public Builder from(PoolRecordSpec in) {
+ return this.mode(in.getState()).weight(in.getWeight()).failOverDelay(in.getFailOverDelay())
+ .threshold(in.getThreshold()).ttl(in.getTTL());
+ }
+
+ public Builder from(TrafficControllerPoolRecord in) {
+ return this.weight(in.getWeight()).pointsTo(in.getPointsTo()).priority(in.getPriority());
+ }
+
+ public Builder from(UpdatePoolRecord in) {
+ return this.pointsTo(in.pointsTo).mode(in.mode).priority(in.priority).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/TrafficControllerPoolApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApi.java
index da0c80f14e..1509528eea 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
@@ -25,6 +25,7 @@ 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;
+import org.jclouds.ultradns.ws.domain.UpdatePoolRecord;
import com.google.common.collect.FluentIterable;
@@ -102,12 +103,26 @@ public interface TrafficControllerPoolApi {
* Retrieves information about the specified pool record
*
* @param poolRecordID
- * {@see TrafficControllerPoolRecord#getId()}
+ * {@link TrafficControllerPoolRecord#getId()}
* @return null if not found
*/
@Nullable
PoolRecordSpec getRecordSpec(String poolRecordID);
+ /**
+ * This request updates an existing pool record.
+ *
+ * @param poolRecordID
+ * {@link TrafficControllerPoolRecord#getId()}
+ * @param update
+ * what to update, usually primed via
+ * {@link UpdatePoolRecord#pointingTo(PoolRecordSpec, String)} or
+ * {@link org.jclouds.ultradns.ws.domain.UpdatePoolRecord.Builder#from(PoolRecordSpec)}
+ * @throws ResourceNotFoundException
+ * if the record doesn't exist
+ */
+ void updateRecord(String poolRecordID, UpdatePoolRecord update) throws ResourceNotFoundException;
+
/**
* 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 6127b3495c..c20cc7f72f 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
@@ -25,15 +25,18 @@ import org.jclouds.Fallbacks.NullOnNotFoundOr404;
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.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.UltraDNSWSExceptions.ResourceAlreadyExistsException;
+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.TrafficControllerPoolRecord;
+import org.jclouds.ultradns.ws.domain.UpdatePoolRecord;
import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth;
import org.jclouds.ultradns.ws.xml.AttributeHandler;
import org.jclouds.ultradns.ws.xml.PoolRecordSpecHandler;
@@ -122,6 +125,15 @@ public interface TrafficControllerPoolAsyncApi {
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture getRecordSpec(@PayloadParam("poolRecordId") String poolRecordID);
+ /**
+ * @see TrafficControllerPoolApi#getRecordSpec(String)
+ */
+ @Named("updatePoolRecord>")
+ @POST
+ @MapBinder(UpdatePoolRecordToXML.class)
+ ListenableFuture updateRecord(@PayloadParam("poolRecordID") String poolRecordID,
+ @PayloadParam("update") UpdatePoolRecord update) throws ResourceNotFoundException;
+
/**
* @see TrafficControllerPoolApi#deleteRecord(String)
*/
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 fc8833bbc8..583a562739 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
@@ -23,8 +23,10 @@ import static org.testng.Assert.assertNull;
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.UpdatePoolRecord;
import org.jclouds.ultradns.ws.internal.BaseUltraDNSWSApiExpectTest;
import org.jclouds.ultradns.ws.parse.GetPoolRecordSpecResponseTest;
import org.jclouds.ultradns.ws.parse.GetTCLoadBalancingPoolsByZoneResponseTest;
@@ -172,6 +174,33 @@ public class TrafficControllerPoolApiExpectTest extends BaseUltraDNSWSApiExpectT
assertNull(notFound.getTrafficControllerPoolApiForZone("jclouds.org.").getRecordSpec("04053D8E57C7931F"));
}
+ UpdatePoolRecord update = UpdatePoolRecord.builder()
+ .pointsTo("www.baz.com.")
+ .mode("Normal")
+ .weight(98)
+ .failOverDelay(0)
+ .threshold(1)
+ .ttl(200).build();
+
+ 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_poolrecord.xml", "application/xml")).build();
+
+ HttpResponse updateRecordResponse = HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType("/poolrecord_updated.xml", "application/xml")).build();
+
+ public void testUpdateRecordWhenResponseIs2xx() {
+ UltraDNSWSApi success = requestSendsResponse(updateRecord, updateRecordResponse);
+ success.getTrafficControllerPoolApiForZone("jclouds.org.").updateRecord("04053D8E57C7931F", update);
+ }
+
+ @Test(expectedExceptions = ResourceNotFoundException.class, expectedExceptionsMessageRegExp = "Pool Record does not exist.")
+ public void testUpdateRecordWhenResponseNotFound() {
+ UltraDNSWSApi notFound = requestSendsResponse(updateRecord, recordDoesntExist);
+ notFound.getTrafficControllerPoolApiForZone("jclouds.org.").updateRecord("04053D8E57C7931F", update);
+ }
+
HttpRequest deleteRecord = 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 11d1fb1cd2..c173d4c4a3 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
@@ -35,6 +35,7 @@ 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;
+import org.jclouds.ultradns.ws.domain.UpdatePoolRecord;
import org.jclouds.ultradns.ws.domain.Zone;
import org.jclouds.ultradns.ws.internal.BaseUltraDNSWSApiLiveTest;
import org.testng.annotations.AfterClass;
@@ -152,6 +153,12 @@ public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest
assertNull(api(zoneName).getRecordSpec("06063D9C54C5AE09"));
}
+ @Test(expectedExceptions = ResourceNotFoundException.class, expectedExceptionsMessageRegExp = "Pool Record does not exist.")
+ public void testUpdateRecordWhenNotFound() {
+ api(zoneName).updateRecord("06063D9C54C5AE09",
+ UpdatePoolRecord.builder().pointsTo("www.foo.com.").mode("Normal").build());
+ }
+
String hostname = "www.tcpool." + zoneName;
String poolId;
@@ -223,6 +230,24 @@ public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest
}
@Test(dependsOnMethods = "addCNAMERecordsToPool")
+ public void testUpdateRecord() {
+ PoolRecordSpec spec = api(zoneName).getRecordSpec(cname2);
+ UpdatePoolRecord update = UpdatePoolRecord.builder().from(spec)
+ .pointsTo("www.baz.com.")
+ .weight(98)
+ .ttl(200).build();
+
+ api(zoneName).updateRecord(cname2, update);
+
+ TrafficControllerPoolRecord record = getRecordById(cname2).get();
+ assertEquals(record.getPointsTo(), "www.baz.com.");
+
+ spec = api(zoneName).getRecordSpec(cname2);
+ assertEquals(spec.getWeight(), 98);
+ assertEquals(spec.getTTL(), 200);
+ }
+
+ @Test(dependsOnMethods = "testUpdateRecord")
public void testDeleteRecord() {
api(zoneName).deleteRecord(cname1);
assertFalse(getRecordById(cname1).isPresent());
diff --git a/providers/ultradns-ws/src/test/resources/poolrecord_updated.xml b/providers/ultradns-ws/src/test/resources/poolrecord_updated.xml
new file mode 100644
index 0000000000..64d564f58e
--- /dev/null
+++ b/providers/ultradns-ws/src/test/resources/poolrecord_updated.xml
@@ -0,0 +1 @@
+Successful
\ No newline at end of file
diff --git a/providers/ultradns-ws/src/test/resources/update_poolrecord.xml b/providers/ultradns-ws/src/test/resources/update_poolrecord.xml
new file mode 100644
index 0000000000..3b33d73e1d
--- /dev/null
+++ b/providers/ultradns-ws/src/test/resources/update_poolrecord.xml
@@ -0,0 +1 @@
+identitycredential04053D8E57C7931Fwww.baz.com.0020098Normal1
\ No newline at end of file