Merge pull request #1563 from rackspace/1.6.x

The Rackspace Cloud DNS APIs moved over from labs.
This commit is contained in:
Adrian Cole 2013-04-24 10:30:30 -07:00
commit 41f9277148
104 changed files with 8661 additions and 0 deletions

View File

@ -40,6 +40,11 @@
<artifactId>openstack-cinder</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>rackspace-clouddns</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.provider</groupId>
<artifactId>aws-cloudwatch</artifactId>
@ -55,6 +60,16 @@
<artifactId>rackspace-cloudblockstorage-uk</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.provider</groupId>
<artifactId>rackspace-clouddns-us</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.provider</groupId>
<artifactId>rackspace-clouddns-uk</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.provider</groupId>
<artifactId>aws-sqs</artifactId>

View File

@ -52,6 +52,7 @@
<module>cloudservers</module>
<module>rackspace-cloudidentity</module>
<module>rackspace-cloudloadbalancers</module>
<module>rackspace-clouddns</module>
<module>sts</module>
<module>route53</module>
</modules>

View File

@ -0,0 +1,154 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId>
<version>1.6.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath>
</parent>
<groupId>org.jclouds.api</groupId>
<artifactId>rackspace-clouddns</artifactId>
<name>jclouds rackspace clouddns api</name>
<description>jclouds components for Rackspace Cloud DNS</description>
<packaging>bundle</packaging>
<properties>
<test.rackspace-clouddns.endpoint>https://identity.api.rackspacecloud.com/v2.0/</test.rackspace-clouddns.endpoint>
<test.rackspace-clouddns.api-version>1.0</test.rackspace-clouddns.api-version>
<test.rackspace-clouddns.build-version />
<test.rackspace-clouddns.identity>${test.rackspace-us.identity}</test.rackspace-clouddns.identity>
<test.rackspace-clouddns.credential>${test.rackspace-us.credential}</test.rackspace-clouddns.credential>
<jclouds.osgi.export>org.jclouds.rackspace.clouddns.v1*;version="${project.version}"</jclouds.osgi.export>
<jclouds.osgi.import>
org.jclouds.rest.internal;version="${project.version}",
org.jclouds*;version="${project.version}",
*
</jclouds.osgi.import>
</properties>
<dependencies>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>openstack-keystone</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>rackspace-cloudidentity</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-compute</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>openstack-keystone</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>openstack-nova</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>rackspace-cloudidentity</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.provider</groupId>
<artifactId>rackspace-cloudservers-us</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-slf4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<!-- TODO: remove when multiple jobs/session are supported -->
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.rackspace-clouddns.endpoint>${test.rackspace-clouddns.endpoint}</test.rackspace-clouddns.endpoint>
<test.rackspace-clouddns.api-version>${test.rackspace-clouddns.api-version}</test.rackspace-clouddns.api-version>
<test.rackspace-clouddns.build-version>${test.rackspace-clouddns.build-version}</test.rackspace-clouddns.build-version>
<test.rackspace-clouddns.identity>${test.rackspace-clouddns.identity}</test.rackspace-clouddns.identity>
<test.rackspace-clouddns.credential>${test.rackspace-clouddns.credential}</test.rackspace-clouddns.credential>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,106 @@
/**
* 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.rackspace.clouddns.v1;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import java.io.Closeable;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.clouddns.v1.config.CloudDNS;
import org.jclouds.rackspace.clouddns.v1.domain.Job;
import org.jclouds.rackspace.clouddns.v1.features.DomainApi;
import org.jclouds.rackspace.clouddns.v1.features.LimitApi;
import org.jclouds.rackspace.clouddns.v1.features.RecordApi;
import org.jclouds.rackspace.clouddns.v1.features.ReverseDNSApi;
import org.jclouds.rackspace.clouddns.v1.functions.ParseJob;
import org.jclouds.rackspace.clouddns.v1.predicates.JobPredicates;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
/**
* Provides access to the Rackspace Cloud DNS API.
* <p/>
* See <a href="http://docs.rackspace.com/cdns/api/v1.0/cdns-devguide/content/index.html">Cloud DNS Developer Guide</a>
*
* @author Everett Toews
*/
public interface CloudDNSApi extends Closeable {
/**
* Returns the current status of a job.
* </p>
* Operations that create, update, or delete resources may take some time to process. Therefore they return
* a Job containing information, which allows the status and response information of the job to be
* retrieved at a later point in time.
* </p>
* You likely won't need to use this method directly. Use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*
* @return null, if not found.
*/
@Named("job:get")
@Endpoint(CloudDNS.class)
@RequestFilters(AuthenticateRequest.class)
@GET
@Consumes(APPLICATION_JSON)
@ResponseParser(ParseJob.class)
@Fallback(NullOnNotFoundOr404.class)
@QueryParams(keys = "showDetails", values = "true")
@Path("/status/{jobId}")
@Nullable
<T> Job<T> getJob(@PathParam("jobId") String jobId);
/**
* Provides access to Limit features.
*/
@Delegate
LimitApi getLimitApi();
/**
* Provides access to Domain features.
*/
@Delegate
DomainApi getDomainApi();
/**
* Provides access to Record features.
*/
@Delegate
@Path("/domains/{domainId}")
RecordApi getRecordApiForDomain(@PathParam("domainId") int domainId);
/**
* Provides access to Reverse DNS features.
*/
@Delegate
ReverseDNSApi getReverseDNSApiForService(@PayloadParam("serviceName") @PathParam("serviceName") String serviceName);
}

View File

@ -0,0 +1,95 @@
/**
* 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.rackspace.clouddns.v1;
import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
import static org.jclouds.rackspace.cloudidentity.v2_0.ServiceType.DNS;
import static org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes.API_KEY_CREDENTIALS;
import java.net.URI;
import java.util.Properties;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.ProviderModule;
import org.jclouds.rackspace.clouddns.v1.config.CloudDNSHttpApiModule;
import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
import org.jclouds.rest.internal.BaseHttpApiMetadata;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
/**
* Implementation of {@link ApiMetadata} for Rackspace Cloud DNS 1.0 API
*
* @author Everett Toews
*/
public class CloudDNSApiMetadata extends BaseHttpApiMetadata<CloudDNSApi> {
@Override
public Builder toBuilder() {
return new Builder().fromApiMetadata(this);
}
public CloudDNSApiMetadata() {
this(new Builder());
}
protected CloudDNSApiMetadata(Builder builder) {
super(builder);
}
public static Properties defaultProperties() {
Properties properties = BaseHttpApiMetadata.defaultProperties();
properties.setProperty(SERVICE_TYPE, DNS);
properties.setProperty(CREDENTIAL_TYPE, API_KEY_CREDENTIALS);
return properties;
}
public static class Builder extends BaseHttpApiMetadata.Builder<CloudDNSApi, Builder> {
protected Builder() {
id("rackspace-clouddns")
.name("Rackspace Cloud DNS API")
.identityName("Username")
.credentialName("API Key")
.documentation(URI.create("http://docs.rackspace.com/cdns/api/v1.0/cdns-devguide/content/index.html"))
.version("1.0")
.defaultEndpoint("https://identity.api.rackspacecloud.com/v2.0/")
.defaultProperties(CloudDNSApiMetadata.defaultProperties())
.defaultModules(ImmutableSet.<Class<? extends Module>> builder()
.add(CloudIdentityAuthenticationApiModule.class)
.add(CloudIdentityAuthenticationModule.class)
.add(ProviderModule.class)
.add(CloudDNSHttpApiModule.class)
.build());
}
@Override
public CloudDNSApiMetadata build() {
return new CloudDNSApiMetadata(this);
}
@Override
protected Builder self() {
return this;
}
}
}

View File

@ -0,0 +1,47 @@
/**
* 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.rackspace.clouddns.v1;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.rackspace.clouddns.v1.domain.Job;
/**
* Exceptions likely to be encountered when using {@link CloudDNSApi}
*
* @author Everett Toews
*/
public interface CloudDNSExceptions {
/**
* A Job errored out.
*/
public static class JobErrorException extends RuntimeException {
private static final long serialVersionUID = 1L;
private final Job.Error jobError;
public JobErrorException(Job.Error jobError) {
super(jobError.toString());
this.jobError = checkNotNull(jobError, "jobError");
}
public Job.Error getJobError() {
return jobError;
}
}
}

View File

@ -0,0 +1,79 @@
/**
* 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.rackspace.clouddns.v1.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Map;
import javax.inject.Inject;
import javax.ws.rs.core.MediaType;
import org.jclouds.http.HttpRequest;
import org.jclouds.json.Json;
import org.jclouds.rackspace.clouddns.v1.domain.Record;
import org.jclouds.rest.MapBinder;
import com.google.common.collect.ImmutableMap;
/**
* @author Everett Toews
*/
public class CreateReverseDNSToJSON implements MapBinder {
private final Json jsonBinder;
@Inject
public CreateReverseDNSToJSON(Json jsonBinder) {
this.jsonBinder = checkNotNull(jsonBinder, "jsonBinder");
}
@SuppressWarnings("unchecked")
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
checkArgument(checkNotNull(postParams.get("href"), "href") instanceof URI, "href is only valid for a URI!");
checkArgument(checkNotNull(postParams.get("records"), "records") instanceof Iterable,
"records is only valid for an Iterable!");
checkNotNull(postParams.get("serviceName"), "serviceName");
Iterable<Record> records = Iterable.class.cast(postParams.get("records"));
URI deviceURI = URI.class.cast(postParams.get("href"));
String serviceName = postParams.get("serviceName").toString();
String json = toJSON(records, deviceURI, serviceName);
request.setPayload(json);
request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON);
return (R) request.toBuilder().payload(json).build();
}
private String toJSON(Iterable<Record> records, URI deviceURI, String serviceName) {
return jsonBinder.toJson(ImmutableMap.<String, Object> of(
"recordsList", ImmutableMap.of("records", records),
"link", ImmutableMap.<String, Object> of(
"href", deviceURI,
"rel", serviceName)));
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
throw new UnsupportedOperationException("use map form");
}
}

View File

@ -0,0 +1,56 @@
/**
* 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.rackspace.clouddns.v1.binders;
import static java.lang.String.format;
import java.util.List;
import java.util.Map;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.MapBinder;
import com.google.common.base.Joiner;
/**
* @author Everett Toews
*/
public class FormatAndContentsToJSON implements MapBinder {
private static final String template = "{\"domains\":[{\"contentType\":\"%s\",\"contents\":\"%s\"}]}";
@SuppressWarnings("unchecked")
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
String format = postParams.get("format").toString();
List<String> contents = List.class.cast(postParams.get("contents"));
return (R) request.toBuilder().payload(toJSON(format, contents)).build();
}
private String toJSON(String format, List<String> contents) {
String contentsAsOneString = Joiner.on("\\n").join(contents);
return format(template, format, contentsAsOneString);
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
throw new UnsupportedOperationException("use map form");
}
}

View File

@ -0,0 +1,74 @@
/**
* 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.rackspace.clouddns.v1.binders;
import static java.lang.String.format;
import java.util.List;
import java.util.Map;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.MapBinder;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
/**
* @author Everett Toews
*/
public class UpdateDomainsToJSON implements MapBinder {
private static final String template = "{\"domains\":[%s]}";
@SuppressWarnings("unchecked")
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
Iterable<Integer> ids = Iterable.class.cast(postParams.get("ids"));
String key, value, updateTemplate;
if (postParams.get("emailAddress") != null) {
updateTemplate = "{\"id\":%s,\"%s\":\"%s\"}";
key = "emailAddress";
} else if (postParams.get("ttl") != null) {
updateTemplate = "{\"id\":%s,\"%s\":%s}";
key = "ttl";
} else {
throw new IllegalStateException("emailAddress or ttl not found in " + postParams);
}
value = postParams.get(key).toString();
return (R) request.toBuilder().payload(toJSON(ids, updateTemplate, key, value)).build();
}
private String toJSON(Iterable<Integer> ids, String updateTemplate, String key, String value) {
List<String> json = Lists.newArrayList();
for (Integer id: ids) {
json.add(format(updateTemplate, id, key, value));
}
String contentsAsOneString = Joiner.on(",").join(json);
return format(template, contentsAsOneString);
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
throw new UnsupportedOperationException("use map form");
}
}

View File

@ -0,0 +1,98 @@
/**
* 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.rackspace.clouddns.v1.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.ws.rs.core.MediaType;
import org.jclouds.http.HttpRequest;
import org.jclouds.json.Json;
import org.jclouds.rackspace.clouddns.v1.domain.Record;
import org.jclouds.rest.Binder;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
/**
* Binds the Records to the request as a JSON payload.
*
* @author Everett Toews
*/
@Singleton
public class UpdateRecordsToJSON implements Binder {
private final Json jsonBinder;
@Inject
public UpdateRecordsToJSON(Json jsonBinder) {
this.jsonBinder = checkNotNull(jsonBinder, "jsonBinder");
}
@SuppressWarnings("unchecked")
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
checkArgument(checkNotNull(input, "input") instanceof Map, "This binder is only valid for Map<String, Record>");
checkNotNull(request, "request");
Map<String, Record> idsToRecords = (Map<String, Record>) input;
List<UpdateRecord> updateRecords = toUpdateRecordList(idsToRecords);
String json = jsonBinder.toJson(ImmutableMap.of("records", updateRecords));
request.setPayload(json);
request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON);
return request;
}
static List<UpdateRecord> toUpdateRecordList(Map<String, Record> idsToRecords) {
List<UpdateRecord> updateRecords = Lists.newArrayList();
for (String recordId: idsToRecords.keySet()) {
Record record = idsToRecords.get(recordId);
UpdateRecord updateRecord = new UpdateRecord();
updateRecord.id = recordId;
updateRecord.name = record.getName();
updateRecord.ttl = record.getTTL().isPresent() ? record.getTTL().get() : null;
updateRecord.data = record.getData();
updateRecord.priority = record.getPriority();
updateRecord.comment = record.getComment();
updateRecords.add(updateRecord);
}
return updateRecords;
}
static final class UpdateRecord {
public String id;
public String name;
public Integer ttl;
public String data;
public Integer priority;
public String comment;
}
}

View File

@ -0,0 +1,83 @@
/**
* 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.rackspace.clouddns.v1.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.ws.rs.core.MediaType;
import org.jclouds.http.HttpRequest;
import org.jclouds.json.Json;
import org.jclouds.rackspace.clouddns.v1.binders.UpdateRecordsToJSON.UpdateRecord;
import org.jclouds.rackspace.clouddns.v1.domain.Record;
import org.jclouds.rest.MapBinder;
import com.google.common.collect.ImmutableMap;
/**
* @author Everett Toews
*/
public class UpdateReverseDNSToJSON implements MapBinder {
private final Json jsonBinder;
@Inject
public UpdateReverseDNSToJSON(Json jsonBinder) {
this.jsonBinder = checkNotNull(jsonBinder, "jsonBinder");
}
@SuppressWarnings("unchecked")
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
checkArgument(checkNotNull(postParams.get("href"), "href") instanceof URI,
"href is only valid for a URI!");
checkArgument(checkNotNull(postParams.get("idsToRecords"), "idsToRecords") instanceof Map,
"records is only valid for a Map!");
checkNotNull(postParams.get("serviceName"), "serviceName");
Map<String, Record> idsToRecords = Map.class.cast(postParams.get("idsToRecords"));
List<UpdateRecord> updateRecords = UpdateRecordsToJSON.toUpdateRecordList(idsToRecords);
URI deviceURI = URI.class.cast(postParams.get("href"));
String serviceName = postParams.get("serviceName").toString();
String json = toJSON(updateRecords, deviceURI, serviceName);
request.setPayload(json);
request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON);
return (R) request.toBuilder().payload(json).build();
}
private String toJSON(Iterable<UpdateRecord> records, URI deviceURI, String serviceName) {
return jsonBinder.toJson(ImmutableMap.<String, Object> of(
"recordsList", ImmutableMap.of("records", records),
"link", ImmutableMap.<String, Object> of(
"href", deviceURI,
"rel", serviceName)));
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
throw new UnsupportedOperationException("use map form");
}
}

View File

@ -0,0 +1,38 @@
/**
* 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.rackspace.clouddns.v1.config;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
/**
* Represents a component related to Rackspace Cloud DNS.
*
* @author Everett Toews
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Qualifier
public @interface CloudDNS {
}

View File

@ -0,0 +1,46 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.rackspace.clouddns.v1.config;
import java.net.URI;
import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.config.HttpApiModule;
import com.google.common.base.Supplier;
import com.google.inject.TypeLiteral;
/**
* Configures Rackspace Cloud DNS.
*
* @author Everett Toews
*/
@ConfiguresHttpApi
public class CloudDNSHttpApiModule extends HttpApiModule<CloudDNSApi> {
@Override
protected void configure() {
bind(new TypeLiteral<Supplier<URI>>() {}).annotatedWith(CloudDNS.class).to(new TypeLiteral<Supplier<URI>>() {});
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
super.configure();
}
}

View File

@ -0,0 +1,206 @@
/**
* 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.rackspace.clouddns.v1.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
/**
* Create a Domain or Subdomain.
*
* @author Everett Toews
*/
public class CreateDomain {
private final String name;
private final String emailAddress;
private final Optional<Integer> ttl;
private final Optional<String> comment;
// subdomains is an ImmutableMap for serialization
private final ImmutableMap<String, Iterable<CreateSubdomain>> subdomains;
// recordList is an ImmutableMap for serialization
private final ImmutableMap<String, Iterable<Record>> recordsList;
private CreateDomain(String name, String email, Optional<Integer> ttl, Optional<String> comment,
ImmutableMap<String, Iterable<CreateSubdomain>> subdomains,
ImmutableMap<String, Iterable<Record>> recordsList) {
this.name = checkNotNull(name, "name required");
this.emailAddress = checkNotNull(email, "email required");
this.ttl = ttl;
this.comment = comment;
this.subdomains = subdomains != null ? subdomains : ImmutableMap.<String, Iterable<CreateSubdomain>> of();
this.recordsList = recordsList != null ? recordsList : ImmutableMap.<String, Iterable<Record>> of();
}
/**
* @see Builder#name(String)
*/
public String getName() {
return name;
}
/**
* @see Builder#email(String)
*/
public String getEmail() {
return emailAddress;
}
/**
* @see Builder#ttl(Integer)
*/
public Optional<Integer> getTTL() {
return ttl;
}
/**
* @see Builder#comment(String)
*/
public Optional<String> getComment() {
return comment;
}
/**
* @see Builder#subdomains(Iterable)
*/
public Iterable<CreateSubdomain> getSubdomains() {
return subdomains.get("domains");
}
/**
* @see Builder#records(Iterable)
*/
public Iterable<Record> getRecords() {
return recordsList.get("records");
}
@Override
public int hashCode() {
return Objects.hashCode(name);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
CreateDomain that = CreateDomain.class.cast(obj);
return Objects.equal(this.name, that.name);
}
protected ToStringHelper string() {
return Objects.toStringHelper(this).omitNullValues().add("name", name).add("email", emailAddress)
.add("ttl", ttl.orNull()).add("comment", comment.orNull()).add("subdomains", subdomains)
.add("records", recordsList);
}
@Override
public String toString() {
return string().toString();
}
public static class Builder {
private String name;
private String emailAddress;
private Optional<Integer> ttl = Optional.absent();
private Optional<String> comment = Optional.absent();
private ImmutableMap<String, Iterable<CreateSubdomain>> subdomains;
private ImmutableMap<String, Iterable<Record>> records;
/**
* The name for the domain or subdomain. Must be a fully qualified domain name (FQDN) that doesn't end in a '.'.
*/
public Builder name(String name) {
this.name = name;
return this;
}
/**
* Email address to use for contacting the domain administrator. Used as the email-addr (rname) in the SOA record.
*/
public Builder email(String email) {
this.emailAddress = email;
return this;
}
/**
* The duration in seconds that the record may be cached by clients. If specified, must be greater than 300. The
* default value, if not specified, is 3600.
*/
public Builder ttl(Integer ttl) {
this.ttl = Optional.fromNullable(ttl);
return this;
}
/**
* If included, its length must be less than or equal to 160 characters.
*/
public Builder comment(String comment) {
this.comment = Optional.fromNullable(comment);
return this;
}
/**
* Create Subdomains of this Domain.
*/
public Builder subdomains(Iterable<CreateSubdomain> subdomains) {
if (subdomains != null) {
this.subdomains = ImmutableMap.of("domains", subdomains);
}
return this;
}
/**
* Create Records for this Domain.
* </p>
* See <a href="http://docs.rackspace.com/cdns/api/v1.0/cdns-devguide/content/supported_record_types.html">
* Supported Record Types</a>
*/
public Builder records(Iterable<Record> records) {
if (records != null) {
this.records = ImmutableMap.of("records", records);
}
return this;
}
public CreateDomain build() {
return new CreateDomain(name, emailAddress, ttl, comment, subdomains, records);
}
public Builder from(CreateDomain in) {
return this.name(in.getName()).email(in.getEmail()).ttl(in.getTTL().orNull())
.comment(in.getComment().orNull()).subdomains(in.getSubdomains()).records(in.getRecords());
}
}
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return new Builder().from(this);
}
}

View File

@ -0,0 +1,153 @@
/**
* 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.rackspace.clouddns.v1.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.base.Optional;
/**
* @author Everett Toews
*/
public class CreateSubdomain {
private final String name;
private final String emailAddress;
private final Optional<Integer> ttl;
private final Optional<String> comment;
private CreateSubdomain(String name, String email, Optional<Integer> ttl, Optional<String> comment) {
this.name = checkNotNull(name, "name required");
this.emailAddress = checkNotNull(email, "email required");
this.ttl = ttl;
this.comment = comment;
}
/**
* @see Builder#name(String)
*/
public String getName() {
return name;
}
/**
* @see Builder#email(String)
*/
public String getEmail() {
return emailAddress;
}
/**
* @see Builder#ttl(Integer)
*/
public Optional<Integer> getTTL() {
return ttl;
}
/**
* @see Builder#comment(String)
*/
public Optional<String> getComment() {
return comment;
}
@Override
public int hashCode() {
return Objects.hashCode(name);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
CreateSubdomain that = CreateSubdomain.class.cast(obj);
return Objects.equal(this.name, that.name);
}
protected ToStringHelper string() {
return Objects.toStringHelper(this).omitNullValues().add("name", name).add("email", emailAddress)
.add("ttl", ttl.orNull()).add("comment", comment.orNull());
}
@Override
public String toString() {
return string().toString();
}
public static class Builder {
private String name;
private String emailAddress;
private Optional<Integer> ttl = Optional.absent();
private Optional<String> comment = Optional.absent();
/**
* The name for the subdomain. Must be a fully qualified domain name (FQDN) that doesn't end in a '.'.
*/
public Builder name(String name) {
this.name = name;
return this;
}
/**
* Email address to use for contacting the domain administrator. Used as the email-addr (rname) in the SOA record.
*/
public Builder email(String email) {
this.emailAddress = email;
return this;
}
/**
* The duration in seconds that the record may be cached. If specified, must be greater than 300. The default
* value, if not specified, is 3600.
*/
public Builder ttl(Integer ttl) {
this.ttl = Optional.fromNullable(ttl);
return this;
}
/**
* If included, its length must be less than or equal to 160 characters.
*/
public Builder comment(String comment) {
this.comment = Optional.fromNullable(comment);
return this;
}
public CreateSubdomain build() {
return new CreateSubdomain(name, emailAddress, ttl, comment);
}
public Builder from(CreateSubdomain in) {
return this.name(in.getName()).email(in.getEmail()).ttl(in.getTTL().orNull())
.comment(in.getComment().orNull());
}
}
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return new Builder().from(this);
}
}

