added record crud for dynect
diff --git a/labs/dynect/src/main/java/org/jclouds/dynect/v3/domain/CreateRecord.java b/labs/dynect/src/main/java/org/jclouds/dynect/v3/domain/CreateRecord.java
new file mode 100644
index 0000000..4f298a5
--- /dev/null
+++ b/labs/dynect/src/main/java/org/jclouds/dynect/v3/domain/CreateRecord.java
@@ -0,0 +1,163 @@
+/**
+ * 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, String 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.dynect.v3.domain;
+
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Objects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+
+import com.google.common.base.Objects;
+import com.google.common.primitives.UnsignedInteger;
+
+/**
+ * @author Adrian Cole
+ */
+public class CreateRecord<D extends Map<String, Object>> {
+
+ private final String fqdn;
+ private final String type;
+ private final UnsignedInteger ttl;
+ private final D rdata;
+
+ private CreateRecord(String fqdn, String type, UnsignedInteger ttl, D rdata) {
+ this.fqdn = checkNotNull(fqdn, "fqdn");
+ this.type = checkNotNull(type, "type of %s", fqdn);
+ this.ttl = checkNotNull(ttl, "ttl of %s", fqdn);
+ this.rdata = checkNotNull(rdata, "rdata of %s", fqdn);
+ }
+
+ /**
+ * @see RecordId#getFQDN()
+ */
+ public String getFQDN() {
+ return fqdn;
+ }
+
+ /**
+ * @see RecordId#getType()
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * zero for zone default
+ *
+ * @see Record#getTTL()
+ */
+ public UnsignedInteger getTTL() {
+ return ttl;
+ }
+
+ /**
+ * @see Record#getRData()
+ */
+ public D getRData() {
+ return rdata;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null || !obj.getClass().equals(CreateRecord.class))
+ return false;
+ CreateRecord<?> that = CreateRecord.class.cast(obj);
+ return equal(this.fqdn, that.fqdn) && equal(this.type, that.type) && equal(this.ttl, that.ttl)
+ && equal(this.rdata, that.rdata);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this).add("fqdn", fqdn).add("type", type).add("ttl", ttl).add("rdata", rdata).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(fqdn, type, ttl, rdata);
+ }
+
+ public static <D extends Map<String, Object>> Builder<D> builder() {
+ return new Builder<D>();
+ }
+
+ public Builder<D> toBuilder() {
+ return new Builder<D>().from(this);
+ }
+
+ public static class Builder<D extends Map<String, Object>> {
+ protected String fqdn;
+ protected String type;
+ protected UnsignedInteger ttl = UnsignedInteger.ZERO;
+ protected D rdata;
+
+ /**
+ * @see CreateRecord#getFQDN()
+ */
+ public Builder<D> fqdn(String fqdn) {
+ this.fqdn = fqdn;
+ return this;
+ }
+
+ /**
+ * @see CreateRecord#getType()
+ */
+ public Builder<D> type(String type) {
+ this.type = type;
+ return this;
+ }
+
+ /**
+ * @see CreateRecord#getTTL()
+ */
+ public Builder<D> ttl(UnsignedInteger ttl) {
+ this.ttl = ttl;
+ return this;
+ }
+
+ /**
+ * @see CreateRecord#getTTL()
+ */
+ public Builder<D> ttl(int ttl) {
+ return ttl(UnsignedInteger.fromIntBits(ttl));
+ }
+
+ /**
+ * @see CreateRecord#getRData()
+ */
+ public Builder<D> rdata(D rdata) {
+ this.rdata = rdata;
+ return this;
+ }
+
+ public CreateRecord<D> build() {
+ return new CreateRecord<D>(fqdn, type, ttl, rdata);
+ }
+
+ public <Y extends D> Builder<D> from(CreateRecord<Y> in) {
+ return fqdn(in.fqdn).type(in.type).ttl(in.ttl).rdata(in.rdata);
+ }
+
+ public <Y extends D> Builder<D> from(Record<Y> in) {
+ return fqdn(in.getFQDN()).type(in.getType()).ttl(in.getTTL()).rdata(in.getRData());
+ }
+ }
+}
\ No newline at end of file
diff --git a/labs/dynect/src/main/java/org/jclouds/dynect/v3/features/RecordApi.java b/labs/dynect/src/main/java/org/jclouds/dynect/v3/features/RecordApi.java
index 63a019b..b0a51bc 100644
--- a/labs/dynect/src/main/java/org/jclouds/dynect/v3/features/RecordApi.java
+++ b/labs/dynect/src/main/java/org/jclouds/dynect/v3/features/RecordApi.java
@@ -21,6 +21,8 @@
import java.util.Map;
import org.jclouds.dynect.v3.DynECTExceptions.JobStillRunningException;
+import org.jclouds.dynect.v3.domain.CreateRecord;
+import org.jclouds.dynect.v3.domain.Job;
import org.jclouds.dynect.v3.domain.Record;
import org.jclouds.dynect.v3.domain.RecordId;
import org.jclouds.dynect.v3.domain.SOARecord;
@@ -32,6 +34,7 @@
import org.jclouds.dynect.v3.domain.rdata.PTRData;
import org.jclouds.dynect.v3.domain.rdata.SRVData;
import org.jclouds.dynect.v3.domain.rdata.TXTData;
+import org.jclouds.javax.annotation.Nullable;
import com.google.common.collect.FluentIterable;
@@ -41,15 +44,52 @@
*/
public interface RecordApi {
/**
- * Retrieves a list of resource record ids for all records of any type in the
- * given zone throws JobStillRunningException;
+ * Retrieves a list of resource record ids for all records of any type in the given zone.
+ *
+ * @throws JobStillRunningException
+ * if a different job in the session is still running
*/
FluentIterable<RecordId> list() throws JobStillRunningException;
/**
+ * Retrieves a list of resource record ids for all records of the fqdn and type in the given zone
+ *
+ * @throws JobStillRunningException
+ * if a different job in the session is still running
+ */
+ FluentIterable<RecordId> listByFQDNAndType(String fqdn, String type) throws JobStillRunningException;
+
+ /**
+ * Schedules addition of a new record into the current session. Calling {@link ZoneApi#publish(String)} will publish
+ * the zone, creating the record.
+ *
+ * @param newRecord
+ * record to create
+ * @return job relating to the scheduled creation.
+ * @throws JobStillRunningException
+ * if a different job in the session is still running
+ */
+ Job scheduleCreate(CreateRecord<?> newRecord) throws JobStillRunningException;
+
+ /**
+ * Schedules deletion of a record into the current session. Calling {@link ZoneApi#publish(String)} will publish the
+ * changes, deleting the record.
+ *
+ * @param recordId
+ * record to delete
+ * @return job relating to the scheduled deletion or null, if the record never existed.
+ * @throws JobStillRunningException
+ * if a different job in the session is still running
+ */
+ @Nullable
+ Job scheduleDelete(RecordId recordId) throws JobStillRunningException;
+
+ /**
* retrieves a resource record without regard to type
*
* @return null if not found
+ * @throws JobStillRunningException
+ * if a different job in the session is still running
*/
Record<? extends Map<String, Object>> get(RecordId recordId) throws JobStillRunningException;
@@ -61,6 +101,8 @@
* @param recordId
* {@link RecordId#getId()}
* @return null if not found
+ * @throws JobStillRunningException
+ * if a different job in the session is still running
*/
Record<AAAAData> getAAAA(String fqdn, long recordId) throws JobStillRunningException;
@@ -72,6 +114,8 @@
* @param recordId
* {@link RecordId#getId()}
* @return null if not found
+ * @throws JobStillRunningException
+ * if a different job in the session is still running
*/
Record<AData> getA(String fqdn, long recordId) throws JobStillRunningException;
@@ -83,6 +127,8 @@
* @param recordId
* {@link RecordId#getId()}
* @return null if not found
+ * @throws JobStillRunningException
+ * if a different job in the session is still running
*/
Record<CNAMEData> getCNAME(String fqdn, long recordId) throws JobStillRunningException;
@@ -94,6 +140,8 @@
* @param recordId
* {@link RecordId#getId()}
* @return null if not found
+ * @throws JobStillRunningException
+ * if a different job in the session is still running
*/
Record<MXData> getMX(String fqdn, long recordId) throws JobStillRunningException;
@@ -105,6 +153,8 @@
* @param recordId
* {@link RecordId#getId()}
* @return null if not found
+ * @throws JobStillRunningException
+ * if a different job in the session is still running
*/
Record<NSData> getNS(String fqdn, long recordId) throws JobStillRunningException;
@@ -116,6 +166,8 @@
* @param recordId
* {@link RecordId#getId()}
* @return null if not found
+ * @throws JobStillRunningException
+ * if a different job in the session is still running
*/
Record<PTRData> getPTR(String fqdn, long recordId) throws JobStillRunningException;
@@ -127,6 +179,8 @@
* @param recordId
* {@link RecordId#getId()}
* @return null if not found
+ * @throws JobStillRunningException
+ * if a different job in the session is still running
*/
SOARecord getSOA(String fqdn, long recordId) throws JobStillRunningException;
@@ -138,6 +192,8 @@
* @param recordId
* {@link RecordId#getId()}
* @return null if not found
+ * @throws JobStillRunningException
+ * if a different job in the session is still running
*/
Record<SRVData> getSRV(String fqdn, long recordId) throws JobStillRunningException;
@@ -149,6 +205,8 @@
* @param recordId
* {@link RecordId#getId()}
* @return null if not found
+ * @throws JobStillRunningException
+ * if a different job in the session is still running
*/
Record<TXTData> getTXT(String fqdn, long recordId) throws JobStillRunningException;
}
\ No newline at end of file
diff --git a/labs/dynect/src/main/java/org/jclouds/dynect/v3/features/RecordAsyncApi.java b/labs/dynect/src/main/java/org/jclouds/dynect/v3/features/RecordAsyncApi.java
index 20fce2b..6902a81 100644
--- a/labs/dynect/src/main/java/org/jclouds/dynect/v3/features/RecordAsyncApi.java
+++ b/labs/dynect/src/main/java/org/jclouds/dynect/v3/features/RecordAsyncApi.java
@@ -19,18 +19,26 @@
package org.jclouds.dynect.v3.features;
import static com.google.common.base.Preconditions.checkNotNull;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.jclouds.http.Uris.uriBuilder;
import java.net.URI;
import java.util.Map;
+import javax.inject.Inject;
import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
+import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.dynect.v3.DynECTExceptions.JobStillRunningException;
+import org.jclouds.dynect.v3.domain.CreateRecord;
+import org.jclouds.dynect.v3.domain.Job;
import org.jclouds.dynect.v3.domain.Record;
import org.jclouds.dynect.v3.domain.RecordId;
import org.jclouds.dynect.v3.domain.SOARecord;
@@ -46,6 +54,7 @@
import org.jclouds.dynect.v3.filters.SessionManager;
import org.jclouds.dynect.v3.functions.ToRecordIds;
import org.jclouds.http.HttpRequest;
+import org.jclouds.json.Json;
import org.jclouds.rest.Binder;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Fallback;
@@ -79,6 +88,58 @@
ListenableFuture<FluentIterable<RecordId>> list() throws JobStillRunningException;
/**
+ * @see RecordApi#listByFQDNAndType
+ */
+ @Named("GetRecord")
+ @GET
+ @Path("/{type}Record/{zone}/{fqdn}")
+ @ResponseParser(ToRecordIds.class)
+ ListenableFuture<FluentIterable<RecordId>> listByFQDNAndType(@PathParam("fqdn") String fqdn,
+ @PathParam("type") String type) throws JobStillRunningException;
+
+ /**
+ * @see RecordApi#scheduleCreate
+ */
+ @Named("CreateRecord")
+ @POST
+ @Path("/{type}Record/{zone}/{fqdn}")
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ ListenableFuture<Job> scheduleCreate(@BinderParam(CreateRecordBinder.class) CreateRecord<?> newRecord)
+ throws JobStillRunningException;
+
+ static class CreateRecordBinder implements Binder {
+ private final Json json;
+
+ @Inject
+ CreateRecordBinder(Json json){
+ this.json = checkNotNull(json, "json");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <R extends HttpRequest> R bindToRequest(R request, Object arg) {
+ CreateRecord<?> in = CreateRecord.class.cast(checkNotNull(arg, "record to create"));
+ URI path = uriBuilder(request.getEndpoint())
+ .build(ImmutableMap.<String, Object> builder()
+ .put("type", in.getType())
+ .put("fqdn", in.getFQDN()).build());
+ return (R) request.toBuilder()
+ .endpoint(path)
+ .payload(json.toJson(ImmutableMap.of("rdata", ImmutableMap.copyOf(in.getRData()), "ttl", in.getTTL().intValue()))).build();
+ }
+ }
+
+ /**
+ * @see RecordApi#scheduleDelete
+ */
+ @Named("DeleteRecord")
+ @DELETE
+ @Fallback(NullOnNotFoundOr404.class)
+ @Consumes(APPLICATION_JSON)
+ ListenableFuture<Job> scheduleDelete(@BinderParam(RecordIdBinder.class) RecordId recordId) throws JobStillRunningException;
+
+ /**
* @see RecordApi#get
*/
@Named("GetRecord")
diff --git a/labs/dynect/src/test/java/org/jclouds/dynect/v3/features/RecordApiExpectTest.java b/labs/dynect/src/test/java/org/jclouds/dynect/v3/features/RecordApiExpectTest.java
index ea4e5e7..aea0721 100644
--- a/labs/dynect/src/test/java/org/jclouds/dynect/v3/features/RecordApiExpectTest.java
+++ b/labs/dynect/src/test/java/org/jclouds/dynect/v3/features/RecordApiExpectTest.java
@@ -19,13 +19,18 @@
package org.jclouds.dynect.v3.features;
import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
+import static com.google.common.net.HttpHeaders.ACCEPT;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.jclouds.dynect.v3.domain.RecordId.recordIdBuilder;
+import static org.jclouds.dynect.v3.domain.rdata.AData.a;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import org.jclouds.dynect.v3.DynECTApi;
+import org.jclouds.dynect.v3.domain.CreateRecord;
+import org.jclouds.dynect.v3.domain.Job;
import org.jclouds.dynect.v3.domain.RecordId;
+import org.jclouds.dynect.v3.domain.rdata.AData;
import org.jclouds.dynect.v3.internal.BaseDynECTApiExpectTest;
import org.jclouds.dynect.v3.parse.GetAAAARecordResponseTest;
import org.jclouds.dynect.v3.parse.GetARecordResponseTest;
@@ -48,33 +53,33 @@
@Test(groups = "unit", testName = "RecordApiExpectTest")
public class RecordApiExpectTest extends BaseDynECTApiExpectTest {
HttpRequest getSOA = HttpRequest.builder().method("GET")
- .endpoint("https://api2.dynect.net/REST/SOARecord/adrianc.zone.dynecttest.jclouds.org/adrianc.zone.dynecttest.jclouds.org/50976579")
- .addHeader("API-Version", "3.3.8")
- .addHeader(CONTENT_TYPE, APPLICATION_JSON)
- .addHeader("Auth-Token", authToken).build();
+ .endpoint("https://api2.dynect.net/REST/SOARecord/jclouds.org/jclouds.org/50976579")
+ .addHeader("API-Version", "3.3.8")
+ .addHeader(CONTENT_TYPE, APPLICATION_JSON)
+ .addHeader("Auth-Token", authToken).build();
HttpResponse soaResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/get_record_soa.json", APPLICATION_JSON)).build();
RecordId soaId = recordIdBuilder()
- .zone("adrianc.zone.dynecttest.jclouds.org")
- .fqdn("adrianc.zone.dynecttest.jclouds.org")
+ .zone("jclouds.org")
+ .fqdn("jclouds.org")
.type("SOA")
.id(50976579l).build();
public void testGetWhenResponseIs2xx() {
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, getSOA, soaResponse);
- assertEquals(success.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").get(soaId).toString(),
+ assertEquals(success.getRecordApiForZone("jclouds.org").get(soaId).toString(),
new GetRecordResponseTest().expected().toString());
}
public void testGetWhenResponseIs404() {
DynECTApi fail = requestsSendResponses(createSession, createSessionResponse, getSOA, notFound);
- assertNull(fail.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").get(soaId));
+ assertNull(fail.getRecordApiForZone("jclouds.org").get(soaId));
}
HttpRequest getAAAA = HttpRequest.builder().method("GET")
- .endpoint("https://api2.dynect.net/REST/AAAARecord/adrianc.zone.dynecttest.jclouds.org/adrianc.zone.dynecttest.jclouds.org/50976579")
+ .endpoint("https://api2.dynect.net/REST/AAAARecord/jclouds.org/jclouds.org/50976579")
.addHeader("API-Version", "3.3.8")
.addHeader(CONTENT_TYPE, APPLICATION_JSON)
.addHeader("Auth-Token", authToken).build();
@@ -83,24 +88,24 @@
.payload(payloadFromResourceWithContentType("/get_record_aaaa.json", APPLICATION_JSON)).build();
RecordId aaaaId = recordIdBuilder()
- .zone("adrianc.zone.dynecttest.jclouds.org")
- .fqdn("adrianc.zone.dynecttest.jclouds.org")
+ .zone("jclouds.org")
+ .fqdn("jclouds.org")
.type("AAAA")
.id(50976579l).build();
public void testGetAAAAWhenResponseIs2xx() {
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, getAAAA, aaaaResponse);
- assertEquals(success.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getAAAA(aaaaId.getFQDN(), aaaaId.getId()).toString(),
+ assertEquals(success.getRecordApiForZone("jclouds.org").getAAAA(aaaaId.getFQDN(), aaaaId.getId()).toString(),
new GetAAAARecordResponseTest().expected().toString());
}
public void testGetAAAAWhenResponseIs404() {
DynECTApi fail = requestsSendResponses(createSession, createSessionResponse, getAAAA, notFound);
- assertNull(fail.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getAAAA(aaaaId.getFQDN(), aaaaId.getId()));
+ assertNull(fail.getRecordApiForZone("jclouds.org").getAAAA(aaaaId.getFQDN(), aaaaId.getId()));
}
HttpRequest getA = HttpRequest.builder().method("GET")
- .endpoint("https://api2.dynect.net/REST/ARecord/adrianc.zone.dynecttest.jclouds.org/adrianc.zone.dynecttest.jclouds.org/50976579")
+ .endpoint("https://api2.dynect.net/REST/ARecord/jclouds.org/jclouds.org/50976579")
.addHeader("API-Version", "3.3.8")
.addHeader(CONTENT_TYPE, APPLICATION_JSON)
.addHeader("Auth-Token", authToken).build();
@@ -109,24 +114,24 @@
.payload(payloadFromResourceWithContentType("/get_record_a.json", APPLICATION_JSON)).build();
RecordId aId = recordIdBuilder()
- .zone("adrianc.zone.dynecttest.jclouds.org")
- .fqdn("adrianc.zone.dynecttest.jclouds.org")
+ .zone("jclouds.org")
+ .fqdn("jclouds.org")
.type("A")
.id(50976579l).build();
public void testGetAWhenResponseIs2xx() {
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, getA, aResponse);
- assertEquals(success.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getA(aId.getFQDN(), aId.getId()).toString(),
+ assertEquals(success.getRecordApiForZone("jclouds.org").getA(aId.getFQDN(), aId.getId()).toString(),
new GetARecordResponseTest().expected().toString());
}
public void testGetAWhenResponseIs404() {
DynECTApi fail = requestsSendResponses(createSession, createSessionResponse, getA, notFound);
- assertNull(fail.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getA(aId.getFQDN(), aId.getId()));
+ assertNull(fail.getRecordApiForZone("jclouds.org").getA(aId.getFQDN(), aId.getId()));
}
HttpRequest getCNAME = HttpRequest.builder().method("GET")
- .endpoint("https://api2.dynect.net/REST/CNAMERecord/adrianc.zone.dynecttest.jclouds.org/adrianc.zone.dynecttest.jclouds.org/50976579")
+ .endpoint("https://api2.dynect.net/REST/CNAMERecord/jclouds.org/jclouds.org/50976579")
.addHeader("API-Version", "3.3.8")
.addHeader(CONTENT_TYPE, APPLICATION_JSON)
.addHeader("Auth-Token", authToken).build();
@@ -135,24 +140,24 @@
.payload(payloadFromResourceWithContentType("/get_record_cname.json", APPLICATION_JSON)).build();
RecordId cnameId = recordIdBuilder()
- .zone("adrianc.zone.dynecttest.jclouds.org")
- .fqdn("adrianc.zone.dynecttest.jclouds.org")
+ .zone("jclouds.org")
+ .fqdn("jclouds.org")
.type("CNAME")
.id(50976579l).build();
public void testGetCNAMEWhenResponseIs2xx() {
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, getCNAME, cnameResponse);
- assertEquals(success.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getCNAME(cnameId.getFQDN(), cnameId.getId()).toString(),
+ assertEquals(success.getRecordApiForZone("jclouds.org").getCNAME(cnameId.getFQDN(), cnameId.getId()).toString(),
new GetCNAMERecordResponseTest().expected().toString());
}
public void testGetCNAMEWhenResponseIs404() {
DynECTApi fail = requestsSendResponses(createSession, createSessionResponse, getCNAME, notFound);
- assertNull(fail.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getCNAME(cnameId.getFQDN(), cnameId.getId()));
+ assertNull(fail.getRecordApiForZone("jclouds.org").getCNAME(cnameId.getFQDN(), cnameId.getId()));
}
HttpRequest getMX = HttpRequest.builder().method("GET")
- .endpoint("https://api2.dynect.net/REST/MXRecord/adrianc.zone.dynecttest.jclouds.org/adrianc.zone.dynecttest.jclouds.org/50976579")
+ .endpoint("https://api2.dynect.net/REST/MXRecord/jclouds.org/jclouds.org/50976579")
.addHeader("API-Version", "3.3.8")
.addHeader(CONTENT_TYPE, APPLICATION_JSON)
.addHeader("Auth-Token", authToken).build();
@@ -161,24 +166,24 @@
.payload(payloadFromResourceWithContentType("/get_record_mx.json", APPLICATION_JSON)).build();
RecordId mxId = recordIdBuilder()
- .zone("adrianc.zone.dynecttest.jclouds.org")
- .fqdn("adrianc.zone.dynecttest.jclouds.org")
+ .zone("jclouds.org")
+ .fqdn("jclouds.org")
.type("MX")
.id(50976579l).build();
public void testGetMXWhenResponseIs2xx() {
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, getMX, mxResponse);
- assertEquals(success.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getMX(mxId.getFQDN(), mxId.getId()).toString(),
+ assertEquals(success.getRecordApiForZone("jclouds.org").getMX(mxId.getFQDN(), mxId.getId()).toString(),
new GetMXRecordResponseTest().expected().toString());
}
public void testGetMXWhenResponseIs404() {
DynECTApi fail = requestsSendResponses(createSession, createSessionResponse, getMX, notFound);
- assertNull(fail.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getMX(mxId.getFQDN(), mxId.getId()));
+ assertNull(fail.getRecordApiForZone("jclouds.org").getMX(mxId.getFQDN(), mxId.getId()));
}
HttpRequest getNS = HttpRequest.builder().method("GET")
- .endpoint("https://api2.dynect.net/REST/NSRecord/adrianc.zone.dynecttest.jclouds.org/adrianc.zone.dynecttest.jclouds.org/50976579")
+ .endpoint("https://api2.dynect.net/REST/NSRecord/jclouds.org/jclouds.org/50976579")
.addHeader("API-Version", "3.3.8")
.addHeader(CONTENT_TYPE, APPLICATION_JSON)
.addHeader("Auth-Token", authToken).build();
@@ -187,24 +192,24 @@
.payload(payloadFromResourceWithContentType("/get_record_ns.json", APPLICATION_JSON)).build();
RecordId nsId = recordIdBuilder()
- .zone("adrianc.zone.dynecttest.jclouds.org")
- .fqdn("adrianc.zone.dynecttest.jclouds.org")
+ .zone("jclouds.org")
+ .fqdn("jclouds.org")
.type("NS")
.id(50976579l).build();
public void testGetNSWhenResponseIs2xx() {
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, getNS, nsResponse);
- assertEquals(success.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getNS(nsId.getFQDN(), nsId.getId()).toString(),
+ assertEquals(success.getRecordApiForZone("jclouds.org").getNS(nsId.getFQDN(), nsId.getId()).toString(),
new GetNSRecordResponseTest().expected().toString());
}
public void testGetNSWhenResponseIs404() {
DynECTApi fail = requestsSendResponses(createSession, createSessionResponse, getNS, notFound);
- assertNull(fail.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getNS(nsId.getFQDN(), nsId.getId()));
+ assertNull(fail.getRecordApiForZone("jclouds.org").getNS(nsId.getFQDN(), nsId.getId()));
}
HttpRequest getPTR = HttpRequest.builder().method("GET")
- .endpoint("https://api2.dynect.net/REST/PTRRecord/adrianc.zone.dynecttest.jclouds.org/adrianc.zone.dynecttest.jclouds.org/50976579")
+ .endpoint("https://api2.dynect.net/REST/PTRRecord/jclouds.org/jclouds.org/50976579")
.addHeader("API-Version", "3.3.8")
.addHeader(CONTENT_TYPE, APPLICATION_JSON)
.addHeader("Auth-Token", authToken).build();
@@ -213,35 +218,35 @@
.payload(payloadFromResourceWithContentType("/get_record_ptr.json", APPLICATION_JSON)).build();
RecordId ptrId = recordIdBuilder()
- .zone("adrianc.zone.dynecttest.jclouds.org")
- .fqdn("adrianc.zone.dynecttest.jclouds.org")
+ .zone("jclouds.org")
+ .fqdn("jclouds.org")
.type("PTR")
.id(50976579l).build();
public void testGetPTRWhenResponseIs2xx() {
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, getPTR, ptrResponse);
- assertEquals(success.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getPTR(ptrId.getFQDN(), ptrId.getId()).toString(),
+ assertEquals(success.getRecordApiForZone("jclouds.org").getPTR(ptrId.getFQDN(), ptrId.getId()).toString(),
new GetPTRRecordResponseTest().expected().toString());
}
public void testGetPTRWhenResponseIs404() {
DynECTApi fail = requestsSendResponses(createSession, createSessionResponse, getPTR, notFound);
- assertNull(fail.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getPTR(ptrId.getFQDN(), ptrId.getId()));
+ assertNull(fail.getRecordApiForZone("jclouds.org").getPTR(ptrId.getFQDN(), ptrId.getId()));
}
public void testGetSOAWhenResponseIs2xx() {
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, getSOA, soaResponse);
- assertEquals(success.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getSOA(soaId.getFQDN(), soaId.getId()).toString(),
+ assertEquals(success.getRecordApiForZone("jclouds.org").getSOA(soaId.getFQDN(), soaId.getId()).toString(),
new GetSOARecordResponseTest().expected().toString());
}
public void testGetSOAWhenResponseIs404() {
DynECTApi fail = requestsSendResponses(createSession, createSessionResponse, getSOA, notFound);
- assertNull(fail.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getSOA(soaId.getFQDN(), soaId.getId()));
+ assertNull(fail.getRecordApiForZone("jclouds.org").getSOA(soaId.getFQDN(), soaId.getId()));
}
HttpRequest getSRV = HttpRequest.builder().method("GET")
- .endpoint("https://api2.dynect.net/REST/SRVRecord/adrianc.zone.dynecttest.jclouds.org/adrianc.zone.dynecttest.jclouds.org/50976579")
+ .endpoint("https://api2.dynect.net/REST/SRVRecord/jclouds.org/jclouds.org/50976579")
.addHeader("API-Version", "3.3.8")
.addHeader(CONTENT_TYPE, APPLICATION_JSON)
.addHeader("Auth-Token", authToken).build();
@@ -250,19 +255,19 @@
.payload(payloadFromResourceWithContentType("/get_record_srv.json", APPLICATION_JSON)).build();
RecordId srvId = recordIdBuilder()
- .zone("adrianc.zone.dynecttest.jclouds.org")
- .fqdn("adrianc.zone.dynecttest.jclouds.org")
+ .zone("jclouds.org")
+ .fqdn("jclouds.org")
.type("SRV")
.id(50976579l).build();
public void testGetSRVWhenResponseIs2xx() {
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, getSRV, srvResponse);
- assertEquals(success.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getSRV(srvId.getFQDN(), srvId.getId()).toString(),
+ assertEquals(success.getRecordApiForZone("jclouds.org").getSRV(srvId.getFQDN(), srvId.getId()).toString(),
new GetSRVRecordResponseTest().expected().toString());
}
HttpRequest getTXT = HttpRequest.builder().method("GET")
- .endpoint("https://api2.dynect.net/REST/TXTRecord/adrianc.zone.dynecttest.jclouds.org/adrianc.zone.dynecttest.jclouds.org/50976579")
+ .endpoint("https://api2.dynect.net/REST/TXTRecord/jclouds.org/jclouds.org/50976579")
.addHeader("API-Version", "3.3.8")
.addHeader(CONTENT_TYPE, APPLICATION_JSON)
.addHeader("Auth-Token", authToken).build();
@@ -271,24 +276,24 @@
.payload(payloadFromResourceWithContentType("/get_record_txt.json", APPLICATION_JSON)).build();
RecordId txtId = recordIdBuilder()
- .zone("adrianc.zone.dynecttest.jclouds.org")
- .fqdn("adrianc.zone.dynecttest.jclouds.org")
+ .zone("jclouds.org")
+ .fqdn("jclouds.org")
.type("TXT")
.id(50976579l).build();
public void testGetTXTWhenResponseIs2xx() {
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, getTXT, txtResponse);
- assertEquals(success.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getTXT(txtId.getFQDN(), txtId.getId()).toString(),
+ assertEquals(success.getRecordApiForZone("jclouds.org").getTXT(txtId.getFQDN(), txtId.getId()).toString(),
new GetTXTRecordResponseTest().expected().toString());
}
public void testGetTXTWhenResponseIs404() {
DynECTApi fail = requestsSendResponses(createSession, createSessionResponse, getTXT, notFound);
- assertNull(fail.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").getTXT(txtId.getFQDN(), txtId.getId()));
+ assertNull(fail.getRecordApiForZone("jclouds.org").getTXT(txtId.getFQDN(), txtId.getId()));
}
HttpRequest list = HttpRequest.builder().method("GET")
- .endpoint("https://api2.dynect.net/REST/AllRecord/adrianc.zone.dynecttest.jclouds.org")
+ .endpoint("https://api2.dynect.net/REST/AllRecord/jclouds.org")
.addHeader("API-Version", "3.3.8")
.addHeader(CONTENT_TYPE, APPLICATION_JSON)
.addHeader("Auth-Token", authToken).build();
@@ -298,7 +303,69 @@
public void testListWhenResponseIs2xx() {
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, list, listResponse);
- assertEquals(success.getRecordApiForZone("adrianc.zone.dynecttest.jclouds.org").list().toString(),
+ assertEquals(success.getRecordApiForZone("jclouds.org").list().toString(),
new ListRecordsResponseTest().expected().toString());
}
+
+ HttpRequest listByFQDNAndType = HttpRequest.builder().method("GET")
+ .endpoint("https://api2.dynect.net/REST/ARecord/jclouds.org/www.foo.com")
+ .addHeader("API-Version", "3.3.8")
+ .addHeader(CONTENT_TYPE, APPLICATION_JSON)
+ .addHeader("Auth-Token", authToken).build();
+
+ public void testListByFQDNAndTypeWhenResponseIs2xx() {
+ DynECTApi success = requestsSendResponses(createSession, createSessionResponse, listByFQDNAndType, listResponse);
+ assertEquals(success.getRecordApiForZone("jclouds.org").listByFQDNAndType("www.foo.com", "A").toString(),
+ new ListRecordsResponseTest().expected().toString());
+ }
+
+ HttpRequest create = HttpRequest.builder().method("POST")
+ .endpoint("https://api2.dynect.net/REST/ARecord/jclouds.org/www.jclouds.org")
+ .addHeader("API-Version", "3.3.8")
+ .addHeader(ACCEPT, APPLICATION_JSON)
+ .addHeader("Auth-Token", authToken)
+ .payload(stringPayload("{\"rdata\":{\"address\":\"1.1.1.1\"},\"ttl\":86400}"))
+ .build();
+
+ HttpResponse createResponse = HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType("/new_record.json", APPLICATION_JSON)).build();
+
+ public void testCreateWhenResponseIs2xx() {
+ DynECTApi success = requestsSendResponses(createSession, createSessionResponse, create, createResponse);
+ CreateRecord<AData> record = CreateRecord.<AData> builder()
+ .fqdn("www.jclouds.org")
+ .type("A")
+ .ttl(86400)
+ .rdata(a("1.1.1.1"))
+ .build();
+ assertEquals(success.getRecordApiForZone("jclouds.org").scheduleCreate(record), Job.success(285372440l));
+ }
+
+ HttpRequest delete = HttpRequest.builder().method("DELETE")
+ .endpoint("https://api2.dynect.net/REST/ARecord/jclouds.org/www.jclouds.org/285372440")
+ .addHeader("API-Version", "3.3.8")
+ .addHeader(ACCEPT, APPLICATION_JSON)
+ .addHeader(CONTENT_TYPE, APPLICATION_JSON)
+ .addHeader("Auth-Token", authToken).build();
+
+ HttpResponse deleteResponse = HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType("/delete_record.json", APPLICATION_JSON)).build();
+
+ RecordId id = recordIdBuilder()
+ .zone("jclouds.org")
+ .fqdn("www.jclouds.org")
+ .type("A")
+ .id(285372440l)
+ .build();
+
+ public void testDeleteWhenResponseIs2xx() {
+ DynECTApi success = requestsSendResponses(createSession, createSessionResponse, delete, deleteResponse);
+
+ assertEquals(success.getRecordApiForZone("jclouds.org").scheduleDelete(id), Job.success(285372457l));
+ }
+
+ public void testDeleteWhenResponseIs404() {
+ DynECTApi fail = requestsSendResponses(createSession, createSessionResponse, delete, notFound);
+ assertNull(fail.getRecordApiForZone("jclouds.org").scheduleDelete(id));
+ }
}
diff --git a/labs/dynect/src/test/java/org/jclouds/dynect/v3/features/RecordApiLiveTest.java b/labs/dynect/src/test/java/org/jclouds/dynect/v3/features/RecordApiLiveTest.java
index 16fb2e2..9c58679 100644
--- a/labs/dynect/src/test/java/org/jclouds/dynect/v3/features/RecordApiLiveTest.java
+++ b/labs/dynect/src/test/java/org/jclouds/dynect/v3/features/RecordApiLiveTest.java
@@ -20,14 +20,21 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.logging.Logger.getAnonymousLogger;
+import static org.jclouds.dynect.v3.domain.rdata.AData.a;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.Map;
+import org.jclouds.JcloudsVersion;
+import org.jclouds.dynect.v3.DynECTExceptions.JobStillRunningException;
+import org.jclouds.dynect.v3.domain.CreateRecord;
+import org.jclouds.dynect.v3.domain.Job;
+import org.jclouds.dynect.v3.domain.Job.Status;
import org.jclouds.dynect.v3.domain.Record;
import org.jclouds.dynect.v3.domain.RecordId;
import org.jclouds.dynect.v3.domain.SOARecord;
+import org.jclouds.dynect.v3.domain.Zone;
import org.jclouds.dynect.v3.domain.rdata.AAAAData;
import org.jclouds.dynect.v3.domain.rdata.AData;
import org.jclouds.dynect.v3.domain.rdata.CNAMEData;
@@ -38,6 +45,7 @@
import org.jclouds.dynect.v3.domain.rdata.SRVData;
import org.jclouds.dynect.v3.domain.rdata.TXTData;
import org.jclouds.dynect.v3.internal.BaseDynECTApiLiveTest;
+import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
@@ -64,8 +72,8 @@
@Test
protected void testListAndGetRecords() {
- for (String zone : context.getApi().getZoneApi().list()) {
- RecordApi api = context.getApi().getRecordApiForZone(zone);
+ for (String zone : zoneApi().list()) {
+ RecordApi api = api(zone);
ImmutableList<RecordId> records = api.list().toList();
getAnonymousLogger().info("zone: " + zone + " record count: " + records.size());
@@ -162,4 +170,85 @@
checkNotNull(rdata.getTxtdata(), "rdata.txtdata cannot be null for TXTRecord: %s", record);
return record;
}
+
+ String zoneFQDN = System.getProperty("user.name").replace('.', '-') + ".record.dynecttest.jclouds.org";
+ String contact = JcloudsVersion.get() + ".jclouds.org";
+
+ private void createZone() {
+ Job job = zoneApi().scheduleCreateWithContact(zoneFQDN, contact);
+ checkNotNull(job, "unable to create zone %s", zoneFQDN);
+ getAnonymousLogger().info("created zone: " + job);
+ assertEquals(job.getStatus(), Status.SUCCESS);
+ assertEquals(context.getApi().getJob(job.getId()), job);
+ Zone zone = zoneApi().publish(zoneFQDN);
+ checkNotNull(zone, "unable to publish zone %s", zoneFQDN);
+ getAnonymousLogger().info("published zone: " + zone);
+ }
+
+ String fqdn = "www." + zoneFQDN;
+ CreateRecord<AData> record = CreateRecord.<AData> builder()
+ .fqdn("www." + zoneFQDN)
+ .type("A")
+ .ttl(86400)
+ .rdata(a("1.1.1.1"))
+ .build();
+
+ public void testCreateRecord() {
+ createZone();
+
+ Job job = null;
+ while (true) {
+ try {
+ job = api(zoneFQDN).scheduleCreate(record);
+ break;
+ } catch (JobStillRunningException e) {
+ continue;
+ }
+ }
+
+ checkNotNull(job, "unable to create record %s", record);
+ getAnonymousLogger().info("created record: " + job);
+ assertEquals(job.getStatus(), Status.SUCCESS);
+ assertEquals(context.getApi().getJob(job.getId()), job);
+ zoneApi().publish(zoneFQDN);
+ }
+
+ RecordId id;
+
+ @Test(dependsOnMethods = "testCreateRecord")
+ public void testListByFQDNAndType() {
+ id = api(zoneFQDN).listByFQDNAndType(record.getFQDN(), record.getType()).toList().get(0);
+ getAnonymousLogger().info(id.toString());
+ Record<? extends Map<String, Object>> newRecord = api(zoneFQDN).get(id);
+ assertEquals(newRecord.getFQDN(), record.getFQDN());
+ assertEquals(newRecord.getType(), record.getType());
+ assertEquals(newRecord.getTTL(), record.getTTL());
+ assertEquals(newRecord.getRData(), record.getRData());
+ checkRecord(newRecord);
+ }
+
+ @Test(dependsOnMethods = "testListByFQDNAndType")
+ public void testDeleteRecord() {
+ Job job = api(zoneFQDN).scheduleDelete(id);
+ checkNotNull(job, "unable to delete record %s", id);
+ getAnonymousLogger().info("deleted record: " + job);
+ assertEquals(job.getStatus(), Status.SUCCESS);
+ assertEquals(context.getApi().getJob(job.getId()), job);
+ zoneApi().publish(zoneFQDN);
+ }
+
+ protected RecordApi api(String zoneFQDN) {
+ return context.getApi().getRecordApiForZone(zoneFQDN);
+ }
+
+ protected ZoneApi zoneApi() {
+ return context.getApi().getZoneApi();
+ }
+
+ @Override
+ @AfterClass(groups = "live", alwaysRun = true)
+ protected void tearDownContext() {
+ zoneApi().delete(zoneFQDN);
+ super.tearDownContext();
+ }
}
diff --git a/labs/dynect/src/test/resources/delete_record.json b/labs/dynect/src/test/resources/delete_record.json
new file mode 100644
index 0000000..af0bf96
--- /dev/null
+++ b/labs/dynect/src/test/resources/delete_record.json
@@ -0,0 +1 @@
+{"status": "success", "data": {}, "job_id": 285372457, "msgs": [{"INFO": "delete: Record will be deleted on zone publish", "SOURCE": "BLL", "ERR_CD": null, "LVL": "INFO"}, {"INFO": "remove_node: www.adriancole.zone.dynecttest.jclouds.org removed from tree.", "SOURCE": "BLL", "ERR_CD": null, "LVL": "INFO"}]}
\ No newline at end of file
diff --git a/labs/dynect/src/test/resources/new_record.json b/labs/dynect/src/test/resources/new_record.json
new file mode 100644
index 0000000..99a3c49
--- /dev/null
+++ b/labs/dynect/src/test/resources/new_record.json
@@ -0,0 +1 @@
+{"status": "success", "data": {"zone": "adriancole.zone.dynecttest.jclouds.org", "ttl": 86400, "fqdn": "www.adriancole.zone.dynecttest.jclouds.org", "record_type": "A", "rdata": {"address": "1.1.1.1"}, "record_id": 0}, "job_id": 285372440, "msgs": [{"INFO": "add: Record added", "SOURCE": "BLL", "ERR_CD": null, "LVL": "INFO"}]}
\ No newline at end of file
diff --git a/labs/dynect/src/test/resources/new_zone.json b/labs/dynect/src/test/resources/new_zone.json
new file mode 100644
index 0000000..1fbbafb
--- /dev/null
+++ b/labs/dynect/src/test/resources/new_zone.json
@@ -0,0 +1 @@
+{"status": "success", "data": {"zone_type": "Primary", "serial_style": "increment", "serial": 0, "zone": "adriancole.zone.dynecttest.jclouds.org"}, "job_id": 285351593, "msgs": [{"INFO": "create: New zone adriancole.zone.dynecttest.jclouds.org created. Publish it to put it on our server.", "SOURCE": "BLL", "ERR_CD": null, "LVL": "INFO"}, {"INFO": "setup: If you plan to provide your own secondary DNS for the zone, allow notify requests from these IP addresses on your nameserver: 204.13.249.66, 208.78.68.66, 2600:2001:0:1::66, 2600:2003:0:1::66", "SOURCE": "BLL", "ERR_CD": null, "LVL": "INFO"}]}
\ No newline at end of file