create and delete traffic controller records in ultradns

This commit is contained in:
adriancole 2013-03-23 18:49:43 -07:00
parent a329feee7c
commit eb1d4710ec
8 changed files with 160 additions and 9 deletions

View File

@ -20,7 +20,7 @@ package org.jclouds.ultradns.ws.features;
import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException;
import org.jclouds.ultradns.ws.domain.RoundRobinPool; import org.jclouds.ultradns.ws.domain.ResourceRecord;
import org.jclouds.ultradns.ws.domain.TrafficControllerPool; import org.jclouds.ultradns.ws.domain.TrafficControllerPool;
import org.jclouds.ultradns.ws.domain.TrafficControllerPoolRecord; import org.jclouds.ultradns.ws.domain.TrafficControllerPoolRecord;
@ -31,6 +31,15 @@ import com.google.common.collect.FluentIterable;
* @author Adrian Cole * @author Adrian Cole
*/ */
public interface TrafficControllerPoolApi { public interface TrafficControllerPoolApi {
/**
* Returns all traffic controller pools in the zone.
*
* @throws ResourceNotFoundException
* if the zone doesn't exist
*/
FluentIterable<TrafficControllerPool> list() throws ResourceNotFoundException;
/** /**
* creates a traffic controller pool. * creates a traffic controller pool.
* *
@ -46,12 +55,12 @@ public interface TrafficControllerPoolApi {
String createPoolForHostname(String name, String hostname) throws ResourceAlreadyExistsException; String createPoolForHostname(String name, String hostname) throws ResourceAlreadyExistsException;
/** /**
* Returns all traffic controller pools in the zone. * removes a pool and all its records and probes
* *
* @throws ResourceNotFoundException * @param id
* if the zone doesn't exist * the {@link TrafficControllerPool#getId() id}
*/ */
FluentIterable<TrafficControllerPool> list() throws ResourceNotFoundException; void delete(String id);
/** /**
* Returns all records in the traffic controller pool. * Returns all records in the traffic controller pool.
@ -62,10 +71,27 @@ public interface TrafficControllerPoolApi {
FluentIterable<TrafficControllerPoolRecord> listRecords(String poolId) throws ResourceNotFoundException; FluentIterable<TrafficControllerPoolRecord> listRecords(String poolId) throws ResourceNotFoundException;
/** /**
* removes a pool and all its records and probes * adds a new record to the pool
* *
* @param id * @param pointsTo
* the {@link RoundRobinPool#getId() id} * the ipv4 address or hostname
* @param lbPoolID
* the pool to add the record to.
* @param ttl
* the {@link ResourceRecord#getTTL ttl} of the record
* @return the {@link TrafficControllerPoolRecord#getId() id} of the new
* record
* @throws ResourceAlreadyExistsException
* if a record already exists with the same attrs
*/ */
void delete(String id); String addRecordToPoolWithTTL(String pointsTo, String lbPoolID, int ttl) throws ResourceAlreadyExistsException;
/**
* deletes a specific pooled resource record
*
* @param poolRecordID
* {@see TrafficControllerPoolRecord#getId()}
*/
void deleteRecord(String poolRecordID);
} }

View File

@ -87,4 +87,24 @@ public interface TrafficControllerPoolAsyncApi {
@Payload("<v01:deleteLBPool><transactionID /><lbPoolID>{lbPoolID}</lbPoolID><DeleteAll>Yes</DeleteAll><retainRecordId /></v01:deleteLBPool>") @Payload("<v01:deleteLBPool><transactionID /><lbPoolID>{lbPoolID}</lbPoolID><DeleteAll>Yes</DeleteAll><retainRecordId /></v01:deleteLBPool>")
@Fallback(VoidOnNotFoundOr404.class) @Fallback(VoidOnNotFoundOr404.class)
ListenableFuture<Void> delete(@PayloadParam("lbPoolID") String id); ListenableFuture<Void> delete(@PayloadParam("lbPoolID") String id);
/**
* @see TrafficControllerPoolApi#addRecordToPoolWithTTL
*/
@Named("addPoolRecord")
@POST
@XMLResponseParser(IDHandler.PoolRecord.class)
@Payload("<v01:addPoolRecord><transactionID /><poolID>{poolID}</poolID><pointsTo>{pointsTo}</pointsTo><priority /><failOverDelay /><ttl>{ttl}</ttl><weight /><mode /><threshold /></v01:addPoolRecord>")
ListenableFuture<String> addRecordToPoolWithTTL(@PayloadParam("pointsTo") String pointsTo,
@PayloadParam("poolID") String lbPoolID, @PayloadParam("ttl") int ttl) throws ResourceAlreadyExistsException;
/**
* @see TrafficControllerPoolApi#deleteRecord(String)
*/
@Named("deletePoolRecord")
@POST
@Payload("<v01:deletePoolRecord><transactionID /><poolRecordID>{poolRecordID}</poolRecordID><parentPoolId /><childPoolId /></v01:deletePoolRecord>")
@Fallback(VoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteRecord(@PayloadParam("poolRecordID") String poolRecordID);
} }

View File

@ -48,6 +48,12 @@ public abstract class IDHandler extends ParseSax.HandlerForGeneratedRequestWithR
} }
} }
public static class PoolRecord extends IDHandler {
public PoolRecord() {
super("poolRecordID");
}
}
private String idElement; private String idElement;
private StringBuilder currentText = new StringBuilder(); private StringBuilder currentText = new StringBuilder();

View File