View File

@ -0,0 +1,162 @@
/**
* 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.rackspace.clouddns.v1.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import java.util.Date;
import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
/**
* A domain is an entity/container of all DNS-related information containing one or more records. Within Rackspace DNS,
* the account which creates the domain is the domain owner.
*
* @author Everett Toews
*/
public class Domain {
private final int id;
private final String name;
private final String email;
private final Optional<String> comment;
private final Date created;
private final Date updated;
private final int accountId;
private final int ttl;
private final Set<String> nameservers;
private final Set<Subdomain> subdomains;
private final Set<RecordDetail> records;
@ConstructorProperties({ "id", "name", "emailAddress", "comment", "created", "updated", "accountId", "ttl",
"nameservers", "subdomains", "recordsList" })
protected Domain(int id, String name, String email, @Nullable String comment, Date created, Date updated,
int accountId, int ttl, @Nullable Set<String> nameservers, @Nullable Set<Subdomain> nameToSubdomain,
@Nullable Set<RecordDetail> records) {
this.id = id;
this.name = name;
this.email = email;
this.comment = Optional.fromNullable(comment);
this.created = created;
this.updated = updated;
this.accountId = accountId;
this.ttl = ttl;
this.nameservers = nameservers != null ? nameservers : ImmutableSet.<String> of();
this.subdomains = nameToSubdomain != null ? nameToSubdomain : ImmutableSet.<Subdomain> of();
this.records = records != null ? records : ImmutableSet.<RecordDetail> of();
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public Optional<String> getComment() {
return comment;
}
public Date getCreated() {
return created;
}
public Date getUpdated() {
return updated;
}
public int getAccountId() {
return accountId;
}
public int getTTL() {
return ttl;
}
public Set<String> getNameservers() {
return nameservers;
}
public Set<Subdomain> getSubdomains() {
return subdomains;
}
public Set<RecordDetail> getRecords() {
return records;
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
Domain that = Domain.class.cast(obj);
return Objects.equal(this.id, that.id);
}
protected ToStringHelper string() {
return Objects.toStringHelper(this).omitNullValues().add("id", id).add("name", name).add("email", email)
.add("comment", comment.orNull()).add("created", created).add("updated", updated)
.add("accountId", accountId).add("ttl", ttl).add("nameservers", nameservers)
.add("subdomains", subdomains).add("records", records);
}
@Override
public String toString() {
return string().toString();
}
protected Domain from(Domain in) {
return new Domain(in.getId(), in.getName(), in.getEmail(), in.getComment().orNull(), in.getCreated(),
in.getUpdated(), in.getAccountId(), in.getTTL(), in.getNameservers(), in.getSubdomains(), in.getRecords());
}
public enum Format {
BIND_9,
UNRECOGNIZED;
public static Format fromValue(String format) {
try {
return valueOf(checkNotNull(format, "format").toUpperCase());
}
catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}
}

View File

@ -0,0 +1,188 @@
/**
* 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.rackspace.clouddns.v1.domain;
import static com.google.common.base.Objects.equal;
import java.beans.ConstructorProperties;
import java.util.Date;
import java.util.List;
import com.google.common.base.Objects;
public class DomainChange {
private final Date from;
private final Date to;
private final List<Change> changes;
@ConstructorProperties({ "from", "to", "changes" })
private DomainChange(Date from, Date to, List<Change> changes) {
this.from = from;
this.to = to;
this.changes = changes;
}
public Date getFrom() {
return from;
}
public Date getTo() {
return to;
}
public List<Change> getChanges() {
return changes;
}
@Override
public int hashCode() {
return Objects.hashCode(from, to, changes);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
DomainChange that = DomainChange.class.cast(obj);
return equal(this.from, that.from) && equal(this.to, that.to) && equal(this.changes, that.changes);
}
@Override
public String toString() {
return Objects.toStringHelper(this).omitNullValues().add("from", from).add("to", to).add("changes", changes)
.toString();
}
public static class Change {
private final String domain;
private final String action;
private final String targetType;
private final int accountId;
private final int targetId;
private final List<ChangeDetail> changeDetails;
@ConstructorProperties({ "domain", "action", "targetType", "accountId", "targetId", "changeDetails" })
protected Change(String domain, String action, String targetType, int accountId, int targetId,
List<ChangeDetail> changeDetails) {
this.domain = domain;
this.action = action;
this.targetType = targetType;
this.accountId = accountId;
this.targetId = targetId;
this.changeDetails = changeDetails;
}
public String getDomain() {
return domain;
}
public String getAction() {
return action;
}
public String getTargetType() {
return targetType;
}
public int getAccountId() {
return accountId;
}
public int getTargetId() {
return targetId;
}
public List<ChangeDetail> getChangeDetails() {
return changeDetails;
}
@Override
public int hashCode() {
return Objects.hashCode(domain, action, targetType, accountId, targetId, changeDetails);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
Change that = Change.class.cast(obj);
return equal(this.domain, that.domain) && equal(this.action, that.action)
&& equal(this.targetType, that.targetType) && equal(this.accountId, that.accountId)
&& equal(this.targetId, that.targetId) && equal(this.changeDetails, that.changeDetails);
}
@Override
public String toString() {
return Objects.toStringHelper(this).omitNullValues().add("domain", domain).add("action", action)
.add("targetType", targetType).add("accountId", accountId).add("targetId", targetId)
.add("changeDetails", changeDetails).toString();
}
}
public static class ChangeDetail {
private final String field;
private final String originalValue;
private final String newValue;
@ConstructorProperties({ "field", "originalValue", "newValue" })
protected ChangeDetail(String field, String originalValue, String newValue) {
this.field = field;
this.originalValue = originalValue;
this.newValue = newValue;
}
public String getField() {
return field;
}
public String getOriginalValue() {
return originalValue;
}
public String getNewValue() {
return newValue;
}
@Override
public int hashCode() {
return Objects.hashCode(field, originalValue, newValue);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
ChangeDetail that = ChangeDetail.class.cast(obj);
return equal(this.field, that.field) && equal(this.originalValue, that.originalValue)
&& equal(this.newValue, that.newValue);
}
@Override
public String toString() {
return Objects.toStringHelper(this).omitNullValues().add("field", field).add("originalValue", originalValue)
.add("newValue", newValue).toString();
}
}
}

View File

@ -0,0 +1,129 @@
package org.jclouds.rackspace.clouddns.v1.domain;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
import com.google.common.base.Optional;
/**
* @see CloudDNSApi#getJob(String)
* @author Everett Toews
*/
public class Job<T> {
private final String id;
private final Status status;
private final Optional<Error> error;
private final Optional<T> resource;
private Job(String id, Status status, Optional<Error> error, Optional<T> resource) {
this.id = id;
this.status = status;
this.error = error;
this.resource = resource;
}
public String getId() {
return id;
}
public Status getStatus() {
return status;
}
public Optional<Error> getError() {
return error;
}
public Optional<T> getResource() {
return resource;
}
public enum Status {
/**
* INITIALIZED is the status that immediately precedes RUNNING and is the first possible state of a job.
* It indicates acceptance of the job.
*/
INITIALIZED,
RUNNING, COMPLETED, ERROR, UNRECOGNIZED;
public static Status fromValue(String status) {
try {
return valueOf(checkNotNull(status, "status").toUpperCase());
}
catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}
public static <T> Builder<T> builder() {
return new Builder<T>();
}
public static class Builder<T> {
private String id;
private Status status;
private Optional<Error> error = Optional.absent();
private Optional<T> resource = Optional.absent();
public Builder<T> id(String id) {
this.id = id;
return this;
}
public Builder<T> status(Status status) {
this.status = status;
return this;
}
public Builder<T> error(Error error) {
this.error = Optional.fromNullable(error);
return this;
}
public Builder<T> resource(T resource) {
this.resource = Optional.fromNullable(resource);
return this;
}
public Job<T> build() {
return new Job<T>(id, status, error, resource);
}
}
public static final class Error {
private final int code;
private final String message;
private final String details;
@ConstructorProperties({ "code", "message", "details" })
protected Error(int code, String message, String details) {
this.code = code;
this.message = message;
this.details = details;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public String getDetails() {
return details;
}
@Override
public String toString() {
return toStringHelper(this).add("code", code).add("message", message).add("details", details).toString();
}
}
}

View File

@ -0,0 +1,221 @@
/**
* 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.rackspace.clouddns.v1.domain;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.base.Optional;
/**
* @author Everett Toews
*/
public class Record {
private final String name;
private final String type;
private final Optional<Integer> ttl;
private final String data;
private final Integer priority;
private final String comment;
private Record(@Nullable String name, @Nullable String type, Optional<Integer> ttl, @Nullable String data,
@Nullable Integer priority, @Nullable String comment) {
this.name = name;
this.type = type;
this.ttl = ttl;
this.data = data;
this.priority = priority;
this.comment = comment;
}
/**
* @see Record.Builder#name(String)
*/
public String getName() {
return name;
}
/**
* @see Record.Builder#type(String)
*/
public String getType() {
return type;
}
/**
* @see Record.Builder#ttl(Integer)
*/
public Optional<Integer> getTTL() {
return ttl;
}
/**
* @see Record.Builder#data(String)
*/
public String getData() {
return data;
}
/**
* @see Record.Builder#priority(Integer)
*/
@Nullable
public Integer getPriority() {
return priority;
}
/**
* @see Record.Builder#comment(String)
*/
@Nullable
public String getComment() {
return comment;
}
@Override
public int hashCode() {
return Objects.hashCode(name, type, ttl, data, priority, comment);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
Record that = Record.class.cast(obj);
return equal(this.name, that.name) && equal(this.type, that.type) && equal(this.ttl, that.ttl)
&& equal(this.data, that.data) && equal(this.priority, that.priority) && equal(this.comment, that.comment);
}
protected ToStringHelper string() {
return toStringHelper(this).omitNullValues().add("name", name).add("type", type).add("ttl", ttl)
.add("data", data).add("priority", priority).add("comment", comment);
}
@Override
public String toString() {
return string().toString();
}
public final static class Builder {
private String name;
private String type;
private Optional<Integer> ttl = Optional.absent();
private String data;
private Integer priority;
private String comment;
/**
* The name for the domain or subdomain. Must be a fully qualified domain name (FQDN) that doesn't end in a '.'.
* </p>
* Users can add one or more wildcard records to any domain or sub-domain on their account. For information on the
* intent and use of wildcard records, see the DNS literature including RFC 1034, section 4.3.3, and RFC 4595.
* </p>
* Wildcards are supported for A, AAAA, CNAME, MX, SRV and TXT record types.
* </p>
* A valid wildcard DNS record is specified by using an asterisk ("*") as the leftmost part of a record name, for
* example *.example.com. An asterisk in any other part of a record name is invalid. Only the asterisk ("*") is
* accepted as a wildcard character.
* </p>
* For SRV records, this specifies the entire service name, which is made up of the service, protocol, and domain
* name to which the record belongs. The service and protocol fields of the service name can be modified but not
* the domain name field.
*/
public Builder name(String name) {
this.name = name;
return this;
}
/**
* The record type to add.
* </p>
* See <a href="http://docs.rackspace.com/cdns/api/v1.0/cdns-devguide/content/supported_record_types.html">
* Supported Record Types</a>
*/
public Builder type(String type) {
this.type = type;
return this;
}
/**
* The duration in seconds that the record may be cached by clients. If specified, must be greater than 300. The
* default value, if not specified, is 3600.
*/
public Builder ttl(int ttl) {
this.ttl = Optional.fromNullable(ttl);
return this;
}
/**
* @see Builder#ttl(int)
*/
public Builder ttl(Optional<Integer> ttl) {
this.ttl = ttl;
return this;
}
/**
* The data field for PTR, A, and AAAA records must be a valid IPv4 or IPv6 IP address.
*/
public Builder data(String data) {
this.data = data;
return this;
}
/**
* Required for MX and SRV records, but forbidden for other record types. If specified, must be an integer from 0
* to 65535.
*/
public Builder priority(Integer priority) {
this.priority = priority;
return this;
}
/**
* If included, its length must be less than or equal to 160 characters.
*/
public Builder comment(String comment) {
this.comment = comment;
return this;
}
public Record build() {
return new Record(name, type, ttl, data, priority, comment);
}
public Builder from(Record in) {
return name(in.getName()).type(in.getType()).ttl(in.getTTL()).data(in.getData()).priority(in.getPriority())
.comment(in.getComment());
}
}
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return builder().from(this);
}
}

View File

@ -0,0 +1,186 @@
/**
* 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.rackspace.clouddns.v1.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.Date;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
/**
* @author Everett Toews
*/
public class RecordDetail {
private final String id;
private final Date created;
private final Date updated;
private final Record record;
private RecordDetail(String id, Date created, Date updated, Record record) {
this.id = checkNotNull(id, "id required");
this.created = checkNotNull(created, "created required");
this.updated = checkNotNull(updated, "updated required");
this.record = checkNotNull(record, "record required");
}
public String getId() {
return id;
}
/**
* When this record was created.
*/
public Date getCreated() {
return created;
}
/**
* When this record was updated.
*/
public Date getUpdated() {
return updated;
}
/**
* The Record.
*/
public Record getRecord() {
return record;
}
/**
* @see Record.Builder#name(String)
*/
public String getName() {
return record.getName();
}
/**
* @see Record.Builder#type(String)
*/
public String getType() {
return record.getType();
}
/**
* @see Record.Builder#ttl(Integer)
*/
public int getTTL() {
return record.getTTL().get();
}
/**
* @see Record.Builder#data(String)
*/
public String getData() {
return record.getData();
}
/**
* @see Record.Builder#priority(Integer)
*/
public Integer getPriority() {
return record.getPriority();
}
/**
* @see Record.Builder#comment(String)
*/
public String getComment() {
return record.getComment();
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
RecordDetail that = RecordDetail.class.cast(obj);
return equal(this.id, that.id);
}
protected ToStringHelper string() {
return toStringHelper(this).omitNullValues().add("id", id).add("created", created).add("updated", updated)
.add("record", record);
}
@Override
public String toString() {
return string().toString();
}
public final static class Builder {
private String id;
private Date created;
private Date updated;
private Record record;
public Builder id(String id) {
this.id = id;
return this;
}
public Builder created(Date created) {
this.created = created;
return this;
}
public Builder updated(Date updated) {
this.updated = updated;
return this;
}
public Builder record(Record record) {
this.record = record;
return this;
}
public Builder record(Record.Builder recordBuilder) {
this.record = recordBuilder.build();
return this;
}
public RecordDetail build() {
return new RecordDetail(id, created, updated, record);
}
public Builder from(RecordDetail in) {
return this.id(in.getId()).created(in.getCreated()).updated(in.getUpdated()).record(in.getRecord());
}
}
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return builder().from(this);
}
}

View File

@ -0,0 +1,98 @@
/**
* 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.rackspace.clouddns.v1.domain;
import java.beans.ConstructorProperties;
import java.util.Date;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
/**
* Subdomains are domains within a parent domain. Subdomains allow you to delegate domains. Subdomains can themselves
* have subdomains, so third-level, fourth-level, fifth-level, and deeper levels of nesting are possible.
*
* @author Everett Toews
*/
public class Subdomain {
private final int id;
private final String name;
private final String emailAddress;
private final Optional<String> comment;
private final Date created;
private final Date updated;
@ConstructorProperties({ "id", "name", "emailAddress", "comment", "created", "updated" })
private Subdomain(int id, String name, String email, @Nullable String comment, Date created, Date updated) {
this.id = id;
this.name = name;
this.emailAddress = email;
this.comment = Optional.fromNullable(comment);
this.created = created;
this.updated = updated;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getEmail() {
return emailAddress;
}
public Optional<String> getComment() {
return comment;
}
public Date getCreated() {
return created;
}
public Date getUpdated() {
return updated;
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
Subdomain that = Subdomain.class.cast(obj);
return Objects.equal(this.id, that.id);
}
@Override
public String toString() {
return Objects.toStringHelper(this).omitNullValues().add("id", id).add("name", name).add("email", emailAddress)
.add("comment", comment.orNull()).add("created", created).add("updated", updated).toString();
}
}

View File

@ -0,0 +1,125 @@
/**
* 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.rackspace.clouddns.v1.domain;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.base.Optional;
/**
* Update a Domain or Subdomain.
*
* @author Everett Toews
*/
public class UpdateDomain {
private final Optional<String> emailAddress;
private final Optional<Integer> ttl;
private final Optional<String> comment;
private UpdateDomain(Optional<String> email, Optional<Integer> ttl, Optional<String> comment) {
this.emailAddress = email;
this.ttl = ttl;
this.comment = comment;
}
public Optional<String> getEmail() {
return emailAddress;
}
public Optional<Integer> getTTL() {
return ttl;
}
public Optional<String> getComment() {
return comment;
}
@Override
public int hashCode() {
return Objects.hashCode(emailAddress, ttl, comment);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
UpdateDomain that = UpdateDomain.class.cast(obj);
return Objects.equal(this.emailAddress, that.emailAddress) && Objects.equal(this.ttl, that.ttl)
&& Objects.equal(this.comment, that.comment);
}
protected ToStringHelper string() {
return Objects.toStringHelper(this).omitNullValues().add("email", emailAddress.orNull()).add("ttl", ttl.orNull())
.add("comment", comment.orNull());
}
@Override
public String toString() {
return string().toString();
}
public static class Builder {
private Optional<String> emailAddress = Optional.absent();
private Optional<Integer> ttl = Optional.absent();
private Optional<String> comment = Optional.absent();
/**
* Email address to use for contacting the domain administrator.
*/
public Builder email(String email) {
this.emailAddress = Optional.fromNullable(email);
return this;
}
/**
* If specified, must be greater than 300.
*/
public Builder ttl(Integer ttl) {
this.ttl = Optional.fromNullable(ttl);
return this;
}
/**
* If included, its length must be less than or equal to 160 characters.
*/
public Builder comment(String comment) {
this.comment = Optional.fromNullable(comment);
return this;
}
public UpdateDomain build() {
return new UpdateDomain(emailAddress, ttl, comment);
}
public Builder from(UpdateDomain in) {
return this.email(in.getEmail().orNull()).ttl(in.getTTL().orNull()).comment(in.getComment().orNull());
}
}
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return new Builder().from(this);
}
}

View File

@ -0,0 +1,298 @@
/**
* 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.rackspace.clouddns.v1.features;
import java.util.Date;
import java.util.List;
import java.util.Set;
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.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.collect.PagedIterable;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
import org.jclouds.rackspace.clouddns.v1.binders.FormatAndContentsToJSON;
import org.jclouds.rackspace.clouddns.v1.binders.UpdateDomainsToJSON;
import org.jclouds.rackspace.clouddns.v1.config.CloudDNS;
import org.jclouds.rackspace.clouddns.v1.domain.CreateDomain;
import org.jclouds.rackspace.clouddns.v1.domain.Domain;
import org.jclouds.rackspace.clouddns.v1.domain.DomainChange;
import org.jclouds.rackspace.clouddns.v1.domain.Job;
import org.jclouds.rackspace.clouddns.v1.domain.Subdomain;
import org.jclouds.rackspace.clouddns.v1.domain.UpdateDomain;
import org.jclouds.rackspace.clouddns.v1.functions.DomainsToPagedIterable;
import org.jclouds.rackspace.clouddns.v1.functions.ParseDomain;
import org.jclouds.rackspace.clouddns.v1.functions.ParseDomains;
import org.jclouds.rackspace.clouddns.v1.functions.ParseJob;
import org.jclouds.rackspace.clouddns.v1.functions.ParseSubdomains;
import org.jclouds.rackspace.clouddns.v1.functions.SubdomainsToPagedIterable;
import org.jclouds.rackspace.clouddns.v1.predicates.JobPredicates;
import org.jclouds.rackspace.cloudidentity.v2_0.CloudIdentityFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
import org.jclouds.rackspace.cloudidentity.v2_0.domain.PaginatedCollection;
import org.jclouds.rackspace.cloudidentity.v2_0.functions.DateParser;
import org.jclouds.rackspace.cloudidentity.v2_0.options.PaginationOptions;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.annotations.WrapWith;
import org.jclouds.rest.binders.BindToJsonPayload;
/**
* @author Everett Toews
*/
@Endpoint(CloudDNS.class)
@RequestFilters(AuthenticateRequest.class)
public interface DomainApi {
/**
* Provisions one or more new DNS domains based on the configuration defined in CreateDomain. If the domain
* creation cannot be fulfilled due to insufficient or invalid data, Job with an ERROR status will
* be returned with information regarding the nature of the failure in the body of the Job. Failures in the
* validation process are non-recoverable and require the caller to correct the cause of the failure.
* This is an atomic operation: if there is a failure in creation of even a single record, the entire process
* will fail.
* </p>
* When a domain is created, and no Time To Live (TTL) is specified, the SOA minTTL (3600 seconds) is used as the
* default. When a record is added without a specified TTL, it will receive the domain TTL by default. When the
* domain and/or record TTL is supplied by the user, either via a create or update call, the TTL values must be 300
* seconds or more.
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*/
@Named("domain:create")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseJob.class)
@Path("/domains")
Job<Set<Domain>> create(@WrapWith("domains") Iterable<CreateDomain> createDomains);
/**
* The resulting list is flat, and does not break the domains down hierarchically by subdomain. All representative
* domains are included in the list, even if a domain is conceptually a subdomain of another domain in the list.
* Records are not included.
*/
@Named("domain:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseDomains.class)
@Transform(DomainsToPagedIterable.class)
@Path("/domains")
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
PagedIterable<Domain> list();
/**
* Filtering the search to limit the results returned can be performed by using the nameFilter parameter. For
* example, "hoola.com" matches hoola.com and similar names such as main.hoola.com and sub.hoola.com.
* </p>
* Filter criteria may consist of:
* <ul>
* <li>Any letter (A-Za-z)</li>
* <li>Numbers (0-9)</li>
* <li>Hyphen ("-")</li>
* <li>1 to 63 characters</li>
* </ul>
* Filter criteria should not include any of the following characters: ' + , | ! " £ $ % & / ( ) = ? ^ * ç ° § ; : _
* > ] [ @ à, é, ò
*/
@Named("domain:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseDomains.class)
@Transform(DomainsToPagedIterable.class)
@Path("/domains")
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
PagedIterable<Domain> listWithFilterByNamesMatching(@QueryParam("name") String nameFilter);
/**
* The resulting list is flat, and does not break the domains down hierarchically by subdomain.
*/
@Named("domain:list")
@GET
@ResponseParser(ParseDomains.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@Path("/domains")
PaginatedCollection<Domain> list(PaginationOptions options);
/**
* List the subdomains of a domain.
*/
@Named("domain:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseSubdomains.class)
@Transform(SubdomainsToPagedIterable.class)
@Path("/domains/{domainId}/subdomains")
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
@Nullable
PagedIterable<Subdomain> listSubdomains(@PathParam("domainId") int domainId);
/**
* List the subdomains of a domain and manually control pagination.
*/
@Named("domain:list")
@GET
@ResponseParser(ParseSubdomains.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@Path("/domains/{domainId}/subdomains")
PaginatedCollection<Subdomain> listSubdomains(@PathParam("domainId") int domainId,
PaginationOptions options);
/**
* Shows all changes to the specified domain since the specified date/time.
*/
@Named("domain:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Path("/domains/{id}/changes")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
DomainChange listChanges(@PathParam("id") int id,
@ParamParser(DateParser.class) @QueryParam("changes") Date since);
/**
* Get all information for a Domain, including records and subdomains.
*/
@Named("domain:get")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Path("/domains/{id}")
@QueryParams(keys = { "showRecords", "showSubdomains" }, values = { "true", "true" })
@ResponseParser(ParseDomain.class)
@Fallback(NullOnNotFoundOr404.class)
@Nullable
Domain get(@PathParam("id") int id);
/**
* This call modifies the domain attributes only. Records cannot be added, modified, or removed.
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*
* @see RecordApi
*/
@Named("domain:update")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseJob.class)
@Path("/domains/{id}")
Job<Void> update(@PathParam("id") int id, @BinderParam(BindToJsonPayload.class) UpdateDomain updateDomain);
/**
* This call modifies the domain's TTL only.
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*/
@Named("domain:update")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseJob.class)
@Path("/domains")
@MapBinder(UpdateDomainsToJSON.class)
Job<Void> updateTTL(@PayloadParam("ids") Iterable<Integer> ids, @PayloadParam("ttl") int ttl);
/**
* This call modifies the domain's email only.
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*/
@Named("domain:update")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseJob.class)
@Path("/domains")
@MapBinder(UpdateDomainsToJSON.class)
Job<Void> updateEmail(@PayloadParam("ids") Iterable<Integer> ids, @PayloadParam("emailAddress") String email);
/**
* This call removes one or more specified domains from the account; when a domain is deleted, its immediate resource
* records are also deleted from the account. By default, if a deleted domain had subdomains, each subdomain becomes
* a root domain and is not deleted; this can be overridden by the optional deleteSubdomains parameter. Utilizing the
* optional deleteSubdomains parameter on domains without subdomains does not result in a failure. When a domain is
* deleted, any and all domain data is immediately purged and is not recoverable via the API.
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*/
@Named("domain:delete")
@DELETE
@Fallback(VoidOnNotFoundOr404.class)
@ResponseParser(ParseJob.class)
@Path("/domains")
@Consumes("*/*")
Job<Void> delete(@QueryParam("id") Iterable<Integer> ids,
@QueryParam("deleteSubdomains") boolean deleteSubdomains);
/**
* This call provides the BIND (Berkeley Internet Name Domain) 9 formatted contents of the requested domain. This
* call is for a single domain only, and as such, does not traverse up or down the domain hierarchy for details (that
* is, no subdomain information is provided).
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*/
@Named("domain:export")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseJob.class)
@Path("/domains/{id}/export")
// format is ignored because the Cloud DNS API doesn't use it but other formats (e.g. BIND 10) may be supported in
// the future and we don't want this interface to change
Job<List<String>> exportFormat(@PathParam("id") int id, Domain.Format format);
/**
* This call provisions a new DNS domain under the account specified by the BIND 9 formatted file configuration
* contents. If the corresponding request cannot be fulfilled due to insufficient or invalid data, an exception will
* be thrown with information regarding the nature of the failure in the body of the response. Failures in the
* validation process are non-recoverable and require the caller to correct the cause of the failure and call again.
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*/
@Named("domain:import")
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseJob.class)
@MapBinder(FormatAndContentsToJSON.class)
@Path("/domains/import")
Job<Domain> importFormat(
@PayloadParam("contents") List<String> contents,
@PayloadParam("format") Domain.Format format);
}

View File

@ -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, 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.rackspace.clouddns.v1.features;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.v2_0.domain.Limits;
import org.jclouds.rackspace.clouddns.v1.config.CloudDNS;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
/**
* All accounts, by default, have a preconfigured set of thresholds (or limits) to manage capacity and prevent abuse
* of the system. The system recognizes two kinds of limits: rate limits and absolute limits. Rate limits are
* thresholds that are reset after a certain amount of time passes. Absolute limits are fixed.
*
* @author Everett Toews
*/
@Endpoint(CloudDNS.class)
@RequestFilters(AuthenticateRequest.class)
public interface LimitApi {
/**
* Provides a list of all applicable limits.
*/
@Named("limits:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@SelectJson("limits")
@Path("/limits")
Limits list();
/**
* All applicable limit types.
*/
@Named("limits:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@SelectJson("limitTypes")
@Path("/limits/types")
Iterable<String> listTypes();
}

View File

@ -0,0 +1,230 @@
/**
* 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.rackspace.clouddns.v1.features;
import java.util.Map;
import java.util.Set;
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.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.collect.PagedIterable;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
import org.jclouds.rackspace.clouddns.v1.binders.UpdateRecordsToJSON;
import org.jclouds.rackspace.clouddns.v1.config.CloudDNS;
import org.jclouds.rackspace.clouddns.v1.domain.Job;
import org.jclouds.rackspace.clouddns.v1.domain.Record;
import org.jclouds.rackspace.clouddns.v1.domain.RecordDetail;
import org.jclouds.rackspace.clouddns.v1.functions.ParseJob;
import org.jclouds.rackspace.clouddns.v1.functions.ParseOnlyRecord;
import org.jclouds.rackspace.clouddns.v1.functions.ParseRecord;
import org.jclouds.rackspace.clouddns.v1.functions.ParseRecords;
import org.jclouds.rackspace.clouddns.v1.functions.RecordsToPagedIterable;
import org.jclouds.rackspace.clouddns.v1.predicates.JobPredicates;
import org.jclouds.rackspace.cloudidentity.v2_0.CloudIdentityFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
import org.jclouds.rackspace.cloudidentity.v2_0.domain.PaginatedCollection;
import org.jclouds.rackspace.cloudidentity.v2_0.options.PaginationOptions;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.annotations.WrapWith;
import org.jclouds.rest.binders.BindToJsonPayload;
/**
* @author Everett Toews
*/
@Endpoint(CloudDNS.class)
@RequestFilters(AuthenticateRequest.class)
public interface RecordApi {
/**
* Create Records for a Domain or Subdomain.
* </p>
* See <a href="http://docs.rackspace.com/cdns/api/v1.0/cdns-devguide/content/supported_record_types.html">
* Supported Record Types</a>
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*/
@Named("record:create")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseJob.class)
@Path("/records")
Job<Set<RecordDetail>> create(@WrapWith("records") Iterable<Record> createRecords);
/**
* This call lists all records configured for the specified domain.
*/
@Named("record:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseRecords.class)
@Transform(RecordsToPagedIterable.class)
@Path("/records")
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
PagedIterable<RecordDetail> list();
/**
* RecordDetails filtered by type.
*/
@Named("record:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseRecords.class)
@Transform(RecordsToPagedIterable.class)
@Path("/records")
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
PagedIterable<RecordDetail> listByType(
@QueryParam("type") String typeFilter);
/**
* RecordDetails filtered by type and data.
*/
@Named("record:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseRecords.class)
@Transform(RecordsToPagedIterable.class)
@Path("/records")
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
PagedIterable<RecordDetail> listByTypeAndData(
@QueryParam("type") String typeFilter,
@QueryParam("data") String dataFilter);
/**
* RecordDetails filtered by name and type.
*/
@Named("record:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseRecords.class)
@Transform(RecordsToPagedIterable.class)
@Path("/records")
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
PagedIterable<RecordDetail> listByNameAndType(
@QueryParam("name") String nameFilter,
@QueryParam("type") String typeFilter);
/**
* Use PaginationOptions to manually control the list of RecordDetail pages returned.
*/
@Named("record:list")
@GET
@ResponseParser(ParseRecords.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@Path("/records")
PaginatedCollection<RecordDetail> list(PaginationOptions options);
/**
* RecordDetails filtered by name and type and data.
*/
@Named("record:get")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseOnlyRecord.class)
@Path("/records")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
RecordDetail getByNameAndTypeAndData(
@QueryParam("name") String nameFilter,
@QueryParam("type") String typeFilter,
@QueryParam("data") String dataFilter);
/**
* Get the details for the specified record in the specified domain.
*/
@Named("record:get")
@GET
@ResponseParser(ParseRecord.class)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/records/{recordId}")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
RecordDetail get(@PathParam("recordId") String recordId);
/**
* Update the configuration of the specified record in the specified domain.
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*/
@Named("record:update")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseJob.class)
@Path("/records/{recordId}")
Job<Void> update(
@PathParam("recordId") String recordId,
@BinderParam(BindToJsonPayload.class) Record record);
/**
* Update the configuration of the specified records in the specified domain.
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*/
@Named("record:update")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseJob.class)
@Path("/records")
Job<Void> update(
@BinderParam(UpdateRecordsToJSON.class) Map<String, Record> idsToRecords);
/**
* Delete the specified record in the specified domain.
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*/
@Named("record:delete")
@DELETE
@Fallback(VoidOnNotFoundOr404.class)
@ResponseParser(ParseJob.class)
@Path("/records/{recordId}")
@Consumes("*/*")
Job<Void> delete(@PathParam("recordId") String recordId);
/**
* Delete the specified records in the specified domain.
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*/
@Named("record:delete")
@DELETE
@Fallback(VoidOnNotFoundOr404.class)
@ResponseParser(ParseJob.class)
@Path("/records")
@Consumes("*/*")
Job<Void> delete(@QueryParam("id") Iterable<String> recordId);
}

View File

@ -0,0 +1,155 @@
/**
* 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.rackspace.clouddns.v1.features;
import java.net.URI;
import java.util.Map;
import java.util.Set;
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.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.collect.PagedIterable;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
import org.jclouds.rackspace.clouddns.v1.binders.CreateReverseDNSToJSON;
import org.jclouds.rackspace.clouddns.v1.binders.UpdateReverseDNSToJSON;
import org.jclouds.rackspace.clouddns.v1.config.CloudDNS;
import org.jclouds.rackspace.clouddns.v1.domain.Job;
import org.jclouds.rackspace.clouddns.v1.domain.Record;
import org.jclouds.rackspace.clouddns.v1.domain.RecordDetail;
import org.jclouds.rackspace.clouddns.v1.functions.ParseJob;
import org.jclouds.rackspace.clouddns.v1.functions.ParseRecord;
import org.jclouds.rackspace.clouddns.v1.functions.ParseRecords;
import org.jclouds.rackspace.clouddns.v1.functions.RecordsToPagedIterable;
import org.jclouds.rackspace.clouddns.v1.predicates.JobPredicates;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.Transform;
/**
* Cloud DNS supports the management of reverse DNS (PTR) records for Rackspace Cloud devices such as Cloud Load
* Balancers and Cloud Servers (both first generation and next generation). In order to manage the PTR records for
* Rackspace Cloud devices, the service as well as the device resource URI must be specified along with record details.
*
* @author Everett Toews
*/
@Endpoint(CloudDNS.class)
@RequestFilters(AuthenticateRequest.class)
public interface ReverseDNSApi {
/**
* List all of the Reverse DNS (PTR) records for a device.
*/
@Named("rdns:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseRecords.class)
@Transform(RecordsToPagedIterable.class)
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
@Path("/rdns/{serviceName}")
PagedIterable<RecordDetail> list(
@QueryParam("href") URI deviceURI);
/**
* List all of the Reverse DNS (PTR) records for a device.
*/
@Named("rdns:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseRecord.class)
@Fallback(NullOnNotFoundOr404.class)
@Path("/rdns/{serviceName}/{recordId}")
RecordDetail get(
@QueryParam("href") URI deviceURI,
@PathParam("recordId") String recordId);
/**
* Create Reverse DNS (PTR) records for a device.
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*/
@Named("rdns:create")
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseJob.class)
@MapBinder(CreateReverseDNSToJSON.class)
@Path("/rdns")
Job<Set<RecordDetail>> create(
@PayloadParam("href") URI deviceURI,
@PayloadParam("records") Iterable<Record> records);
/**
* Update Reverse DNS (PTR) records for a device.
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*/
@Named("rdns:update")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseJob.class)
@MapBinder(UpdateReverseDNSToJSON.class)
@Path("/rdns")
Job<Void> update(
@PayloadParam("href") URI deviceURI,
@PayloadParam("idsToRecords") Map<String, Record> idsToRecords);
/**
* Delete the Reverse DNS (PTR) record with the specified IP address for a device.
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*/
@Named("rdns:delete")
@DELETE
@Fallback(VoidOnNotFoundOr404.class)
@ResponseParser(ParseJob.class)
@Path("/rdns/{serviceName}")
@Consumes("*/*")
Job<Void> delete(@QueryParam("href") URI deviceURI, @QueryParam("ip") String ipAddress);
/**
* Delete all Reverse DNS (PTR) records for a device.
* </p>
* To wait for this call to complete use {@link JobPredicates#awaitComplete(CloudDNSApi, Job)}.
*/
@Named("rdns:delete")
@DELETE
@Fallback(VoidOnNotFoundOr404.class)
@ResponseParser(ParseJob.class)
@Path("/rdns/{serviceName}")
@Consumes("*/*")
Job<Void> deleteAll(@QueryParam("href") URI deviceURI);
}

View File

@ -0,0 +1,51 @@
/**
* 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.rackspace.clouddns.v1.functions;
import java.util.Map;
import java.util.Set;
import org.jclouds.rackspace.clouddns.v1.domain.Domain;
import com.google.common.base.Function;
import com.google.common.collect.Maps;
/**
* Functions for working with Domains.
*
* @author Everett Toews
*/
public class DomainFunctions {
/**
* Take a Set of Domains and return a Map of domain name to the Domain.
*/
public static Map<String, Domain> toDomainMap(Set<Domain> domains) {
return Maps.uniqueIndex(domains, DomainFunctions.GET_DOMAIN_NAME);
}
/**
* Take a Domain and return its name.
*/
public static final Function<Domain, String> GET_DOMAIN_NAME = new Function<Domain, String>() {
public String apply(Domain domain) {
return domain.getName();
}
};
}

View File

@ -0,0 +1,73 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.rackspace.clouddns.v1.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Inject;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.internal.Arg0ToPagedIterable;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
import org.jclouds.rackspace.clouddns.v1.domain.Domain;
import org.jclouds.rackspace.clouddns.v1.features.DomainApi;
import org.jclouds.rackspace.cloudidentity.v2_0.domain.PaginatedCollection;
import org.jclouds.rackspace.cloudidentity.v2_0.options.PaginationOptions;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.base.Optional;
/**
* @author Everett Toews
*/
@Beta
public class DomainsToPagedIterable extends Arg0ToPagedIterable<Domain, DomainsToPagedIterable> {
private final DomainApi api;
@Inject
protected DomainsToPagedIterable(CloudDNSApi api) {
this.api = checkNotNull(api, "api").getDomainApi();
}
@Override
protected Function<Object, IterableWithMarker<Domain>> markerToNextForArg0(Optional<Object> arg0) {
return new ListDomainsAtMarker(api);
}
private static class ListDomainsAtMarker implements Function<Object, IterableWithMarker<Domain>> {
private final DomainApi api;
@Inject
protected ListDomainsAtMarker(DomainApi api) {
this.api = checkNotNull(api, "api");
}
public PaginatedCollection<Domain> apply(Object input) {
PaginationOptions paginationOptions = (PaginationOptions) input;
return api.list(paginationOptions);
}
public String toString() {
return "ListDomainsAtMarker";
}
}
}

View File

@ -0,0 +1,139 @@
/**
* 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.rackspace.clouddns.v1.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.rackspace.clouddns.v1.functions.ParseRecord.toRecordDetails;
import java.beans.ConstructorProperties;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.rackspace.clouddns.v1.domain.Domain;
import org.jclouds.rackspace.clouddns.v1.domain.RecordDetail;
import org.jclouds.rackspace.clouddns.v1.domain.Subdomain;
import org.jclouds.rackspace.clouddns.v1.functions.ParseRecord.RawRecord;
import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
/**
* @author Everett Toews
*/
public class ParseDomain implements Function<HttpResponse, Domain> {
private final ParseJson<RawDomain> json;
@Inject
ParseDomain(ParseJson<RawDomain> json) {
this.json = checkNotNull(json, "json");
}
@Override
public Domain apply(HttpResponse response) {
RawDomain rawDomain = json.apply(response);
if (rawDomain == null)
return null;
return rawDomain.getDomain();
}
/**
* This class is here only to deal with the domain JSON format in Cloud DNS.
*/
static class RawDomain extends Domain {
@ConstructorProperties({ "id", "name", "emailAddress", "comment", "created", "updated", "accountId", "ttl",
"nameservers", "subdomains", "recordsList" })
protected RawDomain(int id, String name, String emailAddress, String comment, Date created, Date updated,
int accountId, int ttl, Iterable<Map<String, String>> nameservers,
SubdomainsWithTotalEntries subdomainsWTE, RecordsWithTotalEntries recordsWTE) {
super(id, name, emailAddress, comment, created, updated, accountId, ttl, transform(nameservers),
transform(subdomainsWTE), transform(recordsWTE));
}
public Domain getDomain() {
return from(this);
}
private static Set<String> transform(Iterable<Map<String, String>> nameserversNasty) {
Builder<String> nameservers = ImmutableSet.builder();
for (Map<String, String> nameToNameserver: nameserversNasty) {
nameservers.add(nameToNameserver.get("name"));
}
return nameservers.build();
}
private static Set<Subdomain> transform(SubdomainsWithTotalEntries subdomainsWTE) {
if (subdomainsWTE == null) {
return null;
}
else {
return ImmutableSet.<Subdomain> copyOf(subdomainsWTE.subdomains);
}
}
private static Set<RecordDetail> transform(RecordsWithTotalEntries recordsWTE) {
if (recordsWTE == null) {
return null;
}
else {
Set<RecordDetail> recordDetails = FluentIterable.from(recordsWTE.records).transform(toRecordDetails).toSet();
return recordDetails;
}
}
/**
* This class is here only to deal with the domain JSON format in Cloud DNS.
*/
private static class SubdomainsWithTotalEntries {
// ignore "totalEntries" in the JSON as it can just be derived form the size of subdomains
@Named("domains")
private Iterable<Subdomain> subdomains;
@ConstructorProperties({ "domains" })
protected SubdomainsWithTotalEntries(Iterable<Subdomain> subdomains) {
this.subdomains = subdomains;
}
}
/**
* This class is here only to deal with the domain JSON format in Cloud DNS.
*/
private static class RecordsWithTotalEntries {
// ignore "totalEntries" in the JSON as it can just be derived form the size of records
private Set<RawRecord> records;
@ConstructorProperties({ "records" })
protected RecordsWithTotalEntries(Set<RawRecord> records) {
this.records = records;
}
}
}
}

View File

@ -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.rackspace.clouddns.v1.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import javax.inject.Inject;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.openstack.v2_0.domain.Link;
import org.jclouds.rackspace.clouddns.v1.domain.Domain;
import org.jclouds.rackspace.cloudidentity.v2_0.domain.PaginatedCollection;
import com.google.common.base.Function;
/**
* @author Everett Toews
*/
public class ParseDomains implements Function<HttpResponse, PaginatedCollection<Domain>> {
private final ParseJson<Domains> json;
@Inject
ParseDomains(ParseJson<Domains> json) {
this.json = checkNotNull(json, "json");
}
@Override
public PaginatedCollection<Domain> apply(HttpResponse response) {
Domains domains = json.apply(response);
return domains;
}
private static class Domains extends PaginatedCollection<Domain> {
@ConstructorProperties({ "domains", "links", "totalEntries" })
protected Domains(Iterable<Domain> domains, Iterable<Link> links, int totalEntries) {
super(domains, links, totalEntries);
}
}
}

View File

@ -0,0 +1,135 @@
/**
* 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.rackspace.clouddns.v1.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.rackspace.clouddns.v1.functions.ParseRecord.toRecordDetails;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import org.jclouds.domain.JsonBall;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.json.Json;
import org.jclouds.rackspace.clouddns.v1.domain.Domain;
import org.jclouds.rackspace.clouddns.v1.domain.Job;
import org.jclouds.rackspace.clouddns.v1.domain.RecordDetail;
import org.jclouds.rackspace.clouddns.v1.functions.ParseDomain.RawDomain;
import org.jclouds.rackspace.clouddns.v1.functions.ParseRecord.RawRecord;
import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.inject.TypeLiteral;
/**
* @author Everett Toews
*/
public class ParseJob implements Function<HttpResponse, Job<?>> {
private final ParseJson<RawJob> parseJson;
private final Json json;
private boolean isCreateSingleRecord;
@Inject
ParseJob(Json json, ParseJson<RawJob> parseJson) {
this.json = checkNotNull(json, "json");
this.parseJson = checkNotNull(parseJson, "parseJson");
}
@Override
public Job<?> apply(HttpResponse response) {
RawJob rawJob = parseJson.apply(response);
if (rawJob == null)
return null;
return toJob(rawJob);
}
public Job<?> toJob(RawJob in) {
return Job.builder().id(in.jobId).status(in.status).error(in.error)
.resource(parseResponse(in.requestUrl, in.response)).build();
}
protected Object parseResponse(String requestUrl, JsonBall response) {
if (response == null) {
return null;
}
else if (requestUrl.contains("import")) {
Type type = new TypeLiteral<Map<String, Set<ParseDomain.RawDomain>>>() { }.getType();
Map<String, Set<RawDomain>> domainMap = json.fromJson(response.toString(), type);
Domain domain = Iterators.getOnlyElement(domainMap.get("domains").iterator()).getDomain();
return domain;
}
else if (requestUrl.contains("export")) {
Type type = new TypeLiteral<Map<String, String>>() { }.getType();
Map<String, String> exportMap = json.fromJson(response.toString(), type);
String contents = exportMap.get("contents");
List<String> contentsAsList = Lists.newArrayList(Splitter.on("\n").omitEmptyStrings().split(contents));
return contentsAsList;
}
else if (response.toString().contains("domains")) {
Type type = new TypeLiteral<Map<String, Set<RawDomain>>>() { }.getType();
Map<String, Set<RawDomain>> domainMap = json.fromJson(response.toString(), type);
Set<Domain> domains = FluentIterable.from(domainMap.get("domains")).transform(toDomain).toSet();
return domains;
}
else if (response.toString().contains("records")) {
Type type = new TypeLiteral<Map<String, Set<RawRecord>>>() { }.getType();
Map<String, Set<RawRecord>> recordMap = json.fromJson(response.toString(), type);
Set<RecordDetail> records = FluentIterable.from(recordMap.get("records")).transform(toRecordDetails).toSet();
if (isCreateSingleRecord) {
return Iterables.getOnlyElement(records);
} else {
return records;
}
}
else {
throw new IllegalStateException("Job parsing problem. Did not recognize any type in job response.\n"
+ response.toString());
}
}
private static class RawJob {
private String jobId;
private Job.Status status;
private Job.Error error;
private String requestUrl;
private JsonBall response;
}
private static final Function<RawDomain, Domain> toDomain = new Function<RawDomain, Domain>() {
public Domain apply(RawDomain domain) {
return domain.getDomain();
}
};
}

View File

@ -0,0 +1,60 @@
/**
* 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.rackspace.clouddns.v1.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.rackspace.clouddns.v1.functions.ParseRecord.toRecordDetails;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.rackspace.clouddns.v1.domain.RecordDetail;
import org.jclouds.rackspace.clouddns.v1.functions.ParseRecord.RawRecord;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
/**
* @author Everett Toews
*/
public class ParseOnlyRecord implements Function<HttpResponse, RecordDetail> {
private final ParseJson<Map<String, List<RawRecord>>> json;
@Inject
ParseOnlyRecord(ParseJson<Map<String, List<RawRecord>>> json) {
this.json = checkNotNull(json, "json");
}
@Override
public RecordDetail apply(HttpResponse response) {
Map<String, List<RawRecord>> records = json.apply(response);
if (records == null)
return null;
RawRecord rawRecord = Iterables.getOnlyElement(records.get("records"));
return toRecordDetails.apply(rawRecord);
}
}

View File

@ -0,0 +1,95 @@
/**
* 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.rackspace.clouddns.v1.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import java.util.Date;
import javax.inject.Inject;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.rackspace.clouddns.v1.domain.Record;
import org.jclouds.rackspace.clouddns.v1.domain.RecordDetail;
import com.google.common.base.Function;
/**
* @author Everett Toews
*/
public class ParseRecord implements Function<HttpResponse, RecordDetail> {
private final ParseJson<RawRecord> json;
@Inject
ParseRecord(ParseJson<RawRecord> json) {
this.json = checkNotNull(json, "json");
}
@Override
public RecordDetail apply(HttpResponse response) {
RawRecord rawRecord = json.apply(response);
if (rawRecord == null)
return null;
return toRecordDetails.apply(rawRecord);
}
static class RawRecord {
public String id;
public String name;
public String type;
public int ttl;
public String data;
public Integer priority;
public String comment;
public Date created;
public Date updated;
@ConstructorProperties({ "id", "name", "type", "ttl", "data", "priority", "comment", "created", "updated" })
protected RawRecord(String id, String name, String type, int ttl, String data, Integer priority, String comment,
Date created, Date updated) {
super();
this.id = id;
this.name = name;
this.type = type;
this.ttl = ttl;
this.data = data;
this.priority = priority;
this.comment = comment;
this.created = created;
this.updated = updated;
}
}
static final Function<RawRecord, RecordDetail> toRecordDetails = new Function<RawRecord, RecordDetail>() {
@Override
public RecordDetail apply(RawRecord rawRecord) {
Record record = Record.builder().name(rawRecord.name).type(rawRecord.type).ttl(rawRecord.ttl)
.data(rawRecord.data).priority(rawRecord.priority).comment(rawRecord.comment).build();
RecordDetail recordDetails = RecordDetail.builder().id(rawRecord.id).created(rawRecord.created)
.updated(rawRecord.updated).record(record).build();
return recordDetails;
}
};
}

View File

@ -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.rackspace.clouddns.v1.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.rackspace.clouddns.v1.functions.ParseRecord.toRecordDetails;
import java.beans.ConstructorProperties;
import javax.inject.Inject;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.openstack.v2_0.domain.Link;
import org.jclouds.rackspace.clouddns.v1.domain.RecordDetail;
import org.jclouds.rackspace.clouddns.v1.functions.ParseRecord.RawRecord;
import org.jclouds.rackspace.cloudidentity.v2_0.domain.PaginatedCollection;
import com.google.common.base.Function;
/**
* @author Everett Toews
*/
public class ParseRecords implements Function<HttpResponse, PaginatedCollection<RecordDetail>> {
private final ParseJson<RawRecords> json;
@Inject
ParseRecords(ParseJson<RawRecords> json) {
this.json = checkNotNull(json, "json");
}
@Override
public PaginatedCollection<RecordDetail> apply(HttpResponse response) {
RawRecords rawRecords = json.apply(response);
Iterable<RecordDetail> records = rawRecords.transform(toRecordDetails);
return new Records(records, rawRecords.getLinks(), rawRecords.getTotalEntries());
}
private static class RawRecords extends PaginatedCollection<RawRecord> {
@ConstructorProperties({ "records", "links", "totalEntries" })
protected RawRecords(Iterable<RawRecord> records, Iterable<Link> links, int totalEntries) {
super(records, links, totalEntries);
}
}
private static class Records extends PaginatedCollection<RecordDetail> {
protected Records(Iterable<RecordDetail> records, Iterable<Link> links, int totalEntries) {
super(records, links, totalEntries);
}
}
}

View File

@ -0,0 +1,68 @@
/**
* 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.rackspace.clouddns.v1.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import javax.inject.Inject;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.openstack.v2_0.domain.Link;
import org.jclouds.rackspace.clouddns.v1.domain.Subdomain;
import org.jclouds.rackspace.cloudidentity.v2_0.domain.PaginatedCollection;
import org.jclouds.rest.InvocationContext;
import com.google.common.base.Function;
/**
* @author Everett Toews
*/
public class ParseSubdomains implements Function<HttpResponse, PaginatedCollection<Subdomain>>, InvocationContext<ParseSubdomains> {
private final ParseJson<Subdomains> json;
@Inject
ParseSubdomains(ParseJson<Subdomains> json) {
this.json = checkNotNull(json, "json");
}
@Override
public PaginatedCollection<Subdomain> apply(HttpResponse response) {
Subdomains subdomains = json.apply(response);
return subdomains;
}
@Override
public ParseSubdomains setContext(HttpRequest request) {
return this;
}
static class Subdomains extends PaginatedCollection<Subdomain> {
@ConstructorProperties({ "domains", "links", "totalEntries" })
protected Subdomains(Iterable<Subdomain> domains, Iterable<Link> links, int totalEntries) {
super(domains, links, totalEntries);
}
}
}

View File

@ -0,0 +1,64 @@
/**
* 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.rackspace.clouddns.v1.functions;
import java.util.Map;
import java.util.Set;
import org.jclouds.rackspace.clouddns.v1.domain.Record;
import org.jclouds.rackspace.clouddns.v1.domain.RecordDetail;
import com.google.common.base.Function;
import com.google.common.collect.Maps;
/**
* Functions for working with Records.
*
* @author Everett Toews
*/
public class RecordFunctions {
private RecordFunctions() {
}
/**
* Take a Set of RecordDetails and return a Map of record id to the Record.
*/
public static Map<String, Record> toRecordMap(Set<RecordDetail> recordDetails) {
Map<String, RecordDetail> idsToRecordDetails = Maps.uniqueIndex(recordDetails, RecordFunctions.GET_RECORD_ID);
return Maps.transformValues(idsToRecordDetails, RecordFunctions.GET_RECORD);
}
/**
* Take a RecordDetail and return its id.
*/
public static final Function<RecordDetail, String> GET_RECORD_ID = new Function<RecordDetail, String>() {
public String apply(RecordDetail recordDetail) {
return recordDetail.getId();
}
};
/**
* Take a RecordDetail and return its Record.
*/
public static final Function<RecordDetail, Record> GET_RECORD = new Function<RecordDetail, Record>() {
public Record apply(RecordDetail recordDetail) {
return recordDetail.getRecord();
}
};
}

View File

@ -0,0 +1,74 @@
/**
* 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.rackspace.clouddns.v1.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Inject;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.internal.Arg0ToPagedIterable;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
import org.jclouds.rackspace.clouddns.v1.domain.RecordDetail;
import org.jclouds.rackspace.clouddns.v1.features.RecordApi;
import org.jclouds.rackspace.cloudidentity.v2_0.domain.PaginatedCollection;
import org.jclouds.rackspace.cloudidentity.v2_0.options.PaginationOptions;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.base.Optional;
/**
* @author Everett Toews
*/
@Beta
public class RecordsToPagedIterable extends Arg0ToPagedIterable<RecordDetail, RecordsToPagedIterable> {
private final CloudDNSApi api;
@Inject
protected RecordsToPagedIterable(CloudDNSApi api) {
this.api = checkNotNull(api, "api");
}
@Override
protected Function<Object, IterableWithMarker<RecordDetail>> markerToNextForArg0(Optional<Object> arg0) {
int domainId = Integer.class.cast(arg0.get());
return new ListRecordsAtMarker(api.getRecordApiForDomain(domainId));
}
private static class ListRecordsAtMarker implements Function<Object, IterableWithMarker<RecordDetail>> {
private final RecordApi api;
@Inject
protected ListRecordsAtMarker(RecordApi api) {
this.api = checkNotNull(api, "api");
}
public PaginatedCollection<RecordDetail> apply(Object input) {
PaginationOptions paginationOptions = (PaginationOptions) input;
return api.list(paginationOptions);
}
public String toString() {
return "ListRecordsAtMarker";
}
}
}

View File

@ -0,0 +1,75 @@
/**
* 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.rackspace.clouddns.v1.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Inject;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.internal.Arg0ToPagedIterable;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
import org.jclouds.rackspace.clouddns.v1.domain.Subdomain;
import org.jclouds.rackspace.clouddns.v1.features.DomainApi;
import org.jclouds.rackspace.cloudidentity.v2_0.domain.PaginatedCollection;
import org.jclouds.rackspace.cloudidentity.v2_0.options.PaginationOptions;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.base.Optional;
/**
* @author Everett Toews
*/
@Beta
public class SubdomainsToPagedIterable extends Arg0ToPagedIterable<Subdomain, SubdomainsToPagedIterable> {
private final DomainApi api;
@Inject
protected SubdomainsToPagedIterable(CloudDNSApi api) {
this.api = checkNotNull(api, "api").getDomainApi();
}
@Override
protected Function<Object, IterableWithMarker<Subdomain>> markerToNextForArg0(Optional<Object> domainId) {
return new ListSubdomainsUnderDomainIdAtMarker(api, Integer.valueOf(domainId.get().toString()));
}
private static class ListSubdomainsUnderDomainIdAtMarker implements Function<Object, IterableWithMarker<Subdomain>> {
private final DomainApi api;
private final int domainId;
@Inject
protected ListSubdomainsUnderDomainIdAtMarker(DomainApi api, int domainId) {
this.api = checkNotNull(api, "api");
this.domainId = domainId;
}
public PaginatedCollection<Subdomain> apply(Object input) {
PaginationOptions paginationOptions = (PaginationOptions) input;
return api.listSubdomains(domainId, paginationOptions);
}
public String toString() {
return "ListSubdomainsUnderDomainIdAtMarker(" + domainId + ")";
}
}
}

View File

@ -0,0 +1,109 @@
/**
* 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.rackspace.clouddns.v1.predicates;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.jclouds.util.Predicates2.retry;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
import org.jclouds.rackspace.clouddns.v1.CloudDNSExceptions;
import org.jclouds.rackspace.clouddns.v1.domain.Job;
import com.google.common.base.Predicate;
import com.google.common.util.concurrent.Atomics;
/**
* Useful Predicates for dealing with Jobs.
*
* @author Everett Toews
*/
public class JobPredicates {
private JobPredicates() {
}
/**
* Tests to see if a Job has completed.
*
* <pre>
* {@code
* CreateDomain createDomain1 = CreateDomain.builder()
* .name("jclouds-example.org")
* .email("jclouds@jclouds-example.org")
* .ttl(600001)
* .comment("Hello Domain 1")
* .build();
*
* Iterable<CreateDomain> createDomains = ImmutableList.of(createDomain1);
* Set<Domain> domains = awaitComplete(api, api.getDomainApi().create(createDomains));
* }
* </pre>
*/
public static <T> T awaitComplete(CloudDNSApi api, Job<T> job)
throws TimeoutException {
AtomicReference<Job<T>> jobRef = Atomics.newReference(job);
if (!retry(jobCompleted(api), 600, 2, 2, SECONDS).apply(jobRef)) {
throw new TimeoutException("Timeout on: " + jobRef.get());
}
return jobRef.get().getResource().orNull();
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private static Predicate<AtomicReference<? extends Job<?>>> jobCompleted(CloudDNSApi cloudDNSApi) {
return new JobStatusPredicate(cloudDNSApi, Job.Status.COMPLETED);
}
private static class JobStatusPredicate<T> implements Predicate<AtomicReference<Job<?>>> {
private CloudDNSApi cloudDNSApi;
private Job.Status status;
private JobStatusPredicate(CloudDNSApi cloudDNSApi, Job.Status status) {
this.cloudDNSApi = checkNotNull(cloudDNSApi, "domainApi must be defined");
this.status = checkNotNull(status, "status must be defined");
}
/**
* @return boolean Return true when the Job reaches status, false otherwise.
*/
@Override
public boolean apply(AtomicReference<Job<?>> jobRef) {
checkNotNull(jobRef, "job must be defined");
if (status.equals(jobRef.get().getStatus())) {
return true;
}
else {
jobRef.set(cloudDNSApi.getJob(jobRef.get().getId()));
checkNotNull(jobRef.get(), "Job %s not found.", jobRef.get().getId());
if (jobRef.get().getError().isPresent()) {
throw new CloudDNSExceptions.JobErrorException(jobRef.get().getError().get());
}
return status.equals(jobRef.get().getStatus());
}
}
}
}

View File

@ -0,0 +1 @@
org.jclouds.rackspace.clouddns.v1.CloudDNSApiMetadata

View File

@ -0,0 +1,50 @@
/**
* 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.rackspace.clouddns.v1.features;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import java.net.URI;
import org.jclouds.http.HttpResponse;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
import org.jclouds.rackspace.clouddns.v1.domain.Domain;
import org.jclouds.rackspace.clouddns.v1.domain.Job;
import org.jclouds.rackspace.clouddns.v1.internal.BaseCloudDNSApiExpectTest;
import org.testng.annotations.Test;
/**
* @author Everett Toews
*/
@Test(groups = "unit")
public class CloudDNSApiExpectTest extends BaseCloudDNSApiExpectTest<CloudDNSApi> {
public void testGetJobDomainExport() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/status/bfbd6ec8-5d4c-49f8-97b5-aa5bfd3e95a4?showDetails=true");
CloudDNSApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/job.json")).build());
Job<Domain> job = api.getJob("bfbd6ec8-5d4c-49f8-97b5-aa5bfd3e95a4");
assertEquals(job.getStatus(), Job.Status.RUNNING);
assertFalse(job.getResource().isPresent());
}
}

View File

@ -0,0 +1,311 @@
/**
* 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.rackspace.clouddns.v1.features;
import static javax.ws.rs.HttpMethod.POST;
import static javax.ws.rs.HttpMethod.PUT;
import static javax.ws.rs.core.Response.Status.OK;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.net.URI;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SimpleTimeZone;
import javax.ws.rs.core.MediaType;
import org.jclouds.http.HttpResponse;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
import org.jclouds.rackspace.clouddns.v1.domain.CreateDomain;
import org.jclouds.rackspace.clouddns.v1.domain.CreateSubdomain;
import org.jclouds.rackspace.clouddns.v1.domain.Domain;
import org.jclouds.rackspace.clouddns.v1.domain.DomainChange;
import org.jclouds.rackspace.clouddns.v1.domain.Job;
import org.jclouds.rackspace.clouddns.v1.domain.Record;
import org.jclouds.rackspace.clouddns.v1.domain.UpdateDomain;
import org.jclouds.rackspace.clouddns.v1.functions.DomainFunctions;
import org.jclouds.rackspace.clouddns.v1.internal.BaseCloudDNSApiExpectTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
/**
* @author Everett Toews
*/
@Test(groups = "unit")
public class DomainApiExpectTest extends BaseCloudDNSApiExpectTest<CloudDNSApi> {
private static final String JCLOUDS_EXAMPLE = "jclouds-example.com";
public void testCreateDomain() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains");
DomainApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET()
.method(POST)
.payload(payloadFromResource("/domain-create.json"))
.endpoint(endpoint)
.build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/domain-create-response.json")).build())
.getDomainApi();
Record createMXRecord = Record.builder()
.type("MX")
.name(JCLOUDS_EXAMPLE)
.data("mail." + JCLOUDS_EXAMPLE)
.priority(11235)
.build();
Record createARecord = Record.builder()
.type("A")
.name(JCLOUDS_EXAMPLE)
.data("10.0.0.1")
.build();
List<Record> createRecords = ImmutableList.of(createMXRecord, createARecord);
CreateSubdomain createSubdomain1 = CreateSubdomain.builder()
.name("dev." + JCLOUDS_EXAMPLE)
.email("jclouds@" + JCLOUDS_EXAMPLE)
.comment("Hello dev subdomain")
.build();
CreateSubdomain createSubdomain2 = CreateSubdomain.builder()
.name("test." + JCLOUDS_EXAMPLE)
.email("jclouds@" + JCLOUDS_EXAMPLE)
.comment("Hello test subdomain")
.build();
List<CreateSubdomain> createSubdomains = ImmutableList.of(createSubdomain1, createSubdomain2);
CreateDomain createDomain1 = CreateDomain.builder()
.name(JCLOUDS_EXAMPLE)
.email("jclouds@" + JCLOUDS_EXAMPLE)
.ttl(600000)
.comment("Hello Domain")
.subdomains(createSubdomains)
.records(createRecords)
.build();
CreateDomain createDomain2 = CreateDomain.builder()
.name("x" + JCLOUDS_EXAMPLE)
.email("jclouds@" + JCLOUDS_EXAMPLE)
.ttl(600000)
.comment("Hello Domain")
.build();
Iterable<CreateDomain> createDomains = ImmutableList.of(createDomain1, createDomain2);
Job<Set<Domain>> job = api.create(createDomains);
assertEquals(job.getStatus(), Job.Status.COMPLETED);
assertTrue(job.getResource().isPresent());
Map<String, Domain> domains = DomainFunctions.toDomainMap(job.getResource().get());
assertEquals(domains.get(JCLOUDS_EXAMPLE).getId(), 3650906);
assertEquals(domains.get(JCLOUDS_EXAMPLE).getEmail(), "jclouds@jclouds-example.com");
assertEquals(domains.get(JCLOUDS_EXAMPLE).getSubdomains().size(), 2);
assertEquals(domains.get(JCLOUDS_EXAMPLE).getRecords().size(), 2);
assertEquals(domains.get("x" + JCLOUDS_EXAMPLE).getId(), 3650909);
}
public void testListDomains() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains");
DomainApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/domain-list.json")).build())
.getDomainApi();
ImmutableList<Domain> domains = api.list().concat().toList();
assertEquals(domains.size(), 4);
for (Domain domain: domains) {
assertTrue(domain.getName().contains(JCLOUDS_EXAMPLE));
}
}
public void testListWithFilterByNamesMatching() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains?name=test.jclouds-example.com");
DomainApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/domain-list-with-filter.json")).build())
.getDomainApi();
ImmutableList<Domain> domains = api.listWithFilterByNamesMatching("test." + JCLOUDS_EXAMPLE).concat().toList();
assertEquals(domains.size(), 1);
assertEquals(domains.get(0).getId(), 3650908);
assertEquals(domains.get(0).getName(), "test." + JCLOUDS_EXAMPLE);
}
public void testListDomainChanges() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/3650908/changes?changes=2013-03-22T03%3A39%3A31Z");
DomainApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/domain-list-changes.json")).build())
.getDomainApi();
Calendar cal = Calendar.getInstance(new SimpleTimeZone(0, "GMT"));
cal.set(2013, 2, 22, 3, 39, 31);
DomainChange domainChange = api.listChanges(3650908, cal.getTime());
assertEquals(domainChange.getChanges().size(), 25);
}
public void testGetDomain() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/3650908?showRecords=true&showSubdomains=true");
DomainApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/domain-get.json")).build())
.getDomainApi();
Domain domain = api.get(3650908);
assertEquals(domain.getName(), "test." + JCLOUDS_EXAMPLE);
assertEquals(domain.getRecords().size(), 2);
assertEquals(domain.getComment().get(), "Hello test subdomain");
assertEquals(domain.getTTL(), 3600);
}
@SuppressWarnings("rawtypes")
public void testUpdateDomain() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/3650908");
DomainApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET()
.method(PUT)
.payload(payloadFromResourceWithContentType("/domain-update.json", MediaType.APPLICATION_JSON))
.endpoint(endpoint)
.build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/domain-update-response.json")).build())
.getDomainApi();
UpdateDomain updateDomain = UpdateDomain.builder()
.email("everett@" + JCLOUDS_EXAMPLE)
.ttl(600001)
.comment("Hello Domain Update")
.build();
Job job = api.update(3650908, updateDomain);
assertEquals(job.getStatus(), Job.Status.COMPLETED);
}
@SuppressWarnings("rawtypes")
public void testUpdateDomainsTTL() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains");
DomainApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET()
.method(PUT)
.payload(payloadFromResource("/domain-update-ttl.json"))
.endpoint(endpoint)
.build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/domain-update-response.json")).build())
.getDomainApi();
List<Integer> ids = ImmutableList.of(3650906, 3650908);
Job job = api.updateTTL(ids, 1234567);
assertEquals(job.getStatus(), Job.Status.COMPLETED);
}
@SuppressWarnings("rawtypes")
public void testUpdateDomainsEmail() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains");
DomainApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET()
.method(PUT)
.payload(payloadFromResource("/domain-update-email.json"))
.endpoint(endpoint)
.build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/domain-update-response.json")).build())
.getDomainApi();
List<Integer> ids = ImmutableList.of(3650906, 3650908);
Job job = api.updateEmail(ids, "everett@" + JCLOUDS_EXAMPLE);
assertEquals(job.getStatus(), Job.Status.COMPLETED);
}
@SuppressWarnings("rawtypes")
public void testDeleteDomains() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains?id=3650907&id=3650906&id=3650908&id=3650909&deleteSubdomains=true");
DomainApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().method("DELETE").replaceHeader("Accept", MediaType.WILDCARD).endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/domain-delete.json")).build())
.getDomainApi();
List<Integer> domainIds = ImmutableList.<Integer> of(3650907, 3650906, 3650908, 3650909);
Job job = api.delete(domainIds, true);
assertEquals(job.getStatus(), Job.Status.COMPLETED);
}
public void testExportDomain() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/3651323/export");
DomainApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/domain-export.json")).build())
.getDomainApi();
Job<List<String>> job = api.exportFormat(3651323, Domain.Format.BIND_9);
assertEquals(job.getStatus(), Job.Status.COMPLETED);
assertEquals(job.getResource().get().size(), 5);
}
public void testImportDomain() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/import");
DomainApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET()
.method(POST)
.payload(payloadFromResource("/domain-import.json"))
.endpoint(endpoint)
.build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/domain-import-response.json")).build())
.getDomainApi();
List<String> contents = ImmutableList.<String> of(
"jclouds-example.com. 3600 IN SOA ns.rackspace.com. jclouds.jclouds-example.com. 1363882703 3600 3600 3600 3600",
"jclouds-example.com. 600 IN A 50.56.174.152");
Job<Domain> job = api.importFormat(contents, Domain.Format.BIND_9);
assertEquals(job.getStatus(), Job.Status.COMPLETED);
assertEquals(job.getResource().get().getName(), JCLOUDS_EXAMPLE);
}
}

View File

@ -0,0 +1,407 @@
/**
* 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.rackspace.clouddns.v1.features;
import static org.jclouds.rackspace.clouddns.v1.predicates.JobPredicates.awaitComplete;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeoutException;
import org.jclouds.rackspace.clouddns.v1.domain.CreateDomain;
import org.jclouds.rackspace.clouddns.v1.domain.CreateSubdomain;
import org.jclouds.rackspace.clouddns.v1.domain.Domain;
import org.jclouds.rackspace.clouddns.v1.domain.Record;
import org.jclouds.rackspace.clouddns.v1.domain.RecordDetail;
import org.jclouds.rackspace.clouddns.v1.domain.Subdomain;
import org.jclouds.rackspace.clouddns.v1.domain.UpdateDomain;
import org.jclouds.rackspace.clouddns.v1.functions.DomainFunctions;
import org.jclouds.rackspace.clouddns.v1.internal.BaseCloudDNSApiLiveTest;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
* @author Everett Toews
*/
@Test(groups = "live", singleThreaded = true, testName = "DomainApiLiveTest")
public class DomainApiLiveTest extends BaseCloudDNSApiLiveTest {
// just in case the username has a '.' we replace it to avoid creating subdomains
private static final String JCLOUDS_EXAMPLE = System.getProperty("user.name").replace('.', '-') + "-domaintest-jclouds.org";
private Map<String, Domain> testDomains;
@Test
public void testCreateDomainsWithSubdomainsAndRecords() throws Exception {
Record createMXRecord = Record.builder()
.type("MX")
.name(JCLOUDS_EXAMPLE)
.data("mail." + JCLOUDS_EXAMPLE)
.priority(11235)
.comment("MX Record")
.ttl(60000)
.build();
Record createARecord = Record.builder()
.type("A")
.name(JCLOUDS_EXAMPLE)
.data("10.0.0.1")
.comment("A Record")
.ttl(60000)
.build();
List<Record> createRecords = ImmutableList.of(createMXRecord, createARecord);
CreateSubdomain createSubdomain1 = CreateSubdomain.builder()
.name("dev." + JCLOUDS_EXAMPLE)
.email("jclouds@" + JCLOUDS_EXAMPLE)
.comment("Hello dev subdomain")
.build();
CreateSubdomain createSubdomain2 = CreateSubdomain.builder()
.name("test." + JCLOUDS_EXAMPLE)
.email("jclouds@" + JCLOUDS_EXAMPLE)
.comment("Hello test subdomain")
.build();
List<CreateSubdomain> createSubdomains = ImmutableList.of(createSubdomain1, createSubdomain2);
CreateDomain createDomain1 = CreateDomain.builder()
.name(JCLOUDS_EXAMPLE)
.email("jclouds1@" + JCLOUDS_EXAMPLE)
.ttl(600001)
.comment("Hello Domain 1")
.subdomains(createSubdomains)
.records(createRecords)
.build();
CreateDomain createDomain2 = CreateDomain.builder()
.name("alt-" + JCLOUDS_EXAMPLE)
.email("jclouds2@" + JCLOUDS_EXAMPLE)
.ttl(600002)
.comment("Hello Domain 2")
.build();
Iterable<CreateDomain> createDomains = ImmutableList.of(createDomain1, createDomain2);
testDomains = DomainFunctions.toDomainMap(awaitComplete(api, api.getDomainApi().create(createDomains)));
assertEquals(testDomains.size(), 2);
Domain jclouds = testDomains.get(JCLOUDS_EXAMPLE);
Domain altjclouds = testDomains.get("alt-" + JCLOUDS_EXAMPLE);
Thread.sleep(1000);
Date now = new Date();
assertTrue(jclouds.getId() > 0);
assertTrue(jclouds.getAccountId() > 0);
assertEquals(jclouds.getName(), JCLOUDS_EXAMPLE);
assertEquals(jclouds.getEmail(), "jclouds1@" + JCLOUDS_EXAMPLE);
assertEquals(jclouds.getComment().get(), "Hello Domain 1");
assertEquals(jclouds.getTTL(), 600001);
assertTrue(jclouds.getCreated().before(now));
assertTrue(jclouds.getUpdated().before(now));
assertEquals(jclouds.getSubdomains().size(), 2);
Subdomain devjclouds = null;
Subdomain testjclouds = null;
for (Subdomain subdomain: jclouds.getSubdomains()) {
if (subdomain.getName().equals("dev." + JCLOUDS_EXAMPLE)) {
devjclouds = subdomain;
} else if (subdomain.getName().equals("test." + JCLOUDS_EXAMPLE)) {
testjclouds = subdomain;
}
}
assertTrue(devjclouds.getId() > 0);
assertEquals(devjclouds.getName(), "dev." + JCLOUDS_EXAMPLE);
assertEquals(devjclouds.getEmail(), "jclouds@" + JCLOUDS_EXAMPLE);
assertEquals(devjclouds.getComment().get(), "Hello dev subdomain");
assertTrue(devjclouds.getCreated().before(now));
assertTrue(devjclouds.getUpdated().before(now));
assertTrue(testjclouds.getId() > 0);
assertEquals(testjclouds.getName(), "test." + JCLOUDS_EXAMPLE);
assertEquals(testjclouds.getEmail(), "jclouds@" + JCLOUDS_EXAMPLE);
assertEquals(testjclouds.getComment().get(), "Hello test subdomain");
assertTrue(testjclouds.getCreated().before(now));
assertTrue(testjclouds.getUpdated().before(now));
assertEquals(jclouds.getRecords().size(), 2);
RecordDetail mxRecord = null;
RecordDetail aRecord = null;
for (RecordDetail record: jclouds.getRecords()) {
if (record.getType().equals("MX")) {
mxRecord = record;
} else if (record.getType().equals("A")) {
aRecord = record;
}
}
assertNotNull(mxRecord.getId());
assertEquals(mxRecord.getType(), "MX");
assertEquals(mxRecord.getName(), JCLOUDS_EXAMPLE);
assertEquals(mxRecord.getPriority().intValue(), 11235);
assertEquals(mxRecord.getComment(), "MX Record");
assertEquals(mxRecord.getTTL(), 60000);
assertTrue(mxRecord.getCreated().before(now));
assertTrue(mxRecord.getUpdated().before(now));
assertNotNull(aRecord.getId());
assertEquals(aRecord.getType(), "A");
assertEquals(aRecord.getName(), JCLOUDS_EXAMPLE);
assertNull(aRecord.getPriority());
assertEquals(aRecord.getComment(), "A Record");
assertEquals(aRecord.getTTL(), 60000);
assertTrue(aRecord.getCreated().before(now));
assertTrue(aRecord.getUpdated().before(now));
assertTrue(altjclouds.getId() > 0);
assertTrue(altjclouds.getAccountId() > 0);
assertEquals(altjclouds.getName(), "alt-" + JCLOUDS_EXAMPLE);
assertEquals(altjclouds.getEmail(), "jclouds2@" + JCLOUDS_EXAMPLE);
assertEquals(altjclouds.getComment().get(), "Hello Domain 2");
assertEquals(altjclouds.getTTL(), 600002);
assertTrue(altjclouds.getCreated().before(now));
assertTrue(altjclouds.getUpdated().before(now));
}
@Test(dependsOnMethods = "testCreateDomainsWithSubdomainsAndRecords")
public void testCreateSimpleDomain() throws Exception {
CreateDomain createDomain = CreateDomain.builder()
.name("simple-" + JCLOUDS_EXAMPLE)
.email("simple-jclouds@" + JCLOUDS_EXAMPLE)
.build();
Iterable<CreateDomain> createDomains = ImmutableList.of(createDomain);
Domain domain = awaitComplete(api, api.getDomainApi().create(createDomains)).iterator().next();
assertEquals(domain.getName(), "simple-" + JCLOUDS_EXAMPLE);
assertEquals(domain.getEmail(), "simple-jclouds@" + JCLOUDS_EXAMPLE);
testDomains = Maps.newHashMap(testDomains);
testDomains.put(domain.getName(), domain);
}
@Test(dependsOnMethods = "testCreateSimpleDomain")
public void testListDomains() throws Exception {
Set<Domain> domains = api.getDomainApi().list().concat().toSet();
assertEquals(domains.size(), 5);
}
@Test(dependsOnMethods = "testListDomains")
public void testListDomainsWithFilter() throws Exception {
Set<Domain> domains = api.getDomainApi().listWithFilterByNamesMatching("alt-" + JCLOUDS_EXAMPLE).concat().toSet();
assertEquals(domains.size(), 1);
}
@Test(dependsOnMethods = "testListDomainsWithFilter")
public void testListSubdomains() throws Exception {
Domain domain = testDomains.get(JCLOUDS_EXAMPLE);
Set<Subdomain> subdomains = api.getDomainApi().listSubdomains(domain.getId()).concat().toSet();
assertEquals(subdomains.size(), 2);
}
@Test(dependsOnMethods = "testListSubdomains")
public void testGetDomain() throws Exception {
Domain domain = testDomains.get(JCLOUDS_EXAMPLE);
Domain jclouds = api.getDomainApi().get(domain.getId());
Thread.sleep(1000);
Date now = new Date();
assertTrue(jclouds.getId() > 0);
assertTrue(jclouds.getAccountId() > 0);
assertEquals(jclouds.getName(), JCLOUDS_EXAMPLE);
assertEquals(jclouds.getEmail(), "jclouds1@" + JCLOUDS_EXAMPLE);
assertEquals(jclouds.getComment().get(), "Hello Domain 1");
assertEquals(jclouds.getTTL(), 600001);
assertTrue(jclouds.getCreated().before(now));
assertTrue(jclouds.getUpdated().before(now));
assertEquals(jclouds.getSubdomains().size(), 2);
Subdomain devjclouds = null;
Subdomain testjclouds = null;
for (Subdomain subdomain: jclouds.getSubdomains()) {
if (subdomain.getName().equals("dev." + JCLOUDS_EXAMPLE)) {
devjclouds = subdomain;
} else if (subdomain.getName().equals("test." + JCLOUDS_EXAMPLE)) {
testjclouds = subdomain;
}
}
assertTrue(devjclouds.getId() > 0);
assertEquals(devjclouds.getName(), "dev." + JCLOUDS_EXAMPLE);
assertEquals(devjclouds.getEmail(), "jclouds@" + JCLOUDS_EXAMPLE);
assertEquals(devjclouds.getComment().get(), "Hello dev subdomain");
assertTrue(devjclouds.getCreated().before(now));
assertTrue(devjclouds.getUpdated().before(now));
assertTrue(testjclouds.getId() > 0);
assertEquals(testjclouds.getName(), "test." + JCLOUDS_EXAMPLE);
assertEquals(testjclouds.getEmail(), "jclouds@" + JCLOUDS_EXAMPLE);
assertEquals(testjclouds.getComment().get(), "Hello test subdomain");
assertTrue(testjclouds.getCreated().before(now));
assertTrue(testjclouds.getUpdated().before(now));
assertEquals(jclouds.getRecords().size(), 4); // 2 created above + 2 nameserver (NS) records
RecordDetail mxRecord = null;
RecordDetail aRecord = null;
RecordDetail nsRecord = null;
for (RecordDetail record: jclouds.getRecords()) {
if (record.getType().equals("MX")) {
mxRecord = record;
} else if (record.getType().equals("A")) {
aRecord = record;
} else if (record.getType().equals("NS")) {
nsRecord = record; // don't care which one we get
}
}
assertNotNull(mxRecord.getId());
assertEquals(mxRecord.getType(), "MX");
assertEquals(mxRecord.getName(), JCLOUDS_EXAMPLE);
assertEquals(mxRecord.getPriority().intValue(), 11235);
assertEquals(mxRecord.getComment(), "MX Record");
assertEquals(mxRecord.getTTL(), 60000);
assertTrue(mxRecord.getCreated().before(now));
assertTrue(mxRecord.getUpdated().before(now));
assertNotNull(aRecord.getId());
assertEquals(aRecord.getType(), "A");
assertEquals(aRecord.getName(), JCLOUDS_EXAMPLE);
assertNull(aRecord.getPriority());
assertEquals(aRecord.getComment(), "A Record");
assertEquals(aRecord.getTTL(), 60000);
assertTrue(aRecord.getCreated().before(now));
assertTrue(aRecord.getUpdated().before(now));
assertNotNull(nsRecord.getId());
assertEquals(nsRecord.getType(), "NS");
assertEquals(nsRecord.getName(), JCLOUDS_EXAMPLE);
assertEquals(nsRecord.getTTL(), 600001);
assertTrue(nsRecord.getCreated().before(now));
assertTrue(nsRecord.getUpdated().before(now));
}
@Test(dependsOnMethods = "testGetDomain")
public void testUpdateDomain() throws Exception {
UpdateDomain updateDomain = UpdateDomain.builder()
.email("jclouds3@" + JCLOUDS_EXAMPLE)
.ttl(600003)
.comment("Hello Domain Update 3")
.build();
awaitComplete(api, api.getDomainApi().update(testDomains.get(JCLOUDS_EXAMPLE).getId(), updateDomain));
Domain jclouds = api.getDomainApi().get(testDomains.get(JCLOUDS_EXAMPLE).getId());
assertEquals(jclouds.getEmail(), "jclouds3@" + JCLOUDS_EXAMPLE);
assertEquals(jclouds.getComment().get(), "Hello Domain Update 3");
assertEquals(jclouds.getTTL(), 600003);
}
@Test(dependsOnMethods = "testUpdateDomain")
public void testUpdateDomainsTTL() throws Exception {
List<Integer> ids = ImmutableList.of(
testDomains.get(JCLOUDS_EXAMPLE).getId(), testDomains.get("alt-" + JCLOUDS_EXAMPLE).getId());
awaitComplete(api, api.getDomainApi().updateTTL(ids, 1234567));
Domain jclouds = api.getDomainApi().get(testDomains.get(JCLOUDS_EXAMPLE).getId());
Domain altjclouds = api.getDomainApi().get(testDomains.get("alt-" + JCLOUDS_EXAMPLE).getId());
assertEquals(jclouds.getTTL(), 1234567);
assertEquals(altjclouds.getTTL(), 1234567);
}
@Test(dependsOnMethods = "testUpdateDomainsTTL")
public void testUpdateDomainsEmail() throws Exception {
List<Integer> ids = ImmutableList.of(
testDomains.get(JCLOUDS_EXAMPLE).getId(), testDomains.get("alt-" + JCLOUDS_EXAMPLE).getId());
awaitComplete(api, api.getDomainApi().updateEmail(ids, "jclouds-up@" + JCLOUDS_EXAMPLE));
Domain jclouds = api.getDomainApi().get(testDomains.get(JCLOUDS_EXAMPLE).getId());
Domain altjclouds = api.getDomainApi().get(testDomains.get("alt-" + JCLOUDS_EXAMPLE).getId());
assertEquals(jclouds.getEmail(), "jclouds-up@" + JCLOUDS_EXAMPLE);
assertEquals(altjclouds.getEmail(), "jclouds-up@" + JCLOUDS_EXAMPLE);
}
@Test(dependsOnMethods = "testUpdateDomainsEmail")
public void testExportDomain() throws Exception {
Domain domain = testDomains.get(JCLOUDS_EXAMPLE);
List<String> domainExport = awaitComplete(api, api.getDomainApi().exportFormat(domain.getId(), Domain.Format.BIND_9));
assertTrue(domainExport.get(0).contains(JCLOUDS_EXAMPLE));
}
@Test(dependsOnMethods = "testExportDomain")
public void testImportDomain() throws Exception {
List<String> contents = ImmutableList.<String> of(
"imp-" + JCLOUDS_EXAMPLE + ". 3600 IN SOA ns.rackspace.com. jclouds.imp-" + JCLOUDS_EXAMPLE + ". 1363882703 3600 3600 3600 3600",
"imp-" + JCLOUDS_EXAMPLE + ". 600 IN A 50.56.174.152");
Domain domain = awaitComplete(api, api.getDomainApi().importFormat(contents, Domain.Format.BIND_9));
RecordDetail record = domain.getRecords().iterator().next();
assertEquals(domain.getName(), "imp-" + JCLOUDS_EXAMPLE);
assertEquals(domain.getEmail(), "jclouds@imp-" + JCLOUDS_EXAMPLE);
assertEquals(record.getType(), "A");
assertEquals(record.getData(), "50.56.174.152");
assertEquals(record.getTTL(), 600);
testDomains = Maps.newHashMap(testDomains);
testDomains.put(domain.getName(), domain);
}
@Override
@AfterClass(groups = { "integration", "live" })
protected void tearDown() {
List<Integer> domainIds = Lists.newArrayList();
for (Domain domain: testDomains.values()) {
domainIds.add(domain.getId());
}
try {
awaitComplete(api, api.getDomainApi().delete(domainIds, true));
}
catch (TimeoutException e) {
e.printStackTrace();
}
super.tearDown();
}
}