@ -107,4 +107,26 @@ public class TrafficControllerPoolApiExpectTest extends BaseUltraDNSWSApiExpectT
UltraDNSWSApi notFound = requestSendsResponse(delete, poolDoesntExist); UltraDNSWSApi notFound = requestSendsResponse(delete, poolDoesntExist);
notFound.getTrafficControllerPoolApiForZone("jclouds.org.").delete("04053D8E57C7931F"); notFound.getTrafficControllerPoolApiForZone("jclouds.org.").delete("04053D8E57C7931F");
} }
HttpRequest createRecord = HttpRequest.builder().method("POST")
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443")
.payload(payloadFromResourceWithContentType("/create_tcrecord.xml", "application/xml")).build();
HttpResponse createRecordResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/tcrecord_created.xml", "application/xml")).build();
public void testCreateRecordWhenResponseIs2xx() {
UltraDNSWSApi success = requestSendsResponse(createRecord, createRecordResponse);
assertEquals(success.getTrafficControllerPoolApiForZone("jclouds.org.").addRecordToPoolWithTTL("1.2.3.4", "04053D8E57C7931F", 300), "06063DAC54F8D3D9");
}
HttpResponse recordAlreadyCreated = HttpResponse.builder().statusCode(500)
.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);
}
} }

View File

@ -35,6 +35,7 @@ import org.jclouds.ultradns.ws.domain.Zone;
import org.jclouds.ultradns.ws.internal.BaseUltraDNSWSApiLiveTest; import org.jclouds.ultradns.ws.internal.BaseUltraDNSWSApiLiveTest;
import org.testng.annotations.AfterClass; import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.base.Optional; import com.google.common.base.Optional;
@ -127,7 +128,80 @@ public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest
checkTCPool(pool.get()); checkTCPool(pool.get());
} }
@DataProvider(name = "records")
public Object[][] createRecords() {
Object[][] records = new Object[2][2];
records[0][0] = "1.2.3.4";
records[0][1] = "A";
records[1][0] = "5.6.7.8";
records[1][1] = "A";
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<TrafficControllerPoolRecord>() {
public boolean apply(TrafficControllerPoolRecord in) {
return record.equals(in.getId()) && pointsTo.equals(in.getPointsTo()) && type.equals(in.getType());
}
}));
}
String cname1;
String cname2;
@Test(dependsOnMethods = "testCreatePool") @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<TrafficControllerPoolRecord>() {
public boolean apply(TrafficControllerPoolRecord in) {
return cname1.equals(in.getId()) && "www.foo.com.".equals(in.getPointsTo()) && "CNAME".equals(in.getType());
}
}));
try {
api(zoneName).addRecordToPoolWithTTL("www.foo.com.", poolId, 30);
fail();
} catch (ResourceAlreadyExistsException e) {
}
cname2 = api(zoneName).addRecordToPoolWithTTL("www.bar.com.", poolId, 30);
getAnonymousLogger().info("created CNAME record: " + cname2);
assertTrue(api(zoneName).listRecords(poolId).anyMatch(new Predicate<TrafficControllerPoolRecord>() {
public boolean apply(TrafficControllerPoolRecord in) {
return cname2.equals(in.getId()) && "www.bar.com.".equals(in.getPointsTo()) && "CNAME".equals(in.getType());
}
}));
}
@Test(dependsOnMethods = "addCNAMERecordsToPool")
public void testDeleteRecord() {
api(zoneName).deleteRecord(cname1);
assertTrue(api(zoneName).listRecords(poolId).anyMatch(new Predicate<TrafficControllerPoolRecord>() {
public boolean apply(TrafficControllerPoolRecord in) {
return cname2.equals(in.getId());
}
}));
assertFalse(api(zoneName).listRecords(poolId).anyMatch(new Predicate<TrafficControllerPoolRecord>() {
public boolean apply(TrafficControllerPoolRecord in) {
return cname1.equals(in.getId());
}
}));
}
@Test(dependsOnMethods = "testDeleteRecord")
public void testDeletePool() { public void testDeletePool() {
api(zoneName).delete(poolId); api(zoneName).delete(poolId);
assertFalse(getPoolById(poolId).isPresent()); assertFalse(getPoolById(poolId).isPresent());

View File

@ -0,0 +1 @@
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v01="http://webservice.api.ultra.neustar.com/v01/"><soapenv:Header><wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsse:UsernameToken><wsse:Username>identity</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">credential</wsse:Password></wsse:UsernameToken></wsse:Security></soapenv:Header><soapenv:Body><v01:addPoolRecord><transactionID /><poolID>04053D8E57C7931F</poolID><pointsTo>1.2.3.4</pointsTo><priority /><failOverDelay /><ttl>300</ttl><weight /><mode /><threshold /></v01:addPoolRecord></soapenv:Body></soapenv:Envelope>

View File

@ -0,0 +1 @@
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>Fault occurred while processing.</faultstring><detail><ns1:UltraWSException xmlns:ns1="http://webservice.api.ultra.neustar.com/v01/"><errorCode xmlns:ns2="http://schema.ultraservice.neustar.com/v01/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:int">2111</errorCode><errorDescription xmlns:ns2="http://schema.ultraservice.neustar.com/v01/">Resource Record of type 1 with these attributes already exists in the system.</errorDescription></ns1:UltraWSException></detail></soap:Fault></soap:Body></soap:Envelope>

View File

@ -0,0 +1 @@
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:addPoolRecordResponse xmlns:ns1="http://webservice.api.ultra.neustar.com/v01/"><poolRecordID xmlns:ns2="http://schema.ultraservice.neustar.com/v01/">06063DAC54F8D3D9</poolRecordID></ns1:addPoolRecordResponse></soap:Body></soap:Envelope>