View File

@ -0,0 +1,84 @@
/**
* 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.rackspace.clouddns.v1.features;
import static javax.ws.rs.core.Response.Status.OK;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import org.jclouds.http.HttpResponse;
import org.jclouds.openstack.v2_0.domain.Limits;
import org.jclouds.openstack.v2_0.domain.RateLimit;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
import org.jclouds.rackspace.clouddns.v1.internal.BaseCloudDNSApiExpectTest;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
/**
* @author Everett Toews
*/
@Test(groups = "unit")
public class LimitApiExpectTest extends BaseCloudDNSApiExpectTest<CloudDNSApi> {
public void testListLimits() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/limits");
LimitApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/limit-list.json")).build()
).getLimitApi();
Limits limits = api.list();
assertEquals(limits.getAbsoluteLimits().get("records per domain"), Integer.valueOf(500));
assertEquals(limits.getAbsoluteLimits().get("domains"), Integer.valueOf(500));
assertEquals(Iterables.size(limits.getRateLimits()), 2);
RateLimit statusRateLimit = Iterables.tryFind(limits.getRateLimits(), isStatusRateLimit()).orNull();
assertEquals(statusRateLimit.getRegex(), ".*/v\\d+\\.\\d+/(\\d+/status).*");
assertEquals(Iterables.get(statusRateLimit.getLimits(), 0).getVerb(), "GET");
assertEquals(Iterables.get(statusRateLimit.getLimits(), 0).getValue(), 5);
assertEquals(Iterables.get(statusRateLimit.getLimits(), 0).getRemaining().get(), Integer.valueOf(5));
assertEquals(Iterables.get(statusRateLimit.getLimits(), 0).getUnit(), "SECOND");
}
public void testListLimitTypes() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/limits/types");
LimitApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/limit-types-list.json")).build()
).getLimitApi();
Iterable<String> limitTypes = api.listTypes();
assertEquals(Iterables.size(limitTypes), 3);
}
private static Predicate<RateLimit> isStatusRateLimit() {
return new Predicate<RateLimit>() {
@Override
public boolean apply(RateLimit rateLimit) {
return rateLimit.getUri().contains("status");
}
};
}
}

View File

@ -0,0 +1,50 @@
/**
* 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.rackspace.clouddns.v1.features;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import org.jclouds.openstack.v2_0.domain.Limits;
import org.jclouds.rackspace.clouddns.v1.internal.BaseCloudDNSApiLiveTest;
import org.testng.annotations.Test;
import com.google.common.collect.Iterables;
/**
* @author Everett Toews
*/
@Test(groups = "live", singleThreaded = true, testName = "LimitApiLiveTest")
public class LimitApiLiveTest extends BaseCloudDNSApiLiveTest {
@Test
public void testList() throws Exception {
Limits limits = api.getLimitApi().list();
assertNotNull(limits.getAbsoluteLimits());
assertNotNull(limits.getRateLimits());
assertTrue(limits.getAbsoluteLimits().size() > 1);
assertTrue(Iterables.size(limits.getRateLimits()) > 1);
}
@Test
public void testListTypes() throws Exception {
Iterable<String> limitTypes = api.getLimitApi().listTypes();
assertNotNull(limitTypes);
assertTrue(Iterables.size(limitTypes) > 1);
}
}

View File

@ -0,0 +1,328 @@
/**
* 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.rackspace.clouddns.v1.features;
import static javax.ws.rs.HttpMethod.POST;
import static javax.ws.rs.HttpMethod.PUT;
import static javax.ws.rs.core.Response.Status.OK;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.net.URI;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.core.MediaType;
import org.jclouds.http.HttpResponse;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
import org.jclouds.rackspace.clouddns.v1.domain.Job;
import org.jclouds.rackspace.clouddns.v1.domain.Record;
import org.jclouds.rackspace.clouddns.v1.domain.RecordDetail;
import org.jclouds.rackspace.clouddns.v1.internal.BaseCloudDNSApiExpectTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
/**
* @author Everett Toews
*/
@Test(groups = "unit")
public class RecordApiExpectTest extends BaseCloudDNSApiExpectTest<CloudDNSApi> {
private static final String JCLOUDS_EXAMPLE = "jclouds-example.com";
public void testAddRecord() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/3650908/records");
RecordApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET()
.method(POST)
.payload(payloadFromResource("/record-create.json"))
.endpoint(endpoint)
.build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/record-create-response.json")).build())
.getRecordApiForDomain(3650908);
Record createMXRecord = Record.builder()
.type("MX")
.name(JCLOUDS_EXAMPLE)
.data("mail." + JCLOUDS_EXAMPLE)
.comment("MX Record")
.priority(11235)
.build();
Record createARecord = Record.builder()
.type("A")
.name(JCLOUDS_EXAMPLE)
.data("10.0.0.1")
.build();
List<Record> createRecords = ImmutableList.of(createMXRecord, createARecord);
Job<Set<RecordDetail>> job = api.create(createRecords);
assertEquals(job.getStatus(), Job.Status.COMPLETED);
assertTrue(job.getResource().isPresent());
Set<RecordDetail> records = job.getResource().get();
Date now = new Date();
RecordDetail mxRecord = null;
RecordDetail aRecord = null;
for (RecordDetail record: records) {
if (record.getType().equals("MX")) {
mxRecord = record;
} else if (record.getType().equals("A")) {
aRecord = record;
}
}
assertNotNull(mxRecord.getId());
assertEquals(mxRecord.getType(), "MX");
assertEquals(mxRecord.getName(), JCLOUDS_EXAMPLE);
assertEquals(mxRecord.getPriority().intValue(), 11235);
assertEquals(mxRecord.getComment(), "MX Record");
assertEquals(mxRecord.getTTL(), 60000);
assertTrue(mxRecord.getCreated().before(now));
assertTrue(mxRecord.getUpdated().before(now));
assertNotNull(aRecord.getId());
assertEquals(aRecord.getType(), "A");
assertEquals(aRecord.getName(), JCLOUDS_EXAMPLE);
assertNull(aRecord.getPriority());
assertEquals(aRecord.getTTL(), 60000);
assertTrue(aRecord.getCreated().before(now));
assertTrue(aRecord.getUpdated().before(now));
}
public void testListRecords() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/3650908/records");
RecordApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/record-list.json")).build())
.getRecordApiForDomain(3650908);
ImmutableList<RecordDetail> records = api.list().concat().toList();
assertEquals(records.size(), 4); // 2 created above + 2 nameserver (NS) records
for (RecordDetail record: records) {
assertTrue(record.getName().contains(JCLOUDS_EXAMPLE));
}
}
public void testListByType() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/3650908/records?type=A");
RecordApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/record-list-with-filter.json")).build())
.getRecordApiForDomain(3650908);
ImmutableList<RecordDetail> records = api.listByType("A").concat().toList();
Date now = new Date();
assertEquals(records.size(), 1);
assertEquals(records.get(0).getId(), "A-9846146");
assertEquals(records.get(0).getName(), JCLOUDS_EXAMPLE);
assertEquals(records.get(0).getType(), "A");
assertEquals(records.get(0).getData(), "10.0.1.0");
assertEquals(records.get(0).getTTL(), 60000);
assertTrue(records.get(0).getCreated().before(now));
assertTrue(records.get(0).getUpdated().before(now));
}
public void testListByTypeAndData() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/3650908/records?type=A&data=10.0.1.0");
RecordApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/record-list-with-filter.json")).build())
.getRecordApiForDomain(3650908);
ImmutableList<RecordDetail> records = api.listByTypeAndData("A", "10.0.1.0").concat().toList();
Date now = new Date();
assertEquals(records.size(), 1);
assertEquals(records.get(0).getId(), "A-9846146");
assertEquals(records.get(0).getName(), JCLOUDS_EXAMPLE);
assertEquals(records.get(0).getType(), "A");
assertEquals(records.get(0).getData(), "10.0.1.0");
assertEquals(records.get(0).getTTL(), 60000);
assertTrue(records.get(0).getCreated().before(now));
assertTrue(records.get(0).getUpdated().before(now));
}
public void testListByNameAndType() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/3650908/records?name=jclouds-example.com&type=A");
RecordApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/record-list-with-filter.json")).build())
.getRecordApiForDomain(3650908);
ImmutableList<RecordDetail> records = api.listByNameAndType(JCLOUDS_EXAMPLE, "A").concat().toList();
Date now = new Date();
assertEquals(records.size(), 1);
assertEquals(records.get(0).getId(), "A-9846146");
assertEquals(records.get(0).getName(), JCLOUDS_EXAMPLE);
assertEquals(records.get(0).getType(), "A");
assertEquals(records.get(0).getData(), "10.0.1.0");
assertEquals(records.get(0).getTTL(), 60000);
assertTrue(records.get(0).getCreated().before(now));
assertTrue(records.get(0).getUpdated().before(now));
}
public void testGetByNameAndTypeAndData() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/3650908/records?name=jclouds-example.com&type=A&data=10.0.1.0");
RecordApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/record-list-with-filter.json")).build())
.getRecordApiForDomain(3650908);
RecordDetail record = api.getByNameAndTypeAndData(JCLOUDS_EXAMPLE, "A", "10.0.1.0");
Date now = new Date();
assertEquals(record.getId(), "A-9846146");
assertEquals(record.getName(), JCLOUDS_EXAMPLE);
assertEquals(record.getType(), "A");
assertEquals(record.getData(), "10.0.1.0");
assertEquals(record.getTTL(), 60000);
assertTrue(record.getCreated().before(now));
assertTrue(record.getUpdated().before(now));
}
public void testGetRecord() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/3650908/records/A-9846146");
RecordApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/record-get.json")).build())
.getRecordApiForDomain(3650908);
RecordDetail record = api.get("A-9846146");
Date now = new Date();
assertEquals(record.getId(), "A-9846146");
assertEquals(record.getName(), JCLOUDS_EXAMPLE);
assertEquals(record.getType(), "A");
assertEquals(record.getData(), "10.0.1.0");
assertEquals(record.getTTL(), 60000);
assertTrue(record.getCreated().before(now));
assertTrue(record.getUpdated().before(now));
}
public void testUpdateRecord() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/3650908/records/SRV-21858");
RecordApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET()
.method(PUT)
.payload(payloadFromResourceWithContentType("/record-update.json", MediaType.APPLICATION_JSON))
.endpoint(endpoint)
.build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/record-update-response.json")).build())
.getRecordApiForDomain(3650908);
Record record = Record.builder()
.name("_sip._udp." + JCLOUDS_EXAMPLE)
.ttl(86401)
.data("1 3444 sip." + JCLOUDS_EXAMPLE) // weight port target
.priority(12358)
.comment("Updated Protocol to UDP")
.build();
Job<Void> job = api.update("SRV-21858", record);
assertEquals(job.getStatus(), Job.Status.COMPLETED);
}
public void testUpdateRecords() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/3650908/records");
RecordApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET()
.method(PUT)
.payload(payloadFromResourceWithContentType("/records-update.json", MediaType.APPLICATION_JSON))
.endpoint(endpoint)
.build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/records-update-response.json")).build())
.getRecordApiForDomain(3650908);
Record updateARecord = Record.builder()
.comment("Multi-record Update")
.build();
Record updateMXRecord = Record.builder()
.comment("Multi-record Update")
.build();
Map<String, Record> updateRecords = ImmutableMap.<String, Record> of(
"A-9846146", updateARecord,
"MX-9846146", updateMXRecord);
Job<?> job = api.update(updateRecords);
assertEquals(job.getStatus(), Job.Status.COMPLETED);
}
public void testDeleteRecord() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/3650908/records/A-9846146");
RecordApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().method("DELETE").replaceHeader("Accept", MediaType.WILDCARD).endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/record-delete.json")).build())
.getRecordApiForDomain(3650908);
Job<?> job = api.delete("A-9846146");
assertEquals(job.getStatus(), Job.Status.COMPLETED);
}
public void testDeleteRecords() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/domains/3650908/records?id=A-9846146&id=MX-9846146");
RecordApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().method("DELETE").replaceHeader("Accept", MediaType.WILDCARD).endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/records-delete.json")).build())
.getRecordApiForDomain(3650908);
List<String> recordIds = ImmutableList.<String> of("A-9846146", "MX-9846146");
Job<?> job = api.delete(recordIds);
assertEquals(job.getStatus(), Job.Status.COMPLETED);
}
}

View File

@ -0,0 +1,293 @@
/**
* 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.rackspace.clouddns.v1.features;
import static org.jclouds.rackspace.clouddns.v1.predicates.JobPredicates.awaitComplete;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeoutException;
import org.jclouds.rackspace.clouddns.v1.domain.CreateDomain;
import org.jclouds.rackspace.clouddns.v1.domain.Domain;
import org.jclouds.rackspace.clouddns.v1.domain.Record;
import org.jclouds.rackspace.clouddns.v1.domain.RecordDetail;
import org.jclouds.rackspace.clouddns.v1.functions.RecordFunctions;
import org.jclouds.rackspace.clouddns.v1.internal.BaseCloudDNSApiLiveTest;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
/**
* @author Everett Toews
*/
@Test(groups = "live", singleThreaded = true, testName = "RecordApiLiveTest")
public class RecordApiLiveTest extends BaseCloudDNSApiLiveTest {
// just in case the username has a '.' we replace it to avoid creating subdomains
private static final String JCLOUDS_EXAMPLE = System.getProperty("user.name").replace('.', '-') + "-recordtest-jclouds.org";
private int domainId;
private String aRecordId;
private String srvRecordId;
private String mxRecordId;
@Test
public void testCreateDomain() throws Exception {
CreateDomain createDomain = CreateDomain.builder()
.name(JCLOUDS_EXAMPLE)
.email("jclouds@" + JCLOUDS_EXAMPLE)
.ttl(60000)
.build();
Iterable<CreateDomain> createDomains = ImmutableList.of(createDomain);
Domain domain = awaitComplete(api, api.getDomainApi().create(createDomains)).iterator().next();
assertEquals(domain.getName(), JCLOUDS_EXAMPLE);
assertEquals(domain.getEmail(), "jclouds@" + JCLOUDS_EXAMPLE);
assertTrue(domain.getRecords().isEmpty());
domainId = domain.getId();
}
@Test(dependsOnMethods = "testCreateDomain")
public void testCreateRecords() throws Exception {
Record createMXRecord = Record.builder()
.type("MX")
.name(JCLOUDS_EXAMPLE)
.data("mail." + JCLOUDS_EXAMPLE)
.comment("MX Record")
.priority(11235)
.build();
Record createARecord = Record.builder()
.type("A")
.name(JCLOUDS_EXAMPLE)
.data("10.0.0.1")
.build();
Record createSRVRecord = Record.builder()
.type("SRV")
.name("_sip._tcp." + JCLOUDS_EXAMPLE)
.ttl(86400)
.data("1 3443 sip." + JCLOUDS_EXAMPLE) // weight port target
.priority(11235)
.comment("Updated Protocol to UDP")
.build();
List<Record> createRecords = ImmutableList.of(createMXRecord, createARecord, createSRVRecord);
Set<RecordDetail> records = awaitComplete(api, api.getRecordApiForDomain(domainId).create(createRecords));
Thread.sleep(1000);
Date now = new Date();
RecordDetail mxRecord = null;
RecordDetail aRecord = null;
RecordDetail srvRecord = null;
for (RecordDetail record: records) {
if (record.getType().equals("MX")) {
mxRecord = record;
} else if (record.getType().equals("A")) {
aRecord = record;
} else if (record.getType().equals("SRV")) {
srvRecord = record;
}
}
assertNotNull(mxRecord.getId());
assertEquals(mxRecord.getType(), "MX");
assertEquals(mxRecord.getName(), JCLOUDS_EXAMPLE);
assertEquals(mxRecord.getPriority().intValue(), 11235);
assertEquals(mxRecord.getComment(), "MX Record");
assertEquals(mxRecord.getTTL(), 60000);
assertTrue(mxRecord.getCreated().before(now));
assertTrue(mxRecord.getUpdated().before(now));
assertNotNull(aRecord.getId());
assertEquals(aRecord.getType(), "A");
assertEquals(aRecord.getName(), JCLOUDS_EXAMPLE);
assertEquals(aRecord.getData(), "10.0.0.1");
assertNull(aRecord.getPriority());
assertEquals(aRecord.getTTL(), 60000);
assertTrue(aRecord.getCreated().before(now));
assertTrue(aRecord.getUpdated().before(now));
assertNotNull(srvRecord.getId());
assertEquals(srvRecord.getType(), "SRV");
assertEquals(srvRecord.getName(), "_sip._tcp." + JCLOUDS_EXAMPLE);
assertEquals(srvRecord.getData(), "1 3443 sip." + JCLOUDS_EXAMPLE);
assertEquals(srvRecord.getPriority().intValue(), 11235);
assertEquals(srvRecord.getTTL(), 86400);
assertTrue(srvRecord.getCreated().before(now));
assertTrue(srvRecord.getUpdated().before(now));
}
@Test(dependsOnMethods = "testCreateRecords")
public void testListRecords() throws Exception {
Set<RecordDetail> records = api.getRecordApiForDomain(domainId).list().concat().toSet();
assertEquals(records.size(), 5); // 3 created above + 2 nameserver (NS) records
}
@Test(dependsOnMethods = "testListRecords")
public void testListRecordsByCriteriaMethods() throws Exception {
List<RecordDetail> records = api.getRecordApiForDomain(domainId).listByType("SRV").concat().toList();
assertEquals(records.size(), 1);
srvRecordId = records.get(0).getId();
records = api.getRecordApiForDomain(domainId).listByTypeAndData("A", "10.0.0.1").concat().toList();
assertEquals(records.size(), 1);
aRecordId = records.get(0).getId();
records = api.getRecordApiForDomain(domainId).listByNameAndType(JCLOUDS_EXAMPLE, "MX").concat().toList();
assertEquals(records.size(), 1);
mxRecordId = records.get(0).getId();
}
@Test(dependsOnMethods = "testListRecordsByCriteriaMethods")
public void testGetRecordByNameAndTypeAndData() throws Exception {
RecordDetail record = api.getRecordApiForDomain(domainId).getByNameAndTypeAndData(JCLOUDS_EXAMPLE, "A", "10.0.0.1");
Date now = new Date();
assertNotNull(record.getId());
assertEquals(record.getName(), JCLOUDS_EXAMPLE);
assertEquals(record.getType(), "A");
assertEquals(record.getData(), "10.0.0.1");
assertEquals(record.getTTL(), 60000);
assertTrue(record.getCreated().before(now));
assertTrue(record.getUpdated().before(now));
}
@Test(dependsOnMethods = "testGetRecordByNameAndTypeAndData")
public void testGetRecord() throws Exception {
RecordDetail record = api.getRecordApiForDomain(domainId).get(aRecordId);
Date now = new Date();
assertNotNull(record.getId());
assertEquals(record.getName(), JCLOUDS_EXAMPLE);
assertEquals(record.getType(), "A");
assertEquals(record.getData(), "10.0.0.1");
assertEquals(record.getTTL(), 60000);
assertTrue(record.getCreated().before(now));
assertTrue(record.getUpdated().before(now));
}
@Test(dependsOnMethods = "testGetRecord")
public void testUpdateRecord() throws Exception {
Record record = Record.builder()
.name("_sip._udp." + JCLOUDS_EXAMPLE)
.ttl(86401)
.data("1 3444 sip." + JCLOUDS_EXAMPLE) // weight port target
.priority(12358)
.comment("Updated Protocol to UDP")
.build();
awaitComplete(api, api.getRecordApiForDomain(domainId).update(srvRecordId, record));
RecordDetail srvRecord = api.getRecordApiForDomain(domainId).get(srvRecordId);
Date now = new Date();
assertNotNull(srvRecord.getId());
assertEquals(srvRecord.getType(), "SRV");
assertEquals(srvRecord.getName(), "_sip._udp." + JCLOUDS_EXAMPLE);
assertEquals(srvRecord.getData(), "1 3444 sip." + JCLOUDS_EXAMPLE);
assertEquals(srvRecord.getPriority().intValue(), 12358);
assertEquals(srvRecord.getTTL(), 86401);
assertEquals(srvRecord.getComment(), "Updated Protocol to UDP");
assertTrue(srvRecord.getCreated().before(now));
assertTrue(srvRecord.getUpdated().before(now));
}
@Test(dependsOnMethods = "testUpdateRecord")
public void testUpdateRecords() throws Exception {
Set<RecordDetail> recordDetails = api.getRecordApiForDomain(domainId).list().concat().toSet();
Map<String, Record> idsToRecords = RecordFunctions.toRecordMap(recordDetails);
Map<String, Record> updateRecords = Maps.transformValues(idsToRecords, updateTTLAndComment(35813, "New TTL"));
awaitComplete(api, api.getRecordApiForDomain(domainId).update(updateRecords));
RecordDetail record = api.getRecordApiForDomain(domainId).get(aRecordId);
Date now = new Date();
assertNotNull(record.getId());
assertEquals(record.getName(), JCLOUDS_EXAMPLE);
assertEquals(record.getType(), "A");
assertEquals(record.getData(), "10.0.0.1");
assertEquals(record.getTTL(), 35813);
assertEquals(record.getComment(), "New TTL");
assertTrue(record.getCreated().before(now));
assertTrue(record.getUpdated().before(now));
recordDetails = api.getRecordApiForDomain(domainId).list().concat().toSet();
for (RecordDetail recordDetail: recordDetails) {
assertEquals(recordDetail.getTTL(), 35813);
assertEquals(recordDetail.getComment(), "New TTL");
}
}
private Function<Record, Record> updateTTLAndComment(final int ttl, final String comment) {
return new Function<Record, Record>() {
public Record apply(Record record) {
return record.toBuilder().ttl(ttl).comment(comment).build();
}
};
}
@Test(dependsOnMethods = "testUpdateRecords")
public void testDeleteRecord() throws Exception {
awaitComplete(api, api.getRecordApiForDomain(domainId).delete(aRecordId));
assertNull(api.getRecordApiForDomain(domainId).get(aRecordId));
}
@Test(dependsOnMethods = "testDeleteRecord")
public void testDeleteRecords() throws Exception {
List<String> recordIds = ImmutableList.<String> of(srvRecordId, mxRecordId);
awaitComplete(api, api.getRecordApiForDomain(domainId).delete(recordIds));
assertNull(api.getRecordApiForDomain(domainId).get(srvRecordId));
assertNull(api.getRecordApiForDomain(domainId).get(mxRecordId));
}
@Override
@AfterClass(groups = { "integration", "live" })
protected void tearDown() {
try {
awaitComplete(api, api.getDomainApi().delete(ImmutableList.<Integer> of(domainId), true));
}
catch (TimeoutException e) {
e.printStackTrace();
}
super.tearDown();
}
}

View File

@ -0,0 +1,221 @@
/**
* 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.rackspace.clouddns.v1.features;
import static javax.ws.rs.HttpMethod.DELETE;
import static javax.ws.rs.HttpMethod.POST;
import static javax.ws.rs.HttpMethod.PUT;
import static javax.ws.rs.core.Response.Status.OK;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.net.URI;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import org.jclouds.http.HttpResponse;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
import org.jclouds.rackspace.clouddns.v1.domain.Job;
import org.jclouds.rackspace.clouddns.v1.domain.Record;
import org.jclouds.rackspace.clouddns.v1.domain.RecordDetail;
import org.jclouds.rackspace.clouddns.v1.internal.BaseCloudDNSApiExpectTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
/**
* @author Everett Toews
*/
@Test(groups = "unit")
public class ReverseDNSApiExpectTest extends BaseCloudDNSApiExpectTest<CloudDNSApi> {
public static final String CLOUD_SERVERS_OPEN_STACK = "cloudServersOpenStack";
private static final String JCLOUDS_EXAMPLE = "jclouds-example.com";
private static final URI SERVER_URI = URI.create("https://dfw.servers.api.rackspacecloud.com/v2/123123/servers/f5fb9334-b4f0-49d0-a2cc-57a5772dc7d1");
public void testCreateReverseDNSRecord() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/rdns");
ReverseDNSApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET()
.method(POST)
.payload(payloadFromResource("/record-ptr-create.json"))
.endpoint(endpoint)
.build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/record-ptr-create-response.json")).build())
.getReverseDNSApiForService(CLOUD_SERVERS_OPEN_STACK);
Record createPTRRecordIPv4 = Record.builder()
.type("PTR")
.name(JCLOUDS_EXAMPLE)
.data("166.78.146.80")
.ttl(11235)
.build();
Record createPTRRecordIPv6 = Record.builder()
.type("PTR")
.name(JCLOUDS_EXAMPLE)
.data("2001:4800:7812:0514:9a32:3c2a:ff04:aed2")
.comment("Hello IPv6")
.build();
List<Record> createRecords = ImmutableList.of(createPTRRecordIPv4, createPTRRecordIPv6);
Job<Set<RecordDetail>> job = api.create(SERVER_URI, createRecords);
assertEquals(job.getStatus(), Job.Status.COMPLETED);
assertTrue(job.getResource().isPresent());
Set<RecordDetail> records = job.getResource().get();
Date now = new Date();
RecordDetail ptrRecordIPv4 = null;
RecordDetail ptrRecordIPv6 = null;
for (RecordDetail record: records) {
if (record.getData().startsWith("166")) {
ptrRecordIPv4 = record;
} else if (record.getData().startsWith("2001")) {
ptrRecordIPv6 = record;
}
}
assertNotNull(ptrRecordIPv4.getId());
assertEquals(ptrRecordIPv4.getType(), "PTR");
assertEquals(ptrRecordIPv4.getName(), JCLOUDS_EXAMPLE);
assertEquals(ptrRecordIPv4.getData(), "166.78.146.80");
assertEquals(ptrRecordIPv4.getTTL(), 11235);
assertNull(ptrRecordIPv4.getPriority());
assertNull(ptrRecordIPv4.getComment());
assertTrue(ptrRecordIPv4.getCreated().before(now));
assertTrue(ptrRecordIPv4.getUpdated().before(now));
assertNotNull(ptrRecordIPv6.getId());
assertEquals(ptrRecordIPv6.getType(), "PTR");
assertEquals(ptrRecordIPv6.getName(), JCLOUDS_EXAMPLE);
assertEquals(ptrRecordIPv6.getData(), "2001:4800:7812:514:9a32:3c2a:ff04:aed2"); // leading 0 in 0514 removed
assertTrue(ptrRecordIPv6.getTTL() > 0);
assertNull(ptrRecordIPv6.getPriority());
assertEquals(ptrRecordIPv6.getComment(), "Hello IPv6");
assertTrue(ptrRecordIPv6.getCreated().before(now));
assertTrue(ptrRecordIPv6.getUpdated().before(now));
}
public void testListReverseDNSRecords() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/rdns/cloudServersOpenStack?href=https%3A//dfw.servers.api.rackspacecloud.com/v2/123123/servers/f5fb9334-b4f0-49d0-a2cc-57a5772dc7d1");
ReverseDNSApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/record-ptr-list.json")).build())
.getReverseDNSApiForService(CLOUD_SERVERS_OPEN_STACK);
ImmutableList<RecordDetail> records = api.list(SERVER_URI).concat().toList();
assertEquals(records.size(), 2);
for (RecordDetail record: records) {
assertTrue(record.getType().contains("PTR"));
assertTrue(record.getName().contains(JCLOUDS_EXAMPLE));
}
}
public void testGetReverseDNSRecord() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/rdns/cloudServersOpenStack/PTR-557437?href=https%3A//dfw.servers.api.rackspacecloud.com/v2/123123/servers/f5fb9334-b4f0-49d0-a2cc-57a5772dc7d1");
ReverseDNSApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/record-ptr-get.json")).build())
.getReverseDNSApiForService(CLOUD_SERVERS_OPEN_STACK);
RecordDetail record = api.get(SERVER_URI, "PTR-557437");
Date now = new Date();
assertEquals(record.getId(), "PTR-557437");
assertEquals(record.getType(), "PTR");
assertEquals(record.getName(), JCLOUDS_EXAMPLE);
assertEquals(record.getData(), "166.78.146.80");
assertEquals(record.getTTL(), 11235);
assertNull(record.getPriority());
assertNull(record.getComment());
assertTrue(record.getCreated().before(now));
assertTrue(record.getUpdated().before(now));
}
public void testUpdateReverseDNSRecord() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/rdns");
ReverseDNSApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET()
.method(PUT)
.payload(payloadFromResourceWithContentType("/record-ptr-update.json", MediaType.APPLICATION_JSON))
.endpoint(endpoint)
.build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/record-ptr-update-response.json")).build())
.getReverseDNSApiForService(CLOUD_SERVERS_OPEN_STACK);
Record updatePTRRecordIPv4 = Record.builder()
.type("PTR")
.name(JCLOUDS_EXAMPLE)
.data("166.78.146.80")
.ttl(12358)
.build();
Map<String, Record> idsToRecords = ImmutableMap.<String, Record> of("PTR-557437", updatePTRRecordIPv4);
Job<Void> job = api.update(SERVER_URI, idsToRecords);
assertEquals(job.getStatus(), Job.Status.COMPLETED);
}
public void testDeleteReverseDNSRecord() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/rdns/cloudServersOpenStack?href=https%3A//dfw.servers.api.rackspacecloud.com/v2/123123/servers/f5fb9334-b4f0-49d0-a2cc-57a5772dc7d1&ip=166.78.146.80");
ReverseDNSApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().method(DELETE).replaceHeader(HttpHeaders.ACCEPT, MediaType.WILDCARD).endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/record-ptr-delete.json")).build())
.getReverseDNSApiForService(CLOUD_SERVERS_OPEN_STACK);
Job<Void> job = api.delete(SERVER_URI, "166.78.146.80");
assertEquals(job.getStatus(), Job.Status.COMPLETED);
}
public void testDeleteReverseDNSRecords() {
URI endpoint = URI.create("https://dns.api.rackspacecloud.com/v1.0/123123/rdns/cloudServersOpenStack?href=https%3A//dfw.servers.api.rackspacecloud.com/v2/123123/servers/f5fb9334-b4f0-49d0-a2cc-57a5772dc7d1");
ReverseDNSApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().method(DELETE).replaceHeader("Accept", MediaType.WILDCARD).endpoint(endpoint).build(),
HttpResponse.builder().statusCode(OK.getStatusCode()).payload(payloadFromResource("/records-ptr-delete.json")).build())
.getReverseDNSApiForService(CLOUD_SERVERS_OPEN_STACK);
Job<Void> job = api.deleteAll(SERVER_URI);
assertEquals(job.getStatus(), Job.Status.COMPLETED);
}
}

View File

@ -0,0 +1,227 @@
/**
* 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.rackspace.clouddns.v1.features;
import static org.jclouds.rackspace.clouddns.v1.features.ReverseDNSApiExpectTest.CLOUD_SERVERS_OPEN_STACK;
import static org.jclouds.rackspace.clouddns.v1.predicates.JobPredicates.awaitComplete;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.net.URI;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeoutException;
import org.jclouds.ContextBuilder;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.config.ComputeServiceProperties;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template;
import org.jclouds.openstack.nova.v2_0.NovaApi;
import org.jclouds.openstack.nova.v2_0.NovaAsyncApi;
import org.jclouds.openstack.nova.v2_0.domain.Server;
import org.jclouds.openstack.nova.v2_0.features.ServerApi;
import org.jclouds.rackspace.clouddns.v1.domain.CreateDomain;
import org.jclouds.rackspace.clouddns.v1.domain.Domain;
import org.jclouds.rackspace.clouddns.v1.domain.Record;
import org.jclouds.rackspace.clouddns.v1.domain.RecordDetail;
import org.jclouds.rackspace.clouddns.v1.internal.BaseCloudDNSApiLiveTest;
import org.jclouds.rest.RestContext;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
/**
* @author Everett Toews
*/
@Test(groups = "live", singleThreaded = true, testName = "ReverseDNSApiLiveTest")
public class ReverseDNSApiLiveTest extends BaseCloudDNSApiLiveTest {
// just in case the username has a '.' we replace it to avoid creating subdomains
private static final String JCLOUDS_EXAMPLE = System.getProperty("user.name").replace('.', '-')
+ "-recordtest-jclouds.org";
private ComputeService computeService;
private RestContext<NovaApi, NovaAsyncApi> nova;
private String serverId;
private URI serverURI;
private String serverIPv4;
private String serverIPv6;
private int domainId;
private String ptrRecordIPv4Id;
private String ptrRecordIPv6Id;
@Test
public void testCreateServer() throws Exception {
Properties overrides = new Properties();
overrides.setProperty(ComputeServiceProperties.POLL_INITIAL_PERIOD, "10000");
overrides.setProperty(ComputeServiceProperties.POLL_MAX_PERIOD, "10000");
ComputeServiceContext context = ContextBuilder.newBuilder("rackspace-cloudservers-us")
.credentials(identity, credential)
.overrides(overrides)
.buildView(ComputeServiceContext.class);
computeService = context.getComputeService();
nova = context.unwrap();
Template template = computeService.templateBuilder().smallest().build();
NodeMetadata nodeMetadata = computeService.createNodesInGroup("jclouds-reverse-dns-test", 1, template).iterator().next();
serverId = nodeMetadata.getId();
serverURI = nodeMetadata.getUri();
ServerApi serverApi = nova.getApi().getServerApiForZone(nodeMetadata.getLocation().getParent().getId());
Server server = serverApi.get(nodeMetadata.getProviderId());
serverIPv4 = server.getAccessIPv4();
serverIPv6 = server.getAccessIPv6();
System.out.println("serverURI = " + serverURI);
System.out.println("serverIPv4 = " + serverIPv4);
System.out.println("serverIPv6 = " + serverIPv6);
}
@Test(dependsOnMethods = "testCreateServer")
public void testCreateDomain() throws Exception {
CreateDomain createDomain = CreateDomain.builder().name(JCLOUDS_EXAMPLE).email("jclouds@" + JCLOUDS_EXAMPLE)
.ttl(60000).build();
Iterable<CreateDomain> createDomains = ImmutableList.of(createDomain);
Domain domain = awaitComplete(api, api.getDomainApi().create(createDomains)).iterator().next();
assertEquals(domain.getName(), JCLOUDS_EXAMPLE);
assertEquals(domain.getEmail(), "jclouds@" + JCLOUDS_EXAMPLE);
assertTrue(domain.getRecords().isEmpty());
domainId = domain.getId();
}
@Test(dependsOnMethods = "testCreateDomain")
public void testCreateReverseDNSRecords() throws Exception {
Record createPTRRecordIPv4 = Record.builder().type("PTR").name(JCLOUDS_EXAMPLE).data(serverIPv4).ttl(11235)
.build();
Record createPTRRecordIPv6 = Record.builder().type("PTR").name(JCLOUDS_EXAMPLE).data(serverIPv6)
.comment("Hello IPv6").build();
List<Record> createRecords = ImmutableList.of(createPTRRecordIPv4, createPTRRecordIPv6);
Set<RecordDetail> records = awaitComplete(api,
api.getReverseDNSApiForService(CLOUD_SERVERS_OPEN_STACK).create(serverURI, createRecords));
Date now = new Date();
RecordDetail ptrRecordIPv4 = null;
RecordDetail ptrRecordIPv6 = null;
for (RecordDetail record: records) {
if (record.getData().equals(serverIPv4)) {
ptrRecordIPv4 = record;
ptrRecordIPv4Id = record.getId();
}
else {
ptrRecordIPv6 = record;
ptrRecordIPv6Id = record.getId();
}
}
assertNotNull(ptrRecordIPv4.getId());
assertEquals(ptrRecordIPv4.getType(), "PTR");
assertEquals(ptrRecordIPv4.getName(), JCLOUDS_EXAMPLE);
assertEquals(ptrRecordIPv4.getData(), serverIPv4);
assertEquals(ptrRecordIPv4.getTTL(), 11235);
assertNull(ptrRecordIPv4.getPriority());
assertNull(ptrRecordIPv4.getComment());
assertTrue(ptrRecordIPv4.getCreated().before(now));
assertTrue(ptrRecordIPv4.getUpdated().before(now));
assertNotNull(ptrRecordIPv6.getId());
assertEquals(ptrRecordIPv6.getType(), "PTR");
assertEquals(ptrRecordIPv6.getName(), JCLOUDS_EXAMPLE);
// can't test equals for data as CDNS will remove leading 0s from IPv6 Addrs
assertNotNull(ptrRecordIPv6.getData());
assertTrue(ptrRecordIPv6.getTTL() > 0);
assertNull(ptrRecordIPv6.getPriority());
assertEquals(ptrRecordIPv6.getComment(), "Hello IPv6");
assertTrue(ptrRecordIPv6.getCreated().before(now));
assertTrue(ptrRecordIPv6.getUpdated().before(now));
}
@Test(dependsOnMethods = "testCreateReverseDNSRecords")
public void testListReverseDNSRecords() throws Exception {
Set<RecordDetail> records = api.getReverseDNSApiForService(CLOUD_SERVERS_OPEN_STACK).list(serverURI).concat()
.toSet();
assertEquals(records.size(), 2);
}
@Test(dependsOnMethods = "testListReverseDNSRecords")
public void testUpdateAndGetReverseDNSRecords() throws Exception {
Record updatePTRRecordIPv4 = Record.builder().type("PTR").name(JCLOUDS_EXAMPLE).data(serverIPv4).ttl(12358)
.build();
Map<String, Record> idsToRecords = ImmutableMap.<String, Record> of(ptrRecordIPv4Id, updatePTRRecordIPv4);
awaitComplete(api, api.getReverseDNSApiForService(CLOUD_SERVERS_OPEN_STACK).update(serverURI, idsToRecords));
RecordDetail record = api.getReverseDNSApiForService(CLOUD_SERVERS_OPEN_STACK).get(serverURI, ptrRecordIPv4Id);
Date now = new Date();
assertNotNull(record.getId());
assertEquals(record.getType(), "PTR");
assertEquals(record.getName(), JCLOUDS_EXAMPLE);
assertEquals(record.getData(), serverIPv4);
assertEquals(record.getTTL(), 12358);
assertNull(record.getPriority());
assertNull(record.getComment());
assertTrue(record.getCreated().before(now));
assertTrue(record.getUpdated().before(now));
}
@Test(dependsOnMethods = "testUpdateAndGetReverseDNSRecords")
public void testDeleteReverseDNSRecord() throws Exception {
awaitComplete(api, api.getReverseDNSApiForService(CLOUD_SERVERS_OPEN_STACK).delete(serverURI, serverIPv4));
assertNull(api.getReverseDNSApiForService(CLOUD_SERVERS_OPEN_STACK).get(serverURI, ptrRecordIPv4Id));
}
@Test(dependsOnMethods = "testUpdateAndGetReverseDNSRecords")
public void testDeleteReverseDNSRecords() throws Exception {
awaitComplete(api, api.getReverseDNSApiForService(CLOUD_SERVERS_OPEN_STACK).deleteAll(serverURI));
assertNull(api.getReverseDNSApiForService(CLOUD_SERVERS_OPEN_STACK).get(serverURI, ptrRecordIPv6Id));
}
@Override
@AfterClass(groups = { "integration", "live" })
protected void tearDown() {
try {
computeService.destroyNode(serverId);
awaitComplete(api, api.getDomainApi().delete(ImmutableList.<Integer> of(domainId), true));
}
catch (TimeoutException e) {
e.printStackTrace();
}
super.tearDown();
}
}

View File

@ -0,0 +1,58 @@
/**
* 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.rackspace.clouddns.v1.internal;
import javax.ws.rs.core.MediaType;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.rackspace.cloudidentity.v2_0.internal.RackspaceFixture;
import org.jclouds.rest.internal.BaseRestApiExpectTest;
/**
* @author Everett Toews
*/
public class BaseCloudDNSApiExpectTest<T> extends BaseRestApiExpectTest<T> {
protected HttpRequest rackspaceAuthWithUsernameAndApiKey;
protected String authToken;
protected HttpResponse responseWithAccess;
public BaseCloudDNSApiExpectTest() {
provider = "rackspace-clouddns";
rackspaceAuthWithUsernameAndApiKey = RackspaceFixture.INSTANCE
.initialAuthWithUsernameAndApiKey(identity, credential);
authToken = RackspaceFixture.INSTANCE.getAuthToken();
responseWithAccess = RackspaceFixture.INSTANCE.responseWithAccess();
}
@Override
protected HttpRequestComparisonType compareHttpRequestAsType(HttpRequest input) {
return HttpRequestComparisonType.JSON;
}
protected HttpRequest.Builder<?> authenticatedGET() {
return HttpRequest.builder()
.method("GET")
.addHeader("Accept", MediaType.APPLICATION_JSON)
.addHeader("X-Auth-Token", authToken);
}
}

View File

@ -0,0 +1,42 @@
/**
* 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.rackspace.clouddns.v1.internal;
import java.util.Properties;
import org.jclouds.apis.BaseApiLiveTest;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
/**
* @author Everett Toews
*/
public class BaseCloudDNSApiLiveTest extends BaseApiLiveTest<CloudDNSApi> {
public BaseCloudDNSApiLiveTest() {
provider = "rackspace-clouddns";
}
@Override
protected Properties setupProperties() {
Properties props = super.setupProperties();
setIfTestSystemPropertyPresent(props, KeystoneProperties.CREDENTIAL_TYPE);
return props;
}
}

View File

@ -0,0 +1,111 @@
{
"request": "{\"domains\":[{\"name\":\"jclouds-example.com\",\"emailAddress\":\"jclouds@jclouds-example.com\",\"ttl\":600000,\"comment\":\"Hello Domain\",\"subdomains\":{\"domains\":[{\"name\":\"dev.jclouds-example.com\",\"emailAddress\":\"jclouds@jclouds-example.com\",\"comment\":\"Hello dev subdomain\"},{\"name\":\"test.jclouds-example.com\",\"emailAddress\":\"jclouds@jclouds-example.com\",\"comment\":\"Hello test subdomain\"}]},\"recordsList\":{\"records\":[{\"name\":\"jclouds-example.com\",\"type\":\"MX\",\"data\":\"mail.jclouds-example.com\",\"priority\":11235},{\"name\":\"jclouds-example.com\",\"type\":\"A\",\"data\":\"10.0.0.1\"}]}},{\"name\":\"xjclouds-example.com\",\"emailAddress\":\"jclouds@jclouds-example.com\",\"ttl\":600000,\"comment\":\"Hello Domain\"}]}",
"response": {
"domains": [
{
"name": "jclouds-example.com",
"id": 3650906,
"comment": "Hello Domain",
"accountId": 123123,
"ttl": 600000,
"subdomains": {
"domains": [
{
"name": "dev.jclouds-example.com",
"id": 3650907,
"comment": "Hello dev subdomain",
"accountId": 123123,
"ttl": 3600,
"emailAddress": "jclouds@jclouds-example.com",
"nameservers": [
{
"name": "dns1.stabletransit.com"
},
{
"name": "dns2.stabletransit.com"
}
],
"updated": "2013-03-22T03:04:15.000+0000",
"created": "2013-03-22T03:04:15.000+0000"
},
{
"name": "test.jclouds-example.com",
"id": 3650908,
"comment": "Hello test subdomain",
"accountId": 123123,
"ttl": 3600,
"emailAddress": "jclouds@jclouds-example.com",
"nameservers": [
{
"name": "dns1.stabletransit.com"
},
{
"name": "dns2.stabletransit.com"
}
],
"updated": "2013-03-22T03:04:15.000+0000",
"created": "2013-03-22T03:04:15.000+0000"
}
]
},
"recordsList": {
"records": [
{
"name": "jclouds-example.com",
"id": "MX-4328817",
"priority": 11235,
"type": "MX",
"data": "mail.jclouds-example.com",
"ttl": 600000,
"updated": "2013-03-22T03:04:13.000+0000",
"created": "2013-03-22T03:04:13.000+0000"
},
{
"name": "jclouds-example.com",
"id": "A-9785208",
"type": "A",
"data": "10.0.0.1",
"ttl": 600000,
"updated": "2013-03-22T03:04:14.000+0000",
"created": "2013-03-22T03:04:14.000+0000"
}
]
},
"emailAddress": "jclouds@jclouds-example.com",
"nameservers": [
{
"name": "dns1.stabletransit.com"
},
{
"name": "dns2.stabletransit.com"
}
],
"updated": "2013-03-22T03:04:12.000+0000",
"created": "2013-03-22T03:04:12.000+0000"
},
{
"name": "xjclouds-example.com",
"id": 3650909,
"comment": "Hello Domain",
"accountId": 123123,
"ttl": 600000,
"emailAddress": "jclouds@jclouds-example.com",
"nameservers": [
{
"name": "dns1.stabletransit.com"
},
{
"name": "dns2.stabletransit.com"
}
],
"updated": "2013-03-22T03:04:16.000+0000",
"created": "2013-03-22T03:04:16.000+0000"
}
]
},
"status": "COMPLETED",
"verb": "POST",
"jobId": "3f4be747-70b0-40e6-96fe-e445c3e12805",
"callbackUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/status/3f4be747-70b0-40e6-96fe-e445c3e12805",
"requestUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/domains"
}

View File

@ -0,0 +1 @@
{"domains":[{"name":"jclouds-example.com","emailAddress":"jclouds@jclouds-example.com","ttl":600000,"comment":"Hello Domain","subdomains":{"domains":[{"name":"dev.jclouds-example.com","emailAddress":"jclouds@jclouds-example.com","comment":"Hello dev subdomain"},{"name":"test.jclouds-example.com","emailAddress":"jclouds@jclouds-example.com","comment":"Hello test subdomain"}]},"recordsList":{"records":[{"name":"jclouds-example.com","type":"MX","data":"mail.jclouds-example.com","priority":11235},{"name":"jclouds-example.com","type":"A","data":"10.0.0.1"}]}},{"name":"xjclouds-example.com","emailAddress":"jclouds@jclouds-example.com","ttl":600000,"comment":"Hello Domain","subdomains":{},"recordsList":{}}]}

View File

@ -0,0 +1,7 @@
{
"status": "COMPLETED",
"verb": "DELETE",
"jobId": "769cffe7-407c-4146-bab5-3a6c4da3e374",
"callbackUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/status/769cffe7-407c-4146-bab5-3a6c4da3e374",
"requestUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/domainsid=3650909&deleteSubdomains=true"
}

View File

@ -0,0 +1,13 @@
{
"response": {
"id": 3651323,
"contentType": "BIND_9",
"contents": "jclouds-example.com.\t600000\tIN\tSOA\tns.rackspace.com. jclouds.jclouds-example.com. 1363960242 21600 3600 1814400 500\njclouds-example.com.\t600000\tIN\tA\t10.0.0.1\njclouds-example.com.\t600000\tIN\tNS\tdns1.stabletransit.com.\njclouds-example.com.\t600000\tIN\tNS\tdns2.stabletransit.com.\njclouds-example.com.\t600000\tIN\tMX\t11235 mail.jclouds-example.com.\n",
"accountId": 123123
},
"status": "COMPLETED",
"verb": "GET",
"jobId": "526d518b-f1b1-4e25-9e19-9643cb030a1e",
"callbackUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/status/526d518b-f1b1-4e25-9e19-9643cb030a1e",
"requestUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/domains/3651323/export"
}

View File

@ -0,0 +1,41 @@
{
"name": "test.jclouds-example.com",
"id": 3650908,
"comment": "Hello test subdomain",
"accountId": 123123,
"ttl": 3600,
"recordsList": {
"records": [
{
"name": "test.jclouds-example.com",
"id": "NS-8646158",
"type": "NS",
"data": "dns1.stabletransit.com",
"ttl": 3600,
"updated": "2013-03-22T03:04:15.000+0000",
"created": "2013-03-22T03:04:15.000+0000"
},
{
"name": "test.jclouds-example.com",
"id": "NS-8646159",
"type": "NS",
"data": "dns2.stabletransit.com",
"ttl": 3600,
"updated": "2013-03-22T03:04:16.000+0000",
"created": "2013-03-22T03:04:16.000+0000"
}
],
"totalEntries": 2
},
"emailAddress": "jclouds@jclouds-example.com",
"nameservers": [
{
"name": "dns1.stabletransit.com"
},
{
"name": "dns2.stabletransit.com"
}
],
"updated": "2013-03-22T03:04:16.000+0000",
"created": "2013-03-22T03:04:15.000+0000"
}

View File

@ -0,0 +1,42 @@
{
"request": "{\"domains\":[{\"contentType\":\"BIND_9\",\"contents\":\"jclouds-example.com. 3600 IN SOA ns.rackspace.com. jclouds.jclouds-example.com. 1363882703 3600 3600 3600 3600\\njclouds-example.com. 600 IN A 50.56.174.152\"}]}",
"response": {
"domains": [
{
"name": "jclouds-example.com",
"id": 3653942,
"accountId": 123123,
"ttl": 3600,
"recordsList": {
"records": [
{
"name": "jclouds-example.com",
"id": "A-9795196",
"type": "A",
"data": "50.56.174.152",
"ttl": 600,
"updated": "2013-03-25T15:15:09.000+0000",
"created": "2013-03-25T15:15:09.000+0000"
}
]
},
"emailAddress": "jclouds@jclouds-example.com",
"nameservers": [
{
"name": "dns1.stabletransit.com"
},
{
"name": "dns2.stabletransit.com"
}
],
"updated": "2013-03-25T15:15:08.000+0000",
"created": "2013-03-25T15:15:08.000+0000"
}
]
},
"status": "COMPLETED",
"verb": "POST",
"jobId": "7729a749-7a16-41ee-a081-00ed71dce4bb",
"callbackUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/status/7729a749-7a16-41ee-a081-00ed71dce4bb",
"requestUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/domains/import"
}

View File

@ -0,0 +1 @@
{"domains":[{"contentType":"BIND_9","contents":"jclouds-example.com. 3600 IN SOA ns.rackspace.com. jclouds.jclouds-example.com. 1363882703 3600 3600 3600 3600\njclouds-example.com. 600 IN A 50.56.174.152"}]}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
{
"domains": [
{
"name": "test.jclouds-example.com",
"id": 3650908,
"comment": "Hello test subdomain",
"emailAddress": "jclouds@jclouds-example.com",
"updated": "2013-03-22T03:04:16.000+0000",
"created": "2013-03-22T03:04:15.000+0000"
}
],
"totalEntries": 1
}

View File

@ -0,0 +1,41 @@
{
"domains": [
{
"name": "dev.jclouds-example.com",
"id": 3650907,
"comment": "Hello dev subdomain",
"accountId": 123123,
"emailAddress": "jclouds@jclouds-example.com",
"updated": "2013-03-22T03:04:15.000+0000",
"created": "2013-03-22T03:04:15.000+0000"
},
{
"name": "jclouds-example.com",
"id": 3650906,
"comment": "Hello Domain",
"accountId": 123123,
"emailAddress": "jclouds@jclouds-example.com",
"updated": "2013-03-22T03:04:14.000+0000",
"created": "2013-03-22T03:04:12.000+0000"
},
{
"name": "test.jclouds-example.com",
"id": 3650908,
"comment": "Hello test subdomain",
"accountId": 123123,
"emailAddress": "jclouds@jclouds-example.com",
"updated": "2013-03-22T03:04:16.000+0000",
"created": "2013-03-22T03:04:15.000+0000"
},
{
"name": "xjclouds-example.com",
"id": 3650909,
"comment": "Hello Domain",
"accountId": 123123,
"emailAddress": "jclouds@jclouds-example.com",
"updated": "2013-03-22T03:04:16.000+0000",
"created": "2013-03-22T03:04:16.000+0000"
}
],
"totalEntries": 4
}

View File

@ -0,0 +1 @@
{"domains":[{"id":3650906,"emailAddress":"everett@jclouds-example.com"},{"id":3650908,"emailAddress":"everett@jclouds-example.com"}]}

View File

@ -0,0 +1,8 @@
{
"request": "{\"domains\":[{\"id\":3650906,\"emailAddress\":\"everett@jclouds-example.com\",\"ttl\":600001,\"comment\":\"Hello Domain Update\"},{\"id\":3650908,\"emailAddress\":\"everett@jclouds-example.com\",\"ttl\":600002,\"comment\":\"Hello Domain Update\"}]}",
"status": "COMPLETED",
"verb": "PUT",
"jobId": "b7fca312-abb5-4e23-91b4-8a21599f0403",
"callbackUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/status/b7fca312-abb5-4e23-91b4-8a21599f0403",
"requestUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/domains"
}

View File

@ -0,0 +1 @@
{"domains":[{"id":3650906,"ttl":1234567},{"id":3650908,"ttl":1234567}]}

View File

@ -0,0 +1 @@
{"ttl":600001,"emailAddress":"everett@jclouds-example.com","comment":"Hello Domain Update"}

View File

@ -0,0 +1,7 @@
{
"status": "RUNNING",
"verb": "GET",
"jobId": "bfbd6ec8-5d4c-49f8-97b5-aa5bfd3e95a4",
"callbackUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/status/bfbd6ec8-5d4c-49f8-97b5-aa5bfd3e95a4",
"requestUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/domains/3650883/export"
}

View File

@ -0,0 +1,57 @@
{
"limits": {
"absolute": {
"records per domain": 500,
"domains": 500
},
"rate": [
{
"limit": [
{
"verb": "GET",
"value": 5,
"remaining": 5,
"unit": "SECOND",
"next-available": "2013-03-06T20:11:14.000Z"
}
],
"uri": "*/status/*",
"regex": ".*/v\\d+\\.\\d+/(\\d+/status).*"
},
{
"limit": [
{
"verb": "GET",
"value": 100,
"remaining": 100,
"unit": "MINUTE",
"next-available": "2013-03-06T20:11:14.000Z"
},
{
"verb": "POST",
"value": 25,
"remaining": 25,
"unit": "MINUTE",
"next-available": "2013-03-06T20:11:14.000Z"
},
{
"verb": "PUT",
"value": 50,
"remaining": 50,
"unit": "MINUTE",
"next-available": "2013-03-06T20:11:14.000Z"
},
{
"verb": "DELETE",
"value": 50,
"remaining": 50,
"unit": "MINUTE",
"next-available": "2013-03-06T20:11:14.000Z"
}
],
"uri": "*/domains*",
"regex": ".*/v\\d+\\.\\d+/(\\d+/domains).*"
}
]
}
}

View File

@ -0,0 +1,7 @@
{
"limitTypes": [
"RATE_LIMIT",
"DOMAIN_LIMIT",
"DOMAIN_RECORD_LIMIT"
]
}

View File

@ -0,0 +1,38 @@
<?xml version="1.0"?>
<configuration scan="false">
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>target/test-data/jclouds.log</file>
<encoder>
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
</encoder>
</appender>
<appender name="WIREFILE" class="ch.qos.logback.core.FileAppender">
<file>target/test-data/jclouds-wire.log</file>
<encoder>
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
</encoder>
</appender>
<root>
<level value="warn" />
</root>
<logger name="org.jclouds">
<level value="DEBUG" />
<appender-ref ref="FILE" />
</logger>
<logger name="jclouds.wire">
<level value="DEBUG" />
<appender-ref ref="WIREFILE" />
</logger>
<logger name="jclouds.headers">
<level value="DEBUG" />
<appender-ref ref="WIREFILE" />
</logger>
</configuration>

View File

@ -0,0 +1,32 @@
{
"request": "{\"records\":[{\"name\":\"jclouds-example.com\",\"type\":\"MX\",\"data\":\"mail.jclouds-example.com\",\"comment\":\"MX Record\",\"priority\":11235},{\"name\":\"jclouds-example.com\",\"type\":\"A\",\"data\":\"10.0.0.1\"}]}",
"response": {
"records": [
{
"name": "jclouds-example.com",
"id": "MX-4350353",
"priority": 11235,
"type": "MX",
"comment":"MX Record",
"data": "mail.jclouds-example.com",
"ttl": 60000,
"updated": "2013-04-05T19:53:18.000+0000",
"created": "2013-04-05T19:53:18.000+0000"
},
{
"name": "jclouds-example.com",
"id": "A-9844102",
"type": "A",
"data": "10.0.0.1",
"ttl": 60000,
"updated": "2013-04-05T19:53:19.000+0000",
"created": "2013-04-05T19:53:19.000+0000"
}
]
},
"status": "COMPLETED",
"verb": "POST",
"jobId": "290bdc5b-f6fa-4c67-83d7-3b29d2abb8e0",
"callbackUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/status/290bdc5b-f6fa-4c67-83d7-3b29d2abb8e0",
"requestUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/domains/3668461/records"
}

View File

@ -0,0 +1 @@
{"records":[{"name":"jclouds-example.com","type":"MX","data":"mail.jclouds-example.com","comment":"MX Record","priority":11235},{"name":"jclouds-example.com","type":"A","data":"10.0.0.1"}]}

View File

@ -0,0 +1,7 @@
{
"status": "COMPLETED",
"verb": "DELETE",
"jobId": "2a5b0f28-05a1-4003-9cec-470c7602cc02",
"callbackUrl": "https://dns.api.rackspacecloud.com/v1.0/717071/status/2a5b0f28-05a1-4003-9cec-470c7602cc02",
"requestUrl": "https://dns.api.rackspacecloud.com/v1.0/717071/domains/3670431/records/A-9849792"
}

View File

@ -0,0 +1,9 @@
{
"name": "jclouds-example.com",
"id": "A-9846146",
"type": "A",
"data": "10.0.1.0",
"ttl": 60000,
"updated": "2013-04-06T15:20:29.000+0000",
"created": "2013-04-06T15:20:29.000+0000"
}

View File

@ -0,0 +1,13 @@
{
"records": [
{
"name": "jclouds-example.com",
"id": "A-9846146",
"type": "A",
"data": "10.0.1.0",
"ttl": 60000,
"updated": "2013-04-06T15:20:29.000+0000",
"created": "2013-04-06T15:20:29.000+0000"
}
]
}

View File

@ -0,0 +1,42 @@
{
"records": [
{
"name": "jclouds-example.com",
"id": "A-9846146",
"type": "A",
"data": "10.0.1.0",
"ttl": 60000,
"updated": "2013-04-06T15:20:29.000+0000",
"created": "2013-04-06T15:20:29.000+0000"
},
{
"name": "jclouds-example.com",
"id": "NS-8684719",
"type": "NS",
"data": "dns1.stabletransit.com",
"ttl": 60000,
"updated": "2013-04-06T15:19:20.000+0000",
"created": "2013-04-06T15:19:20.000+0000"
},
{
"name": "jclouds-example.com",
"id": "NS-8684720",
"type": "NS",
"data": "dns2.stabletransit.com",
"ttl": 60000,
"updated": "2013-04-06T15:19:20.000+0000",
"created": "2013-04-06T15:19:20.000+0000"
},
{
"name": "jclouds-example.com",
"id": "MX-4351045",
"priority": 11235,
"type": "MX",
"data": "mail.jclouds-example.com.com",
"ttl": 60000,
"updated": "2013-04-06T15:20:28.000+0000",
"created": "2013-04-06T15:20:28.000+0000"
}
],
"totalEntries": 4
}

View File

@ -0,0 +1,31 @@
{
"request": "{\"recordsList\":{\"records\":[{\"name\":\"jclouds-example.com\",\"type\":\"PTR\",\"ttl\":11235,\"data\":\"166.78.146.80\"},{\"name\":\"jclouds-example.com\",\"type\":\"PTR\",\"data\":\"2001:4800:7812:0514:9a32:3c2a:ff04:aed2\",\"comment\":\"Hello IPv6\"}]},\"link\":{\"href\":\"https://dfw.servers.api.rackspacecloud.com/v2/123123/servers/f5fb9334-b4f0-49d0-a2cc-57a5772dc7d1\",\"rel\":\"cloudServersOpenStack\"}}",
"response": {
"records": [
{
"name": "jclouds-example.com",
"id": "PTR-557432",
"type": "PTR",
"data": "166.78.146.80",
"ttl": 11235,
"updated": "2013-04-11T15:20:23.000+0000",
"created": "2013-04-11T15:20:23.000+0000"
},
{
"name": "jclouds-example.com",
"id": "PTR-557433",
"type": "PTR",
"data": "2001:4800:7812:514:9a32:3c2a:ff04:aed2",
"ttl": 3600,
"comment": "Hello IPv6",
"updated": "2013-04-11T15:20:25.000+0000",
"created": "2013-04-11T15:20:25.000+0000"
}
]
},
"status": "COMPLETED",
"verb": "POST",
"jobId": "0e9aefac-476f-40ba-9626-66dd54c0a5c9",
"callbackUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/status/0e9aefac-476f-40ba-9626-66dd54c0a5c9",
"requestUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/rdns"
}

View File

@ -0,0 +1 @@
{"recordsList":{"records":[{"name":"jclouds-example.com","type":"PTR","ttl":11235,"data":"166.78.146.80"},{"name":"jclouds-example.com","type":"PTR","data":"2001:4800:7812:0514:9a32:3c2a:ff04:aed2","comment":"Hello IPv6"}]},"link":{"href":"https://dfw.servers.api.rackspacecloud.com/v2/123123/servers/f5fb9334-b4f0-49d0-a2cc-57a5772dc7d1","rel":"cloudServersOpenStack"}}

View File

@ -0,0 +1,7 @@
{
"status": "COMPLETED",
"verb": "DELETE",
"jobId": "4988d69c-37b5-406c-b82b-58ed099d68cd",
"callbackUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/status/4988d69c-37b5-406c-b82b-58ed099d68cd",
"requestUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/rdns/cloudServersOpenStackhref=https://dfw.servers.api.rackspacecloud.com/v2/123123/servers/f5fb9334-b4f0-49d0-a2cc-57a5772dc7d1&ip=166.78.146.80"
}

View File

@ -0,0 +1,9 @@
{
"name": "jclouds-example.com",
"id": "PTR-557437",
"type": "PTR",
"data": "166.78.146.80",
"ttl": 11235,
"updated": "2013-04-11T15:35:34.000+0000",
"created": "2013-04-11T15:35:34.000+0000"
}

View File

@ -0,0 +1,23 @@
{
"records": [
{
"name": "jclouds-example.com",
"id": "PTR-557437",
"type": "PTR",
"data": "166.78.146.80",
"ttl": 11235,
"updated": "2013-04-11T15:35:34.000+0000",
"created": "2013-04-11T15:35:34.000+0000"
},
{
"name": "jclouds-example.com",
"id": "PTR-557438",
"type": "PTR",
"comment": "Hello IPv6",
"data": "2001:4800:7812:514:9a32:3c2a:ff04:aed2",
"ttl": 3600,
"updated": "2013-04-11T15:35:37.000+0000",
"created": "2013-04-11T15:35:37.000+0000"
}
]
}

View File

@ -0,0 +1,8 @@
{
"request": "{\"recordsList\":{\"records\":[{\"id\":\"PTR-557437\",\"name\":\"jclouds-example.com\",\"ttl\":12358,\"data\":\"166.78.146.80\"}]},\"link\":{\"href\":\"https://dfw.servers.api.rackspacecloud.com/v2/123123/servers/f5fb9334-b4f0-49d0-a2cc-57a5772dc7d1\",\"rel\":\"cloudServersOpenStack\"}}",
"status": "COMPLETED",
"verb": "PUT",
"jobId": "8e9970a4-365e-4fd9-a243-71c0abcdf18f",
"callbackUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/status/8e9970a4-365e-4fd9-a243-71c0abcdf18f",
"requestUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/rdns"
}

View File

@ -0,0 +1 @@
{"recordsList":{"records":[{"id":"PTR-557437","name":"jclouds-example.com","ttl":12358,"data":"166.78.146.80"}]},"link":{"href":"https://dfw.servers.api.rackspacecloud.com/v2/123123/servers/f5fb9334-b4f0-49d0-a2cc-57a5772dc7d1","rel":"cloudServersOpenStack"}}

View File

@ -0,0 +1,8 @@
{
"request": "{\"name\":\"_sip._udp.jclouds-example.com\",\"ttl\":86401,\"data\":\"1 3444 sip.jclouds-example.com\",\"priority\":12358,\"comment\":\"Updated Protocol to UDP\"}",
"status": "COMPLETED",
"verb": "PUT",
"jobId": "90659522-915d-4b69-a806-0bc464f01cde",
"callbackUrl": "https://dns.api.rackspacecloud.com/v1.0/717071/status/90659522-915d-4b69-a806-0bc464f01cde",
"requestUrl": "https://dns.api.rackspacecloud.com/v1.0/717071/domains/3669444/records/SRV-21839"
}

View File

@ -0,0 +1 @@
{"name":"_sip._udp.jclouds-example.com","ttl":86401,"data":"1 3444 sip.jclouds-example.com","priority":12358,"comment":"Updated Protocol to UDP"}

View File

@ -0,0 +1,7 @@
{
"status": "COMPLETED",
"verb": "DELETE",
"jobId": "2ad9876f-74f8-4c1c-af9c-1641a72cab75",
"callbackUrl": "https://dns.api.rackspacecloud.com/v1.0/717071/status/2ad9876f-74f8-4c1c-af9c-1641a72cab75",
"requestUrl": "https://dns.api.rackspacecloud.com/v1.0/717071/domains/3670431/records?id=A-9846146&id=MX-9846146"
}

View File

@ -0,0 +1,7 @@
{
"status": "COMPLETED",
"verb": "DELETE",
"jobId": "ddeea5c4-cbec-4bc3-b37f-eb4f8c0771cc",
"callbackUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/status/ddeea5c4-cbec-4bc3-b37f-eb4f8c0771cc",
"requestUrl": "https://dns.api.rackspacecloud.com/v1.0/123123/rdns/cloudServersOpenStackhref=https://dfw.servers.api.rackspacecloud.com/v2/123123/servers/f5fb9334-b4f0-49d0-a2cc-57a5772dc7d1"
}

View File

@ -0,0 +1,8 @@
{
"request": "{\"records\":[{\"id\":\"A-9849792\",\"comment\":\"Multi-record Update\"},{\"id\":\"NS-8687533\",\"comment\":\"Multi-record Update\"},{\"id\":\"NS-8687534\",\"comment\":\"Multi-record Update\"},{\"id\":\"MX-4352374\",\"comment\":\"Multi-record Update\"}]}",
"status": "COMPLETED",
"verb": "PUT",
"jobId": "839768a9-102b-49cc-8227-b9de7485296a",
"callbackUrl": "https://dns.api.rackspacecloud.com/v1.0/717071/status/839768a9-102b-49cc-8227-b9de7485296a",
"requestUrl": "https://dns.api.rackspacecloud.com/v1.0/717071/domains/3670431/records"
}

View File

@ -0,0 +1 @@
{"records":[{"id":"A-9846146","comment":"Multi-record Update"},{"id":"MX-9846146","comment":"Multi-record Update"}]}

View File

@ -66,6 +66,8 @@
<module>cloudservers-uk</module>
<module>cloudfiles-us</module>
<module>cloudfiles-uk</module>
<module>rackspace-clouddns-us</module>
<module>rackspace-clouddns-uk</module>
<module>rackspace-cloudloadbalancers-us</module>
<module>rackspace-cloudloadbalancers-uk</module>
<module>rackspace-cloudservers-us</module>

View File

@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId>
<version>1.6.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath>
</parent>
<groupId>org.jclouds.provider</groupId>
<artifactId>rackspace-clouddns-uk</artifactId>
<name>jclouds Rackspace Next Generation Cloud DNS UK provider</name>
<description>Rackspace Next Generation Cloud DNS UK</description>
<packaging>bundle</packaging>
<properties>
<test.rackspace-clouddns-uk.endpoint>https://lon.identity.api.rackspacecloud.com/v2.0/</test.rackspace-clouddns-uk.endpoint>
<test.rackspace-clouddns-uk.api-version>1.0</test.rackspace-clouddns-uk.api-version>
<test.rackspace-clouddns-uk.build-version />
<test.rackspace-clouddns-uk.identity>${test.rackspace-uk.identity}</test.rackspace-clouddns-uk.identity>
<test.rackspace-clouddns-uk.credential>${test.rackspace-uk.credential}</test.rackspace-clouddns-uk.credential>
<test.rackspace-clouddns-uk.template />
<jclouds.osgi.export>org.jclouds.rackspace.clouddns.us*;version="${project.version}"</jclouds.osgi.export>
<jclouds.osgi.import>
org.jclouds.compute.internal;version="${project.version}",
org.jclouds.rest.internal;version="${project.version}",
org.jclouds*;version="${project.version}",
*
</jclouds.osgi.import>
</properties>
<dependencies>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>openstack-keystone</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>rackspace-clouddns</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>rackspace-cloudidentity</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>openstack-keystone</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>rackspace-clouddns</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>rackspace-cloudidentity</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-slf4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.rackspace-clouddns-uk.endpoint>${test.rackspace-clouddns-uk.endpoint}</test.rackspace-clouddns-uk.endpoint>
<test.rackspace-clouddns-uk.api-version>${test.rackspace-clouddns-uk.api-version}</test.rackspace-clouddns-uk.api-version>
<test.rackspace-clouddns-uk.build-version>${test.rackspace-clouddns-uk.build-version}</test.rackspace-clouddns-uk.build-version>
<test.rackspace-clouddns-uk.identity>${test.rackspace-clouddns-uk.identity}</test.rackspace-clouddns-uk.identity>
<test.rackspace-clouddns-uk.credential>${test.rackspace-clouddns-uk.credential}</test.rackspace-clouddns-uk.credential>
<test.rackspace-clouddns-uk.template>${test.rackspace-clouddns-uk.template}</test.rackspace-clouddns-uk.template>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,85 @@
/**
* 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.rackspace.clouddns.uk;
import java.net.URI;
import java.util.Properties;
import org.jclouds.providers.ProviderMetadata;
import org.jclouds.providers.internal.BaseProviderMetadata;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApiMetadata;
/**
* Implementation of {@link org.jclouds.types.ProviderMetadata} for Rackspace DNS UK.
*
* @author Everett Toews
*/
public class CloudDNSUKProviderMetadata extends BaseProviderMetadata {
public static Builder builder() {
return new Builder();
}
@Override
public Builder toBuilder() {
return builder().fromProviderMetadata(this);
}
public CloudDNSUKProviderMetadata() {
super(builder());
}
public CloudDNSUKProviderMetadata(Builder builder) {
super(builder);
}
public static Properties defaultProperties() {
Properties properties = new Properties();
return properties;
}
public static class Builder extends BaseProviderMetadata.Builder {
protected Builder(){
id("rackspace-clouddns-uk")
.name("Rackspace Cloud DNS UK")
.apiMetadata(new CloudDNSApiMetadata().toBuilder()
.defaultEndpoint("https://lon.identity.api.rackspacecloud.com/v2.0/")
.build())
.homepage(URI.create("http://www.rackspace.com/cloud/public/dns/"))
.console(URI.create("https://mycloud.rackspace.com"))
.linkedServices("rackspace-cloudidentity", "rackspace-cloudservers-uk", "cloudfiles-uk", "rackspace-cloudblockstorage-uk", "rackspace-cloudloadbalancers-uk")
.iso3166Codes("GB-SLG")
.endpoint("https://lon.identity.api.rackspacecloud.com/v2.0/")
.defaultProperties(CloudDNSApiMetadata.defaultProperties());
}
@Override
public CloudDNSUKProviderMetadata build() {
return new CloudDNSUKProviderMetadata(this);
}
@Override
public Builder fromProviderMetadata(
ProviderMetadata in) {
super.fromProviderMetadata(in);
return this;
}
}
}

View File

@ -0,0 +1 @@
org.jclouds.rackspace.clouddns.uk.CloudDNSUKProviderMetadata

View File

@ -0,0 +1,33 @@
/**
* 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.rackspace.clouddns.uk.features;
import org.jclouds.rackspace.clouddns.v1.features.DomainApiLiveTest;
import org.testng.annotations.Test;
/**
*
* @author Everett Toews
*/
@Test(groups = "live", singleThreaded = true, testName = "CloudDNSUKDomainApiLiveTest")
public class CloudDNSUKDomainApiLiveTest extends DomainApiLiveTest {
public CloudDNSUKDomainApiLiveTest() {
provider = "rackspace-clouddns-uk";
}
}

View File

@ -0,0 +1,33 @@
/**
* 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.rackspace.clouddns.uk.features;
import org.jclouds.rackspace.clouddns.v1.features.LimitApiLiveTest;
import org.testng.annotations.Test;
/**
*
* @author Everett Toews
*/
@Test(groups = "live", singleThreaded = true, testName = "CloudDNSUKLimitApiLiveTest")
public class CloudDNSUKLimitApiLiveTest extends LimitApiLiveTest {
public CloudDNSUKLimitApiLiveTest() {
provider = "rackspace-clouddns-uk";
}
}

View File

@ -0,0 +1,36 @@
/**
* 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.rackspace.clouddns.uk.features;
import org.jclouds.providers.internal.BaseProviderMetadataTest;
import org.jclouds.rackspace.clouddns.uk.CloudDNSUKProviderMetadata;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApiMetadata;
import org.testng.annotations.Test;
/**
*
* @author Everett Toews
*/
@Test(groups = "unit", testName = "CloudDNSUKProviderTest")
public class CloudDNSUKProviderTest extends BaseProviderMetadataTest {
public CloudDNSUKProviderTest() {
super(new CloudDNSUKProviderMetadata(), new CloudDNSApiMetadata());
}
}

View File

@ -0,0 +1,33 @@
/**
* 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.rackspace.clouddns.uk.features;
import org.jclouds.rackspace.clouddns.v1.features.RecordApiLiveTest;
import org.testng.annotations.Test;
/**
*
* @author Everett Toews
*/
@Test(groups = "live", singleThreaded = true, testName = "CloudDNSUKRecordApiLiveTest")
public class CloudDNSUKRecordApiLiveTest extends RecordApiLiveTest {
public CloudDNSUKRecordApiLiveTest() {
provider = "rackspace-clouddns-uk";
}
}

View File

@ -0,0 +1,167 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId>
<version>1.6.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath>
</parent>
<groupId>org.jclouds.provider</groupId>
<artifactId>rackspace-clouddns-us</artifactId>
<name>jclouds Rackspace Next Generation Cloud DNS US provider</name>
<description>Rackspace Next Generation Cloud DNS US</description>
<packaging>bundle</packaging>
<properties>
<test.rackspace-clouddns-us.endpoint>https://identity.api.rackspacecloud.com/v2.0/</test.rackspace-clouddns-us.endpoint>
<test.rackspace-clouddns-us.api-version>1.0</test.rackspace-clouddns-us.api-version>
<test.rackspace-clouddns-us.build-version />
<test.rackspace-clouddns-us.identity>${test.rackspace-us.identity}</test.rackspace-clouddns-us.identity>
<test.rackspace-clouddns-us.credential>${test.rackspace-us.credential}</test.rackspace-clouddns-us.credential>
<test.rackspace-clouddns-us.template />
<jclouds.osgi.export>org.jclouds.rackspace.clouddns.us*;version="${project.version}"</jclouds.osgi.export>
<jclouds.osgi.import>
org.jclouds.compute.internal;version="${project.version}",
org.jclouds.rest.internal;version="${project.version}",
org.jclouds*;version="${project.version}",
*
</jclouds.osgi.import>
</properties>
<dependencies>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>openstack-keystone</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>rackspace-clouddns</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>rackspace-cloudidentity</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-compute</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>openstack-keystone</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>openstack-nova</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>rackspace-clouddns</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>rackspace-cloudidentity</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.provider</groupId>
<artifactId>rackspace-cloudservers-us</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-slf4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.rackspace-clouddns-us.endpoint>${test.rackspace-clouddns-us.endpoint}</test.rackspace-clouddns-us.endpoint>
<test.rackspace-clouddns-us.api-version>${test.rackspace-clouddns-us.api-version}</test.rackspace-clouddns-us.api-version>
<test.rackspace-clouddns-us.build-version>${test.rackspace-clouddns-us.build-version}</test.rackspace-clouddns-us.build-version>
<test.rackspace-clouddns-us.identity>${test.rackspace-clouddns-us.identity}</test.rackspace-clouddns-us.identity>
<test.rackspace-clouddns-us.credential>${test.rackspace-clouddns-us.credential}</test.rackspace-clouddns-us.credential>
<test.rackspace-clouddns-us.template>${test.rackspace-clouddns-us.template}</test.rackspace-clouddns-us.template>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,85 @@
/**
* 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.rackspace.clouddns.us;
import java.net.URI;
import java.util.Properties;
import org.jclouds.providers.ProviderMetadata;
import org.jclouds.providers.internal.BaseProviderMetadata;
import org.jclouds.rackspace.clouddns.v1.CloudDNSApiMetadata;
/**
* Implementation of {@link org.jclouds.types.ProviderMetadata} for Rackspace DNS US.
*
* @author Everett Toews
*/
public class CloudDNSUSProviderMetadata extends BaseProviderMetadata {
public static Builder builder() {
return new Builder();
}
@Override
public Builder toBuilder() {
return builder().fromProviderMetadata(this);
}
public CloudDNSUSProviderMetadata() {
super(builder());
}
public CloudDNSUSProviderMetadata(Builder builder) {
super(builder);
}
public static Properties defaultProperties() {
Properties properties = new Properties();
return properties;
}
public static class Builder extends BaseProviderMetadata.Builder {
protected Builder(){
id("rackspace-clouddns-us")
.name("Rackspace Cloud DNS US")
.apiMetadata(new CloudDNSApiMetadata().toBuilder()
.defaultEndpoint("https://identity.api.rackspacecloud.com/v2.0/")
.build())
.homepage(URI.create("http://www.rackspace.com/cloud/public/dns/"))
.console(URI.create("https://mycloud.rackspace.com"))
.linkedServices("rackspace-cloudidentity", "rackspace-cloudservers-us", "cloudfiles-us", "rackspace-cloudblockstorage-us", "rackspace-cloudloadbalancers-us")
.iso3166Codes("US-TX")
.endpoint("https://identity.api.rackspacecloud.com/v2.0/")
.defaultProperties(CloudDNSApiMetadata.defaultProperties());
}
@Override
public CloudDNSUSProviderMetadata build() {
return new CloudDNSUSProviderMetadata(this);
}
@Override
public Builder fromProviderMetadata(
ProviderMetadata in) {
super.fromProviderMetadata(in);
return this;
}
}
}

View File

@ -0,0 +1 @@
org.jclouds.rackspace.clouddns.us.CloudDNSUSProviderMetadata

View File

@ -0,0 +1,33 @@
/**
* 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.rackspace.clouddns.us.features;
import org.jclouds.rackspace.clouddns.v1.features.DomainApiLiveTest;
import org.testng.annotations.Test;
/**
*
* @author Everett Toews
*/
@Test(groups = "live", singleThreaded = true, testName = "CloudDNSUSDomainApiLiveTest")
public class CloudDNSUSDomainApiLiveTest extends DomainApiLiveTest {
public CloudDNSUSDomainApiLiveTest() {
provider = "rackspace-clouddns-us";
}
}

Some files were not shown because too many files have changed in this diff Show More