Merge pull request #1339 from jclouds/ultradns-rr-crud

ultradns rr crud
This commit is contained in:
Adrian Cole 2013-02-22 15:20:00 -08:00
commit dc4dbd68bf
32 changed files with 1759 additions and 18 deletions

View File

@ -0,0 +1,161 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.ultradns.ws;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.EnumSet;
import java.util.Set;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.collect.BiMap;
import com.google.common.collect.ForwardingMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.primitives.UnsignedInteger;
/**
* Most UltraDNS commands use the numerical type value of a resource record
* rather than their names. This class helps convert the numerical values to
* what people more commonly use. Note that this does not complain a complete
* mapping and may need updates over time.
*
* @author Adrian Cole
* @see org.jclouds.rest.annotations.ParamParser
*/
@Beta
public class ResourceTypeToValue extends ForwardingMap<String, UnsignedInteger> implements Function<Object, String>,
BiMap<String, UnsignedInteger> {
/**
* look up the value (ex. {@code 28}) for the mnemonic name (ex. {@code AAAA}
* ).
*
* @param type
* type to look up. ex {@code AAAA}
* @throws IllegalArgumentException
* if the type was not configured.
*/
public static UnsignedInteger lookup(String type) throws IllegalArgumentException {
checkNotNull(type, "resource type was null");
checkArgument(lookup.containsKey(type), "%s do not include %s; types: %s", ResourceTypes.class.getSimpleName(),
type, EnumSet.allOf(ResourceTypes.class));
return lookup.get(type);
}
/**
* Taken from <a href=
* "http://www.iana.org/assignments/dns-parameters/dns-parameters.xml#dns-parameters-3"
* >iana types</a>.
*
*/
// enum only to look and format prettier than fluent bimap builder calls
private static enum ResourceTypes {
/**
* a host address
*/
A(1),
/**
* an authoritative name server
*/
NS(2),
/**
* the canonical name for an alias
*/
CNAME(5),
/**
* marks the start of a zone of authority
*/
SOA(6),
/**
* a domain name pointer
*/
PTR(12),
/**
* mail exchange
*/
MX(15),
/**
* text strings
*/
TXT(16),
/**
* IP6 Address
*/
AAAA(28),
/**
* Server Selection
*/
SRV(33);
private final UnsignedInteger value;
private ResourceTypes(int value) {
this.value = UnsignedInteger.fromIntBits(value);
}
}
@Override
protected ImmutableBiMap<String, UnsignedInteger> delegate() {
return lookup;
}
private static final ImmutableBiMap<String, UnsignedInteger> lookup;
static {
ImmutableBiMap.Builder<String, UnsignedInteger> builder = ImmutableBiMap.builder();
for (ResourceTypes r : EnumSet.allOf(ResourceTypes.class)) {
builder.put(r.name(), r.value);
}
lookup = builder.build();
}
/**
* @see ImmutableBiMap#forcePut(Object, Object)
*/
@Deprecated
@Override
public UnsignedInteger forcePut(String key, UnsignedInteger value) {
return lookup.forcePut(key, value);
}
@Override
public Set<UnsignedInteger> values() {
return lookup.values();
}
@Override
public BiMap<UnsignedInteger, String> inverse() {
return lookup.inverse();
}
@Override
public String apply(Object input) {
return lookup(checkNotNull(input, "resource type was null").toString()).toString();
}
}

View File

@ -19,7 +19,9 @@
package org.jclouds.ultradns.ws;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.ultradns.ws.domain.Account;
import org.jclouds.ultradns.ws.features.ResourceRecordApi;
import org.jclouds.ultradns.ws.features.TaskApi;
import org.jclouds.ultradns.ws.features.ZoneApi;
@ -43,6 +45,15 @@ public interface UltraDNSWSApi {
@Delegate
ZoneApi getZoneApi();
/**
* Provides synchronous access to Resource Record features.
*
* @param zoneName
* zoneName including a trailing dot
*/
@Delegate
ResourceRecordApi getResourceRecordApiForZone(@PayloadParam("zoneName") String zoneName);
/**
* Provides synchronous access to Task features.
*/

View File

@ -23,10 +23,12 @@ import javax.ws.rs.POST;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.Payload;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.ultradns.ws.domain.Account;
import org.jclouds.ultradns.ws.features.ResourceRecordAsyncApi;
import org.jclouds.ultradns.ws.features.TaskAsyncApi;
import org.jclouds.ultradns.ws.features.ZoneAsyncApi;
import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth;
@ -61,6 +63,15 @@ public interface UltraDNSWSAsyncApi {
@Delegate
ZoneAsyncApi getZoneApi();
/**
* Provides asynchronous access to Resource Record features.
*
* @param zoneName
* zoneName including a trailing dot
*/
@Delegate
ResourceRecordAsyncApi getResourceRecordApiForZone(@PayloadParam("zoneName") String zoneName);
/**
* Provides asynchronous access to Task features.
*/

View File

@ -0,0 +1,72 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.ultradns.ws.binders;
import static java.lang.String.format;
import java.util.Map;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.MapBinder;
import org.jclouds.ultradns.ws.domain.ResourceRecord;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
/**
*
* @author Adrian Cole
*/
public class ZoneAndResourceRecordToXML implements MapBinder {
private static final String template = "<v01:createResourceRecord><transactionID /><resourceRecord ZoneName=\"%s\" Type=\"%s\" DName=\"%s\" TTL=\"%s\">%s</resourceRecord></v01:createResourceRecord>";
@SuppressWarnings("unchecked")
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
String zoneName = postParams.get("zoneName").toString();
ResourceRecord record = ResourceRecord.class.cast(postParams.get("resourceRecord"));
String xml = toXML(zoneName, record);
Optional<?> guid = Optional.fromNullable(postParams.get("guid"));
if (guid.isPresent()) {
xml = update(guid.get(), xml);
}
return (R) request.toBuilder().payload(xml).build();
}
@VisibleForTesting
static String toXML(String zoneName, ResourceRecord record) {
StringBuilder values = new StringBuilder("<InfoValues");
for (int i = 0; i < record.getRData().size(); i++) {
values.append(' ').append("Info").append(i + 1).append("Value=").append('"')
.append(record.getRData().get(i)).append('"');
}
values.append(" />");
return format(template, zoneName, record.getType(), record.getName(), record.getTTL(), values.toString());
}
static String update(Object guid, String xml) {
return xml.replace("createResourceRecord", "updateResourceRecord").replace("<resourceRecord",
format("<resourceRecord Guid=\"%s\"", guid));
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
throw new UnsupportedOperationException("use map form");
}
}

View File

@ -29,6 +29,8 @@ import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule;
import org.jclouds.ultradns.ws.UltraDNSWSApi;
import org.jclouds.ultradns.ws.UltraDNSWSAsyncApi;
import org.jclouds.ultradns.ws.features.ResourceRecordApi;
import org.jclouds.ultradns.ws.features.ResourceRecordAsyncApi;
import org.jclouds.ultradns.ws.features.TaskApi;
import org.jclouds.ultradns.ws.features.TaskAsyncApi;
import org.jclouds.ultradns.ws.features.ZoneApi;
@ -47,6 +49,7 @@ public class UltraDNSWSRestClientModule extends RestClientModule<UltraDNSWSApi,
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
.put(ZoneApi.class, ZoneAsyncApi.class)
.put(ResourceRecordApi.class, ResourceRecordAsyncApi.class)
.put(TaskApi.class, TaskAsyncApi.class).build();
public UltraDNSWSRestClientModule() {

View File

@ -0,0 +1,189 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.ultradns.ws.domain;
import static com.google.common.base.Functions.toStringFunction;
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 static com.google.common.collect.Iterables.transform;
import java.util.List;
import org.jclouds.ultradns.ws.ResourceTypeToValue;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.UnsignedInteger;
/**
* @author Adrian Cole
*/
public class ResourceRecord {
private final String dName;
private final UnsignedInteger type;
private final UnsignedInteger ttl;
private final List<String> infoValues;
private ResourceRecord(String dName, UnsignedInteger type, UnsignedInteger ttl, List<String> infoValues) {
this.dName = checkNotNull(dName, "dName");
this.type = checkNotNull(type, "type of %s", dName);
this.ttl = checkNotNull(ttl, "ttl of %s", dName);
this.infoValues = checkNotNull(infoValues, "infoValues of %s", dName);
}
/**
* the {@code dName} of the record.
*/
public String getName() {
return dName;
}
/**
* the type value. ex {@code 1} for type {@code A}
*/
public UnsignedInteger getType() {
return type;
}
public UnsignedInteger getTTL() {
return ttl;
}
/**
* {@link #getType() type}-specific binary values.
*/
public List<String> getRData() {
return infoValues;
}
@Override
public int hashCode() {
return Objects.hashCode(dName, type, ttl, infoValues);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
ResourceRecord that = ResourceRecord.class.cast(obj);
return equal(this.dName, that.dName) && equal(this.type, that.type) && equal(this.ttl, that.ttl)
&& equal(this.infoValues, that.infoValues);
}
@Override
public String toString() {
return toStringHelper("").omitNullValues().add("dName", dName).add("type", type).add("ttl", ttl)
.add("infoValues", infoValues).toString();
}
public static Builder rrBuilder() {
return new Builder();
}
public Builder toBuilder() {
return rrBuilder().from(this);
}
public final static class Builder {
private String dName;
private UnsignedInteger type;
private UnsignedInteger ttl;
private ImmutableList.Builder<String> infoValues = ImmutableList.<String> builder();
/**
* @see ResourceRecord#getName()
*/
public Builder name(String dName) {
this.dName = dName;
return this;
}
/**
* use this for common type values available in
* {@link ResourceTypeToValue}, such as {@code MX} or {@code PTR}
*
* @see ResourceRecord#getType()
* @throws IllegalArgumentException
* if the type value is not present in
* {@link ResourceTypeToValue},
*/
public Builder type(String type) throws IllegalArgumentException {
this.type = ResourceTypeToValue.lookup(type);
return this;
}
/**
* @see ResourceRecord#getType()
*/
public Builder type(UnsignedInteger type) {
this.type = type;
return this;
}
/**
* @see ResourceRecord#getType()
*/
public Builder type(int type) {
return type(UnsignedInteger.fromIntBits(type));
}
/**
* @see ResourceRecord#getTTL()
*/
public Builder ttl(UnsignedInteger ttl) {
this.ttl = ttl;
return this;
}
/**
* @see ResourceRecord#getTTL()
*/
public Builder ttl(int ttl) {
return ttl(UnsignedInteger.fromIntBits(ttl));
}
/**
* @see ResourceRecord#getRData()
*/
public Builder rdata(Object infoValue) {
this.infoValues.add(infoValue.toString());
return this;
}
/**
* @see ResourceRecord#getRData()
*/
public Builder rdata(Iterable<?> infoValues) {
this.infoValues.addAll(transform(infoValues, toStringFunction()));
return this;
}
public ResourceRecord build() {
return new ResourceRecord(dName, type, ttl, infoValues.build());
}
public Builder from(ResourceRecord in) {
return name(in.getName()).type(in.getType()).ttl(in.getTTL()).rdata(in.getRData());
}
}
}

View File

@ -0,0 +1,181 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.ultradns.ws.domain;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Date;
import com.google.common.base.Objects;
/**
*
* @author Adrian Cole
*/
public class ResourceRecordMetadata {
private final String zoneId;
private final String guid;
private final String zoneName;
private final Date created;
private final Date modified;
private final ResourceRecord record;
private ResourceRecordMetadata(String zoneId, String guid, String zoneName, Date created, Date modified,
ResourceRecord record) {
this.zoneId = checkNotNull(zoneId, "zoneId");
this.guid = checkNotNull(guid, "guid");
this.zoneName = checkNotNull(zoneName, "zoneName of %s/%s", zoneId, guid);
this.created = checkNotNull(created, "created of %s/%s", zoneId, guid);
this.modified = checkNotNull(modified, "modified of %s/%s", zoneId, guid);
this.record = checkNotNull(record, "record of %s/%s", zoneId, guid);
}
public String getZoneId() {
return zoneId;
}
public String getGuid() {
return guid;
}
public String getZoneName() {
return zoneName;
}
public Date getCreated() {
return created;
}
public Date getModified() {
return modified;
}
/**
* the record in the zone file.
*/
public ResourceRecord getRecord() {
return record;
}
@Override
public int hashCode() {
return Objects.hashCode(zoneId, guid);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
ResourceRecordMetadata that = ResourceRecordMetadata.class.cast(obj);
return equal(this.zoneId, that.zoneId) && equal(this.guid, that.guid);
}
@Override
public String toString() {
return toStringHelper("").omitNullValues().add("zoneId", zoneId).add("guid", guid).add("zoneName", zoneName)
.add("created", created).add("modified", modified).add("record", record).toString();
}
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return builder().from(this);
}
public final static class Builder {
private String zoneId;
private String guid;
private String zoneName;
private Date created;
private Date modified;
private ResourceRecord record;
/**
* @see ResourceRecordMetadata#getZoneName()
*/
public Builder zoneName(String zoneName) {
this.zoneName = zoneName;
return this;
}
/**
* @see ResourceRecordMetadata#getGuid()
*/
public Builder guid(String guid) {
this.guid = guid;
return this;
}
/**
* @see ResourceRecordMetadata#getZoneId()
*/
public Builder zoneId(String zoneId) {
this.zoneId = zoneId;
return this;
}
/**
* @see ResourceRecordMetadata#getCreated()
*/
public Builder created(Date created) {
this.created = created;
return this;
}
/**
* @see ResourceRecordMetadata#getModified()
*/
public Builder modified(Date modified) {
this.modified = modified;
return this;
}
/**
* @see ResourceRecordMetadata#getRecord()
*/
public Builder record(ResourceRecord record) {
this.record = record;
return this;
}
/**
* @see ResourceRecordMetadata#getRecord()
*/
public Builder record(ResourceRecord.Builder record) {
this.record = record.build();
return this;
}
public ResourceRecordMetadata build() {
return new ResourceRecordMetadata(zoneId, guid, zoneName, created, modified, record);
}
public Builder from(ResourceRecordMetadata in) {
return this.zoneName(in.zoneName).guid(in.guid).zoneId(in.zoneId).created(in.created).modified(in.modified)
.record(in.record);
}
}
}

View File

@ -0,0 +1,117 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.ultradns.ws.features;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.ultradns.ws.ResourceTypeToValue;
import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException;
import org.jclouds.ultradns.ws.domain.ResourceRecord;
import org.jclouds.ultradns.ws.domain.ResourceRecordMetadata;
import com.google.common.collect.FluentIterable;
import com.google.common.primitives.UnsignedInteger;
/**
* @see ResourceRecordAsyncApi
* @author Adrian Cole
*/
public interface ResourceRecordApi {
/**
* creates a resource record in the zone.
*
* @param toCreate
* the new record to create.
* @return the {@code guid} of the new record
* @throws ResourceAlreadyExistsException
* if a record already exists with the same attrs
*/
String create(ResourceRecord toCreate) throws ResourceAlreadyExistsException;
/**
* updates an existing resource record in the zone.
*
* @param guid
* the global unique identifier for the resource record {@see
* ResourceRecordMetadata#getGuid()}
* @param updated
* the record to update.
* @throws ResourceNotFoundException
* if the guid doesn't exist
*/
void update(String guid, ResourceRecord updated) throws ResourceNotFoundException;
/**
* Returns all the specified record types in the zone.
*
* @throws ResourceNotFoundException
* if the zone doesn't exist
*/
FluentIterable<ResourceRecordMetadata> list() throws ResourceNotFoundException;
/**
* Returns all the specified record types in the zone with the fully
* qualified {@link hostName}
*
* @param hostName
* fully qualified hostname including the trailing dot.
* @throws ResourceNotFoundException
* if the zone doesn't exist
*/
FluentIterable<ResourceRecordMetadata> listByName(String hostName) throws ResourceNotFoundException;
/**
* Returns all the specified record types in the zone with the fully
* qualified {@link hostName} and {@link rrType}
*
* @param hostName
* fully qualified hostname including the trailing dot.
* @param rrType
* type value (ex. for {@code A}, this is {@code 1}
*
* @throws ResourceNotFoundException
* if the zone doesn't exist
*/
FluentIterable<ResourceRecordMetadata> listByNameAndType(String hostName, UnsignedInteger rrType)
throws ResourceNotFoundException;
/**
* @see #listByNameAndType(String, UnsignedInteger)
*/
FluentIterable<ResourceRecordMetadata> listByNameAndType(String hostName, int rrType)
throws ResourceNotFoundException;
/**
* @param type
* the literal type defined in {@link ResourceTypeToValue}. ex
* {@code AAAA}
* @see #listByNameAndType(String, UnsignedInteger)
*/
FluentIterable<ResourceRecordMetadata> listByNameAndType(String hostName, String type)
throws ResourceNotFoundException;
/**
* deletes a specific resource record/
*
* @param guid
* the global unique identifier for the resource record {@see
* ResourceRecordMetadata#getGuid()}
*/
void delete(String guid);
}

View File

@ -0,0 +1,137 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.ultradns.ws.features;
import javax.inject.Named;
import javax.ws.rs.POST;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.Payload;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.ultradns.ws.ResourceTypeToValue;
import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException;
import org.jclouds.ultradns.ws.binders.ZoneAndResourceRecordToXML;
import org.jclouds.ultradns.ws.domain.ResourceRecord;
import org.jclouds.ultradns.ws.domain.ResourceRecordMetadata;
import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth;
import org.jclouds.ultradns.ws.xml.GuidHandler;
import org.jclouds.ultradns.ws.xml.ResourceRecordListHandler;
import com.google.common.collect.FluentIterable;
import com.google.common.primitives.UnsignedInteger;
import com.google.common.util.concurrent.ListenableFuture;
/**
* @see ResourceRecordApi
* @see <a href="https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01?wsdl" />
* @see <a href="https://www.ultradns.net/api/NUS_API_XML_SOAP.pdf" />
* @author Adrian Cole
*/
@RequestFilters(SOAPWrapWithPasswordAuth.class)
@VirtualHost
public interface ResourceRecordAsyncApi {
/**
* @see ResourceRecordApi#create(ResourceRecordMetadata)
*/
@Named("createResourceRecord")
@POST
@XMLResponseParser(GuidHandler.class)
@MapBinder(ZoneAndResourceRecordToXML.class)
ListenableFuture<String> create(@PayloadParam("resourceRecord") ResourceRecord toCreate)
throws ResourceAlreadyExistsException;
/**
* @see ResourceRecordApi#update(String guid, BasicResourceRecord)
*/
@Named("updateResourceRecord")
@POST
@MapBinder(ZoneAndResourceRecordToXML.class)
ListenableFuture<Void> update(@PayloadParam("guid") String guid,
@PayloadParam("resourceRecord") ResourceRecord toCreate) throws ResourceNotFoundException;
/**
* @see ResourceRecordApi#list()
*/
@Named("getResourceRecordsOfZone")
@POST
@XMLResponseParser(ResourceRecordListHandler.class)
@Payload("<v01:getResourceRecordsOfZone><zoneName>{zoneName}</zoneName><rrType>0</rrType></v01:getResourceRecordsOfZone>")
ListenableFuture<FluentIterable<ResourceRecord>> list() throws ResourceNotFoundException;
/**
* @see ResourceRecordApi#listByName(String)
*/
@Named("getResourceRecordsOfDNameByType")
@POST
@XMLResponseParser(ResourceRecordListHandler.class)
@Payload("<v01:getResourceRecordsOfDNameByType><zoneName>{zoneName}</zoneName><hostName>{hostName}</hostName><rrType>0</rrType></v01:getResourceRecordsOfDNameByType>")
ListenableFuture<FluentIterable<ResourceRecordMetadata>> listByName(@PayloadParam("hostName") String hostName)
throws ResourceNotFoundException;
/**
* @see ResourceRecordApi#listByNameAndType(String, UnsignedInteger)
*/
@Named("getResourceRecordsOfDNameByType")
@POST
@XMLResponseParser(ResourceRecordListHandler.class)
@Payload("<v01:getResourceRecordsOfDNameByType><zoneName>{zoneName}</zoneName><hostName>{hostName}</hostName><rrType>{rrType}</rrType></v01:getResourceRecordsOfDNameByType>")
ListenableFuture<FluentIterable<ResourceRecordMetadata>> listByNameAndType(
@PayloadParam("hostName") String hostName, @PayloadParam("rrType") UnsignedInteger rrType)
throws ResourceNotFoundException;
/**
* @see ResourceRecordApi#listByNameAndType(String, int)
*/
@Named("getResourceRecordsOfDNameByType")
@POST
@XMLResponseParser(ResourceRecordListHandler.class)
@Payload("<v01:getResourceRecordsOfDNameByType><zoneName>{zoneName}</zoneName><hostName>{hostName}</hostName><rrType>{rrType}</rrType></v01:getResourceRecordsOfDNameByType>")
ListenableFuture<FluentIterable<ResourceRecordMetadata>> listByNameAndType(
@PayloadParam("hostName") String hostName, @PayloadParam("rrType") int rrType)
throws ResourceNotFoundException;
/**
* @see ResourceRecordApi#listByNameAndType(String, String)
*/
@Named("getResourceRecordsOfDNameByType")
@POST
@XMLResponseParser(ResourceRecordListHandler.class)
@Payload("<v01:getResourceRecordsOfDNameByType><zoneName>{zoneName}</zoneName><hostName>{hostName}</hostName><rrType>{rrType}</rrType></v01:getResourceRecordsOfDNameByType>")
ListenableFuture<FluentIterable<ResourceRecordMetadata>> listByNameAndType(
@PayloadParam("hostName") String hostName,
@PayloadParam("rrType") @ParamParser(ResourceTypeToValue.class) String rrType)
throws ResourceNotFoundException;
/**
* @see ResourceRecordApi#delete(String)
*/
@Named("deleteResourceRecord")
@POST
@Payload("<v01:deleteResourceRecord><transactionID /><guid>{guid}</guid></v01:deleteResourceRecord>")
@Fallback(VoidOnNotFoundOr404.class)
ListenableFuture<Void> delete(@PayloadParam("guid") String guid);
}

View File

@ -78,9 +78,11 @@ public class UltraDNSWSErrorHandler implements HttpErrorHandler {
switch (exception.getError().getCode()) {
case 0:
case 1801:
case 2103:
case 2401:
return new ResourceNotFoundException(exception.getError().getDescription(), exception);
case 1802:
case 2111:
return new ResourceAlreadyExistsException(exception.getError().getDescription(), exception);
}
return exception;

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.ultradns.ws.xml;
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.ultradns.ws.domain.ResourceRecordMetadata;
import org.xml.sax.Attributes;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.inject.Inject;
/**
*
* @author Adrian Cole
*/
public class ResourceRecordListHandler extends
ParseSax.HandlerForGeneratedRequestWithResult<FluentIterable<ResourceRecordMetadata>> {
private final ResourceRecordMetadataHandler resourceRecordHandler;
private Builder<ResourceRecordMetadata> rrs = ImmutableSet.<ResourceRecordMetadata> builder();
@Inject
public ResourceRecordListHandler(ResourceRecordMetadataHandler resourceRecordHandler) {
this.resourceRecordHandler = resourceRecordHandler;
}
@Override
public FluentIterable<ResourceRecordMetadata> getResult() {
return FluentIterable.from(rrs.build());
}
@Override
public void startElement(String url, String name, String qName, Attributes attributes) {
resourceRecordHandler.startElement(url, name, qName, attributes);
}
@Override
public void endElement(String uri, String name, String qName) {
if (equalsOrSuffix(qName, "ResourceRecord")) {
rrs.add(resourceRecordHandler.getResult());
}
}
}

View File

@ -0,0 +1,77 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.ultradns.ws.xml;
import static org.jclouds.util.SaxUtils.cleanseAttributes;
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
import java.util.Map;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.ultradns.ws.domain.ResourceRecord;
import org.jclouds.ultradns.ws.domain.ResourceRecordMetadata;
import org.xml.sax.Attributes;
import com.google.common.primitives.UnsignedInteger;
import com.google.inject.Inject;
/**
*
* @author Adrian Cole
*/
public class ResourceRecordMetadataHandler extends
ParseSax.HandlerForGeneratedRequestWithResult<ResourceRecordMetadata> {
private final DateService dateService;
@Inject
private ResourceRecordMetadataHandler(DateService dateService) {
this.dateService = dateService;
}
private ResourceRecordMetadata.Builder rrm = ResourceRecordMetadata.builder();
private ResourceRecord.Builder rr = ResourceRecord.rrBuilder();
@Override
public ResourceRecordMetadata getResult() {
try {
return rrm.record(rr.build()).build();
} finally {
rrm = ResourceRecordMetadata.builder();
rr = ResourceRecord.rrBuilder();
}
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attrs) {
Map<String, String> attributes = cleanseAttributes(attrs);
if (equalsOrSuffix(qName, "ResourceRecord")) {
rrm.zoneId(attributes.get("ZoneId"));
rrm.guid(attributes.get("Guid"));
rrm.zoneName(attributes.get("ZoneName"));
rrm.created(dateService.iso8601DateParse(attributes.get("Created")));
rrm.modified(dateService.iso8601DateParse(attributes.get("Modified")));
rr.type(UnsignedInteger.valueOf(attributes.get("Type")));
rr.name(attributes.get("DName"));
rr.ttl(UnsignedInteger.valueOf(attributes.get("TTL")));
} else if (equalsOrSuffix(qName, "InfoValues")) {
rr.rdata(attributes.values());
}
}
}

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.ultradns.ws;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ResourceTypeToValueTest")
public class ResourceTypeToValueTest {
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "ResourceTypes do not include RRRR; types: \\[A, NS, CNAME, SOA, PTR, MX, TXT, AAAA, SRV\\]")
public void testNiceExceptionOnNotFound() {
new ResourceTypeToValue().apply("RRRR");
}
@Test(expectedExceptions = NullPointerException.class, expectedExceptionsMessageRegExp = "resource type was null")
public void testNiceExceptionOnNull() {
new ResourceTypeToValue().apply(null);
}
@Test
public void testNormalCase() {
assertEquals(new ResourceTypeToValue().apply("AAAA"), "28");
}
}

View File

@ -0,0 +1,54 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.ultradns.ws.binders;
import static org.testng.Assert.assertEquals;
import org.jclouds.ultradns.ws.domain.ResourceRecord;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ZoneAndResourceRecordToXMLTest")
public class ZoneAndResourceRecordToXMLTest {
String A = "<v01:createResourceRecord><transactionID /><resourceRecord ZoneName=\"jclouds.org.\" Type=\"1\" DName=\"www.jclouds.org.\" TTL=\"3600\"><InfoValues Info1Value=\"1.1.1.1\" /></resourceRecord></v01:createResourceRecord>";
public void testA() {
assertEquals(
ZoneAndResourceRecordToXML.toXML("jclouds.org.", ResourceRecord.rrBuilder().name("www.jclouds.org.")
.type(1).ttl(3600).rdata("1.1.1.1").build()), A);
}
String MX = "<v01:createResourceRecord><transactionID /><resourceRecord ZoneName=\"jclouds.org.\" Type=\"15\" DName=\"mail.jclouds.org.\" TTL=\"1800\"><InfoValues Info1Value=\"10\" Info2Value=\"maileast.jclouds.org.\" /></resourceRecord></v01:createResourceRecord>";
public void testMX() {
assertEquals(
ZoneAndResourceRecordToXML.toXML("jclouds.org.", ResourceRecord.rrBuilder().name("mail.jclouds.org.")
.type(15).ttl(1800).rdata(10).rdata("maileast.jclouds.org.").build()), MX);
}
String A_UPDATE = "<v01:updateResourceRecord><transactionID /><resourceRecord Guid=\"ABCDEF\" ZoneName=\"jclouds.org.\" Type=\"1\" DName=\"www.jclouds.org.\" TTL=\"3600\"><InfoValues Info1Value=\"1.1.1.1\" /></resourceRecord></v01:updateResourceRecord>";
public void testUpdate() {
assertEquals(ZoneAndResourceRecordToXML.update("ABCDEF", A), A_UPDATE);
}
}

View File

@ -0,0 +1,157 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.ultradns.ws.features;
import static org.jclouds.ultradns.ws.domain.ResourceRecord.rrBuilder;
import static org.testng.Assert.assertEquals;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.ultradns.ws.UltraDNSWSApi;
import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException;
import org.jclouds.ultradns.ws.domain.ResourceRecord;
import org.jclouds.ultradns.ws.internal.BaseUltraDNSWSApiExpectTest;
import org.jclouds.ultradns.ws.parse.GetResourceRecordsOfResourceRecordResponseTest;
import org.testng.annotations.Test;
import com.google.common.primitives.UnsignedInteger;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ResourceRecordApiExpectTest")
public class ResourceRecordApiExpectTest extends BaseUltraDNSWSApiExpectTest {
HttpRequest create = HttpRequest.builder().method("POST")
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443")
.payload(payloadFromResourceWithContentType("/create_rr.xml", "application/xml")).build();
HttpResponse createResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/rr_created.xml", "application/xml")).build();
ResourceRecord record = rrBuilder().name("mail.jclouds.org.").type("MX").ttl(1800).rdata(10)
.rdata("maileast.jclouds.org.").build();
public void testCreateWhenResponseIs2xx() {
UltraDNSWSApi success = requestSendsResponse(create, createResponse);
success.getResourceRecordApiForZone("jclouds.org.").create(record);
}
HttpResponse alreadyCreated = HttpResponse.builder().statusCode(500)
.payload(payloadFromResourceWithContentType("/rr_already_exists.xml", "application/xml")).build();
@Test(expectedExceptions = ResourceAlreadyExistsException.class, expectedExceptionsMessageRegExp = "Resource Record of type 15 with these attributes already exists in the system.")
public void testCreateWhenResponseError1802() {
UltraDNSWSApi already = requestSendsResponse(create, alreadyCreated);
already.getResourceRecordApiForZone("jclouds.org.").create(record);
}
HttpRequest update = HttpRequest.builder().method("POST")
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443")
.payload(payloadFromResourceWithContentType("/update_rr.xml", "application/xml")).build();
HttpResponse updateResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/rr_updated.xml", "application/xml")).build();
public void testUpdateWhenResponseIs2xx() {
UltraDNSWSApi success = requestSendsResponse(update, updateResponse);
success.getResourceRecordApiForZone("jclouds.org.").update("04053D8E57C7931F", record);
}
HttpRequest list = HttpRequest.builder().method("POST")
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443")
.payload(payloadFromResourceWithContentType("/list_records.xml", "application/xml")).build();
HttpResponse listResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/records.xml", "application/xml")).build();
public void testListWhenResponseIs2xx() {
UltraDNSWSApi success = requestSendsResponse(list, listResponse);
assertEquals(
success.getResourceRecordApiForZone("jclouds.org.").list().toString(),
new GetResourceRecordsOfResourceRecordResponseTest().expected().toString());
}
HttpResponse zoneDoesntExist = HttpResponse.builder().message("Server Error").statusCode(500)
.payload(payloadFromResource("/zone_doesnt_exist.xml")).build();
@Test(expectedExceptions = ResourceNotFoundException.class, expectedExceptionsMessageRegExp = "Zone does not exist in the system.")
public void testListWhenResponseError1801() {
UltraDNSWSApi notFound = requestSendsResponse(list, zoneDoesntExist);
notFound.getResourceRecordApiForZone("jclouds.org.").list();
}
HttpRequest listByName = HttpRequest.builder().method("POST")
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443")
.payload(payloadFromResourceWithContentType("/list_records_by_name.xml", "application/xml")).build();
public void testListByNameWhenResponseIs2xx() {
UltraDNSWSApi success = requestSendsResponse(listByName, listResponse);
assertEquals(
success.getResourceRecordApiForZone("jclouds.org.").listByName("www.jclouds.org.").toString(),
new GetResourceRecordsOfResourceRecordResponseTest().expected().toString());
}
HttpRequest listByNameAndType = HttpRequest.builder().method("POST")
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443")
.payload(payloadFromResourceWithContentType("/list_records_by_name_and_type.xml", "application/xml")).build();
public void testListByNameAndTypeWhenResponseIs2xx() {
UltraDNSWSApi success = requestSendsResponse(listByNameAndType, listResponse);
assertEquals(success.getResourceRecordApiForZone("jclouds.org.").listByNameAndType("www.jclouds.org.", 1)
.toString(), new GetResourceRecordsOfResourceRecordResponseTest().expected().toString());
assertEquals(
success.getResourceRecordApiForZone("jclouds.org.")
.listByNameAndType("www.jclouds.org.", UnsignedInteger.ONE).toString(),
new GetResourceRecordsOfResourceRecordResponseTest().expected().toString());
assertEquals(success.getResourceRecordApiForZone("jclouds.org.").listByNameAndType("www.jclouds.org.", "A")
.toString(), new GetResourceRecordsOfResourceRecordResponseTest().expected().toString());
}
HttpRequest delete = HttpRequest.builder().method("POST")
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443")
.payload(payloadFromResourceWithContentType("/delete_rr.xml", "application/xml")).build();
HttpResponse deleteResponse = HttpResponse.builder().statusCode(404)
.payload(payloadFromResourceWithContentType("/rr_deleted.xml", "application/xml")).build();
public void testDeleteWhenResponseIs2xx() {
UltraDNSWSApi success = requestSendsResponse(delete, deleteResponse);
success.getZoneApi().delete("04053D8E57C7931F");
}
HttpResponse rrDoesntExist = HttpResponse.builder().message("Server Error").statusCode(500)
.payload(payloadFromResource("/rr_doesnt_exist.xml")).build();
public void testDeleteWhenResponseRRNotFound() {
UltraDNSWSApi notFound = requestSendsResponse(delete, rrDoesntExist);
notFound.getZoneApi().delete("04053D8E57C7931F");
}
}

View File

@ -0,0 +1,198 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.ultradns.ws.features;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.equalTo;
import static java.util.logging.Logger.getAnonymousLogger;
import static org.jclouds.ultradns.ws.domain.ResourceRecord.rrBuilder;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicLong;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.ultradns.ws.ResourceTypeToValue;
import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException;
import org.jclouds.ultradns.ws.domain.Account;
import org.jclouds.ultradns.ws.domain.ResourceRecord;
import org.jclouds.ultradns.ws.domain.ResourceRecordMetadata;
import org.jclouds.ultradns.ws.domain.Zone;
import org.jclouds.ultradns.ws.internal.BaseUltraDNSWSApiLiveTest;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.BiMap;
import com.google.common.collect.FluentIterable;
import com.google.common.primitives.UnsignedInteger;
/**
* @author Adrian Cole
*/
@Test(groups = "live", singleThreaded = true, testName = "ResourceRecordApiLiveTest")
public class ResourceRecordApiLiveTest extends BaseUltraDNSWSApiLiveTest {
private String zoneName = System.getProperty("user.name").replace('.', '-') + ".rr.ultradnstest.jclouds.org.";
private Account account;
@Override
@BeforeClass(groups = { "integration", "live" })
public void setupContext() {
super.setupContext();
context.getApi().getZoneApi().delete(zoneName);
account = context.getApi().getCurrentAccount();
context.getApi().getZoneApi().createInAccount(zoneName, account.getId());
}
@Override
@AfterClass(groups = { "integration", "live" })
protected void tearDownContext() {
context.getApi().getZoneApi().delete(zoneName);
super.tearDownContext();
}
private void checkResourceRecord(ResourceRecord rr) {
checkNotNull(rr.getName(), "DName cannot be null for a ResourceRecord %s", rr);
checkNotNull(rr.getType(), "Type cannot be null for a ResourceRecord %s", rr);
assertTrue(rr.getType().intValue() > 0, "Type must be positive for a ResourceRecord " + rr);
checkNotNull(rr.getType(), "Type cannot be null for a ResourceRecord %s", rr);
checkNotNull(rr.getTTL(), "TTL cannot be null for a ResourceRecord %s", rr);
checkNotNull(rr.getRData(), "InfoValues cannot be null for a ResourceRecord %s", rr);
}
private void checkResourceRecordMetadata(ResourceRecordMetadata rr) {
checkNotNull(rr.getZoneId(), "ZoneId cannot be null for a ResourceRecordMetadata %s", rr);
checkNotNull(rr.getGuid(), "Guid cannot be null for a ResourceRecordMetadata %s", rr);
checkNotNull(rr.getZoneName(), "ZoneName cannot be null for a ResourceRecordMetadata %s", rr);
checkNotNull(rr.getCreated(), "Created cannot be null for a ResourceRecordMetadata %s", rr);
checkNotNull(rr.getModified(), "Modified cannot be null for a ResourceRecordMetadata %s", rr);
checkResourceRecord(rr.getRecord());
}
AtomicLong zones = new AtomicLong();
@Test
public void testListResourceRecords() {
for (Zone zone : context.getApi().getZoneApi().listByAccount(account.getId())) {
zones.incrementAndGet();
for (ResourceRecordMetadata rr : api(zone.getName()).list()) {
recordTypeCounts.getUnchecked(rr.getRecord().getType()).incrementAndGet();
checkResourceRecordMetadata(rr);
}
}
}
LoadingCache<UnsignedInteger, AtomicLong> recordTypeCounts = CacheBuilder.newBuilder().build(
new CacheLoader<UnsignedInteger, AtomicLong>() {
public AtomicLong load(UnsignedInteger key) throws Exception {
return new AtomicLong();
}
});
private final static BiMap<UnsignedInteger, String> valueToType = new ResourceTypeToValue().inverse();
@AfterClass
void logSummary() {
getAnonymousLogger().info("zoneCount: " + zones);
for (Entry<UnsignedInteger, AtomicLong> entry : recordTypeCounts.asMap().entrySet())
getAnonymousLogger().info(
String.format("type: %s, count: %s", valueToType.get(entry.getKey()), entry.getValue()));
}
@Test(expectedExceptions = ResourceNotFoundException.class, expectedExceptionsMessageRegExp = "Zone does not exist in the system.")
public void testListResourceRecordsWhenZoneIdNotFound() {
api("AAAAAAAAAAAAAAAA").list();
}
@Test(expectedExceptions = ResourceNotFoundException.class, expectedExceptionsMessageRegExp = "No Resource Record with GUID found in the system")
public void testUpdateWhenNotFound() {
api(zoneName).update("AAAAAAAAAAAAAAAA",
rrBuilder().name("mail." + zoneName).type("MX").ttl(1800).rdata(10).rdata("maileast.jclouds.org.").build());
}
@Test
public void testDeleteWhenNotFound() {
api(zoneName).delete("AAAAAAAAAAAAAAAA");
}
String guid;
ResourceRecord mx = rrBuilder().name("mail." + zoneName).type("MX").ttl(1800).rdata(10)
.rdata("maileast.jclouds.org.").build();
@Test
public void testCreateRecord() {
guid = api(zoneName).create(mx);
getAnonymousLogger().info("created record: " + guid);
try {
api(zoneName).create(mx);
fail();
} catch (ResourceAlreadyExistsException e) {
}
assertTrue(listRRs(mx).anyMatch(equalTo(mx)));
}
@Test(dependsOnMethods = "testCreateRecord")
public void testListResourceRecordsByName() {
FluentIterable<ResourceRecord> byName = api(zoneName).listByName(mx.getName()).transform(toRecord);
assertTrue(byName.anyMatch(equalTo(mx)));
}
@Test(dependsOnMethods = "testCreateRecord")
public void testListResourceRecordsByNameAndType() {
FluentIterable<ResourceRecord> byNameAndType = api(zoneName).listByNameAndType(mx.getName(), mx.getType())
.transform(toRecord);
assertTrue(byNameAndType.anyMatch(equalTo(mx)));
}
@Test(dependsOnMethods = { "testListResourceRecordsByName", "testListResourceRecordsByNameAndType" })
public void testUpdateRecord() {
mx = mx.toBuilder().ttl(3600).build();
api(zoneName).update(guid, mx);
assertTrue(listRRs(mx).anyMatch(equalTo(mx)));
}
@Test(dependsOnMethods = "testUpdateRecord")
public void testDeleteRecord() {
api(zoneName).delete(guid);
assertFalse(listRRs(mx).anyMatch(equalTo(mx)));
}
private Function<ResourceRecordMetadata, ResourceRecord> toRecord = new Function<ResourceRecordMetadata, ResourceRecord>() {
public ResourceRecord apply(ResourceRecordMetadata in) {
checkResourceRecordMetadata(in);
return in.getRecord();
}
};
private FluentIterable<ResourceRecord> listRRs(ResourceRecord mx) {
return api(zoneName).list().transform(toRecord);
}
private ResourceRecordApi api(String zoneName) {
return context.getApi().getResourceRecordApiForZone(zoneName);
}
}

View File

@ -41,7 +41,7 @@ import com.google.inject.Guice;
*
* @author Adrian Cole
*/
@Test(groups = "unit" )
@Test(groups = "unit")
public class UltraDNSWSErrorHandlerTest {
UltraDNSWSErrorHandler function = Guice.createInjector(new SaxParserModule()).getInstance(
UltraDNSWSErrorHandler.class);
@ -49,12 +49,11 @@ public class UltraDNSWSErrorHandlerTest {
@Test
public void testCode0SetsResourceNotFoundException() throws IOException {
HttpRequest request = HttpRequest.builder().method("POST")
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443")
.payload(payloadFromResource("/list_tasks.xml")).build();
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443").payload(payloadFromResource("/list_tasks.xml")).build();
HttpCommand command = new HttpCommand(request);
HttpResponse response = HttpResponse.builder().message("Server Error").statusCode(500)
.payload(payloadFromResource("/task_doesnt_exist.xml")).build();
.payload(payloadFromResource("/task_doesnt_exist.xml")).build();
function.handleError(command, response);
@ -71,12 +70,12 @@ public class UltraDNSWSErrorHandlerTest {
@Test
public void testCode2401SetsResourceNotFoundException() throws IOException {
HttpRequest request = HttpRequest.builder().method("POST")
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443")
.payload(payloadFromResource("/list_zones_by_account.xml")).build();
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443")
.payload(payloadFromResource("/list_zones_by_account.xml")).build();
HttpCommand command = new HttpCommand(request);
HttpResponse response = HttpResponse.builder().message("Server Error").statusCode(500)
.payload(payloadFromResource("/account_doesnt_exist.xml")).build();
.payload(payloadFromResource("/account_doesnt_exist.xml")).build();
function.handleError(command, response);
@ -93,12 +92,11 @@ public class UltraDNSWSErrorHandlerTest {
@Test
public void testCode1801SetsResourceNotFoundException() throws IOException {
HttpRequest request = HttpRequest.builder().method("POST")
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443")
.payload(payloadFromResource("/get_zone.xml")).build();
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443").payload(payloadFromResource("/get_zone.xml")).build();
HttpCommand command = new HttpCommand(request);
HttpResponse response = HttpResponse.builder().message("Server Error").statusCode(500)
.payload(payloadFromResource("/zone_doesnt_exist.xml")).build();
.payload(payloadFromResource("/zone_doesnt_exist.xml")).build();
function.handleError(command, response);
@ -113,14 +111,34 @@ public class UltraDNSWSErrorHandlerTest {
}
@Test
public void testCode1802SetsResourceAlreadyExistsException() throws IOException {
public void testCode2103SetsResourceNotFoundException() throws IOException {
HttpRequest request = HttpRequest.builder().method("POST")
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443")
.payload(payloadFromResource("/create_zone.xml")).build();
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443").payload(payloadFromResource("/delete_rr.xml")).build();
HttpCommand command = new HttpCommand(request);
HttpResponse response = HttpResponse.builder().message("Server Error").statusCode(500)
.payload(payloadFromResource("/zone_already_exists.xml")).build();
.payload(payloadFromResource("/rr_doesnt_exist.xml")).build();
function.handleError(command, response);
assertEquals(command.getException().getClass(), ResourceNotFoundException.class);
assertEquals(command.getException().getMessage(), "No Resource Record with GUID found in the system AAAAAAAAAAAAAAAA");
UltraDNSWSResponseException exception = UltraDNSWSResponseException.class.cast(command.getException().getCause());
assertEquals(exception.getMessage(), "Error 2103: No Resource Record with GUID found in the system AAAAAAAAAAAAAAAA");
assertEquals(exception.getError().getDescription(), "No Resource Record with GUID found in the system AAAAAAAAAAAAAAAA");
assertEquals(exception.getError().getCode(), 2103);
}
@Test
public void testCode1802SetsResourceAlreadyExistsException() throws IOException {
HttpRequest request = HttpRequest.builder().method("POST")
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443").payload(payloadFromResource("/create_zone.xml")).build();
HttpCommand command = new HttpCommand(request);
HttpResponse response = HttpResponse.builder().message("Server Error").statusCode(500)
.payload(payloadFromResource("/zone_already_exists.xml")).build();
function.handleError(command, response);
@ -134,6 +152,30 @@ public class UltraDNSWSErrorHandlerTest {
assertEquals(exception.getError().getCode(), 1802);
}
@Test
public void testCode2111SetsResourceAlreadyExistsException() throws IOException {
HttpRequest request = HttpRequest.builder().method("POST")
.endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01")
.addHeader("Host", "ultra-api.ultradns.com:8443").payload(payloadFromResource("/create_rr.xml")).build();
HttpCommand command = new HttpCommand(request);
HttpResponse response = HttpResponse.builder().message("Server Error").statusCode(500)
.payload(payloadFromResource("/rr_already_exists.xml")).build();
function.handleError(command, response);
assertEquals(command.getException().getClass(), ResourceAlreadyExistsException.class);
assertEquals(command.getException().getMessage(),
"Resource Record of type 15 with these attributes already exists in the system.");
UltraDNSWSResponseException exception = UltraDNSWSResponseException.class.cast(command.getException().getCause());
assertEquals(exception.getMessage(),
"Error 2111: Resource Record of type 15 with these attributes already exists in the system.");
assertEquals(exception.getError().getDescription(),
"Resource Record of type 15 with these attributes already exists in the system.");
assertEquals(exception.getError().getCode(), 2111);
}
private Payload payloadFromResource(String resource) {
try {
return payloadFromStringWithContentType(toStringAndClose(getClass().getResourceAsStream(resource)),

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.ultradns.ws.parse;
import static org.jclouds.ultradns.ws.domain.ResourceRecord.rrBuilder;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.ultradns.ws.domain.ResourceRecordMetadata;
import org.jclouds.ultradns.ws.xml.ResourceRecordListHandler;
import org.testng.annotations.Test;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
/**
* @author Adrian Cole
*/
@Test(testName = "GetResourceRecordsOfDNameByTypeResponseTest")
public class GetResourceRecordsOfDNameByTypeResponseTest extends BaseHandlerTest {
SimpleDateFormatDateService dateService = new SimpleDateFormatDateService();
@Test
public void test() {
InputStream is = getClass().getResourceAsStream("/records_by_name_and_type.xml");
FluentIterable<ResourceRecordMetadata> expected = expected();
ResourceRecordListHandler handler = injector.getInstance(ResourceRecordListHandler.class);
FluentIterable<ResourceRecordMetadata> result = factory.create(handler).parse(is);
assertEquals(result.toList().toString(), expected.toList().toString());
}
public FluentIterable<ResourceRecordMetadata> expected() {
ResourceRecordMetadata record = ResourceRecordMetadata.builder()
.zoneId("03053D8E57C7A22A")
.guid("04053D8E57C7A22F")
.zoneName("adrianc.rr.ultradnstest.jclouds.org.")
.created(dateService.iso8601DateParse("2013-02-22T08:22:48.000Z"))
.modified(dateService.iso8601DateParse("2013-02-22T08:22:49.000Z"))
.record(rrBuilder().type(6).name("adrianc.rr.ultradnstest.jclouds.org.").ttl(86400)
.rdata("pdns75.ultradns.com.")
.rdata("adrianc.netflix.com.")
.rdata("2013022200")
.rdata("86400")
.rdata("86400")
.rdata("86400")
.rdata("86400").build()).build();
return FluentIterable.from(ImmutableList.of(record));
}
}

View File

@ -0,0 +1,100 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.ultradns.ws.parse;
import static org.jclouds.ultradns.ws.domain.ResourceRecord.rrBuilder;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.ultradns.ws.domain.ResourceRecordMetadata;
import org.jclouds.ultradns.ws.domain.ResourceRecordMetadata.Builder;
import org.jclouds.ultradns.ws.xml.ResourceRecordListHandler;
import org.testng.annotations.Test;
import com.google.common.base.Splitter;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
/**
* @author Adrian Cole
*/
@Test(testName = "GetResourceRecordsOfResourceRecordResponseTest")
public class GetResourceRecordsOfResourceRecordResponseTest extends BaseHandlerTest {
SimpleDateFormatDateService dateService = new SimpleDateFormatDateService();
@Test
public void test() {
InputStream is = getClass().getResourceAsStream("/records.xml");
FluentIterable<ResourceRecordMetadata> expected = expected();
ResourceRecordListHandler handler = injector.getInstance(ResourceRecordListHandler.class);
FluentIterable<ResourceRecordMetadata> result = factory.create(handler).parse(is);
assertEquals(result.toList().toString(), expected.toList().toString());
}
public FluentIterable<ResourceRecordMetadata> expected() {
Builder builder = ResourceRecordMetadata.builder().zoneId("0000000000000001").zoneName("jclouds.org.");
ImmutableList<ResourceRecordMetadata> records = ImmutableList.<ResourceRecordMetadata> builder()
.add(builder.guid("04023A2507B6468F")
.created(dateService.iso8601DateParse("2010-10-02T16:57:16.000Z"))
.modified(dateService.iso8601DateParse("2011-09-27T23:49:21.000Z"))
.record(rrBuilder().type(1).name("www.jclouds.org.").ttl(3600).rdata("1.2.3.4")).build())
.add(builder.guid("0B0338C2023F7969")
.created(dateService.iso8601DateParse("2009-10-12T12:02:23.000Z"))
.modified(dateService.iso8601DateParse("2009-10-12T12:02:23.000Z"))
.record(rrBuilder().type(2).name("jclouds.org.").ttl(86400).rdata("pdns2.ultradns.net.")).build())
.add(builder.guid("0B0338C2023F7968")
.created(dateService.iso8601DateParse("2009-10-12T12:02:23.000Z"))
.modified(dateService.iso8601DateParse("2009-10-12T12:02:23.000Z"))
.record(rrBuilder().type(2).name("jclouds.org.").ttl(86400).rdata("pdns1.ultradns.net.")).build())
.add(builder.guid("0B0338C2023F796B")
.created(dateService.iso8601DateParse("2009-10-12T12:02:23.000Z"))
.modified(dateService.iso8601DateParse("2009-10-12T12:02:23.000Z"))
.record(rrBuilder().type(2).name("jclouds.org.").ttl(86400).rdata("pdns4.ultradns.org.")).build())
.add(builder.guid("0B0338C2023F7983")
.created(dateService.iso8601DateParse("2009-10-12T12:02:23.000Z"))
.modified(dateService.iso8601DateParse("2011-09-27T23:49:22.000Z"))
.record(rrBuilder().type(6).name("jclouds.org.").ttl(3600).rdata(Splitter.on(' ').split(
"pdns2.ultradns.net. admin.jclouds.org. 2011092701 10800 3600 604800 86400"))).build())
.add(builder.guid("0B0338C2023F796E")
.created(dateService.iso8601DateParse("2009-10-12T12:02:23.000Z"))
.modified(dateService.iso8601DateParse("2011-09-27T23:49:22.000Z"))
.record(rrBuilder().type(1).name("jclouds.org.").ttl(3600).rdata("1.2.3.4")).build())
.add(builder.guid("0B0338C2023F796C")
.created(dateService.iso8601DateParse("2009-10-12T12:02:23.000Z"))
.modified(dateService.iso8601DateParse("2009-10-12T12:02:23.000Z"))
.record(rrBuilder().type(2).name("jclouds.org.").ttl(86400).rdata("pdns5.ultradns.info.")).build())
.add(builder.guid("0B0338C2023F796D")
.created(dateService.iso8601DateParse("2009-10-12T12:02:23.000Z"))
.modified(dateService.iso8601DateParse("2009-10-12T12:02:23.000Z"))
.record(rrBuilder().type(2).name("jclouds.org.").ttl(86400).rdata("pdns6.ultradns.co.uk.")).build())
.add(builder.guid("0B0338C2023F796A")
.created(dateService.iso8601DateParse("2009-10-12T12:02:23.000Z"))
.modified(dateService.iso8601DateParse("2009-10-12T12:02:23.000Z"))
.record(rrBuilder().type(2).name("jclouds.org.").ttl(86400).rdata("pdns3.ultradns.org.")).build())
.build();
return FluentIterable.from(records);
}
}

View File

@ -0,0 +1 @@
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v01="http://webservice.api.ultra.neustar.com/v01/"><soapenv:Header><wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsse:UsernameToken><wsse:Username>identity</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">credential</wsse:Password></wsse:UsernameToken></wsse:Security></soapenv:Header><soapenv:Body><v01:createResourceRecord><transactionID /><resourceRecord ZoneName="jclouds.org." Type="15" DName="mail.jclouds.org." TTL="1800"><InfoValues Info1Value="10" Info2Value="maileast.jclouds.org." /></resourceRecord></v01:createResourceRecord></soapenv:Body></soapenv:Envelope>

View File

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

View File

@ -0,0 +1 @@
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v01="http://webservice.api.ultra.neustar.com/v01/"><soapenv:Header><wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsse:UsernameToken><wsse:Username>identity</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">credential</wsse:Password></wsse:UsernameToken></wsse:Security></soapenv:Header><soapenv:Body><v01:getResourceRecordsOfZone><zoneName>jclouds.org.</zoneName><rrType>0</rrType></v01:getResourceRecordsOfZone></soapenv:Body></soapenv:Envelope>

View File

@ -0,0 +1 @@
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v01="http://webservice.api.ultra.neustar.com/v01/"><soapenv:Header><wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsse:UsernameToken><wsse:Username>identity</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">credential</wsse:Password></wsse:UsernameToken></wsse:Security></soapenv:Header><soapenv:Body><v01:getResourceRecordsOfDNameByType><zoneName>jclouds.org.</zoneName><hostName>www.jclouds.org.</hostName><rrType>0</rrType></v01:getResourceRecordsOfDNameByType></soapenv:Body></soapenv:Envelope>

View File

@ -0,0 +1 @@
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v01="http://webservice.api.ultra.neustar.com/v01/"><soapenv:Header><wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsse:UsernameToken><wsse:Username>identity</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">credential</wsse:Password></wsse:UsernameToken></wsse:Security></soapenv:Header><soapenv:Body><v01:getResourceRecordsOfDNameByType><zoneName>jclouds.org.</zoneName><hostName>www.jclouds.org.</hostName><rrType>1</rrType></v01:getResourceRecordsOfDNameByType></soapenv:Body></soapenv:Envelope>

View File

@ -0,0 +1,36 @@
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:getResourceRecordsOfZoneResponse xmlns:ns1="http://webservice.api.ultra.neustar.com/v01/">
<ResourceRecordList xmlns:ns2="http://schema.ultraservice.neustar.com/v01/">
<ns2:ResourceRecord ZoneName="jclouds.org." Type="1" DName="www.jclouds.org." TTL="3600" Guid="04023A2507B6468F" ZoneId="0000000000000001" LName="www.jclouds.org." Created="2010-10-02T16:57:16.000Z" Modified="2011-09-27T23:49:21.000Z">
<ns2:InfoValues Info1Value="1.2.3.4"/>
</ns2:ResourceRecord>
<ns2:ResourceRecord ZoneName="jclouds.org." Type="2" DName="jclouds.org." TTL="86400" Guid="0B0338C2023F7969" ZoneId="0000000000000001" LName="jclouds.org." Created="2009-10-12T12:02:23.000Z" Modified="2009-10-12T12:02:23.000Z">
<ns2:InfoValues Info1Value="pdns2.ultradns.net."/>
</ns2:ResourceRecord>
<ns2:ResourceRecord ZoneName="jclouds.org." Type="2" DName="jclouds.org." TTL="86400" Guid="0B0338C2023F7968" ZoneId="0000000000000001" LName="jclouds.org." Created="2009-10-12T12:02:23.000Z" Modified="2009-10-12T12:02:23.000Z">
<ns2:InfoValues Info1Value="pdns1.ultradns.net."/>
</ns2:ResourceRecord>
<ns2:ResourceRecord ZoneName="jclouds.org." Type="2" DName="jclouds.org." TTL="86400" Guid="0B0338C2023F796B" ZoneId="0000000000000001" LName="jclouds.org." Created="2009-10-12T12:02:23.000Z" Modified="2009-10-12T12:02:23.000Z">
<ns2:InfoValues Info1Value="pdns4.ultradns.org."/>
</ns2:ResourceRecord>
<ns2:ResourceRecord ZoneName="jclouds.org." Type="6" DName="jclouds.org." TTL="3600" Guid="0B0338C2023F7983" ZoneId="0000000000000001" LName="jclouds.org." Created="2009-10-12T12:02:23.000Z" Modified="2011-09-27T23:49:22.000Z">
<ns2:InfoValues Info1Value="pdns2.ultradns.net." Info2Value="admin.jclouds.org." Info3Value="2011092701" Info4Value="10800" Info5Value="3600" Info6Value="604800" Info7Value="86400"/>
</ns2:ResourceRecord>
<ns2:ResourceRecord ZoneName="jclouds.org." Type="1" DName="jclouds.org." TTL="3600" Guid="0B0338C2023F796E" ZoneId="0000000000000001" LName="jclouds.org." Created="2009-10-12T12:02:23.000Z" Modified="2011-09-27T23:49:22.000Z">
<ns2:InfoValues Info1Value="1.2.3.4"/>
</ns2:ResourceRecord>
<ns2:ResourceRecord ZoneName="jclouds.org." Type="2" DName="jclouds.org." TTL="86400" Guid="0B0338C2023F796C" ZoneId="0000000000000001" LName="jclouds.org." Created="2009-10-12T12:02:23.000Z" Modified="2009-10-12T12:02:23.000Z">
<ns2:InfoValues Info1Value="pdns5.ultradns.info."/>
</ns2:ResourceRecord>
<ns2:ResourceRecord ZoneName="jclouds.org." Type="2" DName="jclouds.org." TTL="86400" Guid="0B0338C2023F796D" ZoneId="0000000000000001" LName="jclouds.org." Created="2009-10-12T12:02:23.000Z" Modified="2009-10-12T12:02:23.000Z">
<ns2:InfoValues Info1Value="pdns6.ultradns.co.uk."/>
</ns2:ResourceRecord>
<ns2:ResourceRecord ZoneName="jclouds.org." Type="2" DName="jclouds.org." TTL="86400" Guid="0B0338C2023F796A" ZoneId="0000000000000001" LName="jclouds.org." Created="2009-10-12T12:02:23.000Z" Modified="2009-10-12T12:02:23.000Z">
<ns2:InfoValues Info1Value="pdns3.ultradns.org."/>
</ns2:ResourceRecord>
</ResourceRecordList>
</ns1:getResourceRecordsOfZoneResponse>
</soap:Body>
</soap:Envelope>

View File

@ -0,0 +1 @@
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:getResourceRecordsOfDNameByTypeResponse xmlns:ns1="http://webservice.api.ultra.neustar.com/v01/"><ResourceRecordList xmlns:ns2="http://schema.ultraservice.neustar.com/v01/"><ns2:ResourceRecord ZoneName="adrianc.rr.ultradnstest.jclouds.org." Type="6" DName="adrianc.rr.ultradnstest.jclouds.org." TTL="86400" Guid="04053D8E57C7A22F" ZoneId="03053D8E57C7A22A" LName="adrianc.rr.ultradnstest.jclouds.org." Created="2013-02-22T08:22:48.000Z" Modified="2013-02-22T08:22:49.000Z"><ns2:InfoValues Info1Value="pdns75.ultradns.com." Info2Value="adrianc.netflix.com." Info3Value="2013022200" Info4Value="86400" Info5Value="86400" Info6Value="86400" Info7Value="86400"/></ns2:ResourceRecord></ResourceRecordList></ns1:getResourceRecordsOfDNameByTypeResponse></soap:Body></soap:Envelope>

View File

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

View File

@ -0,0 +1 @@
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v01="http://webservice.api.ultra.neustar.com/v01/"><soapenv:Header><wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsse:UsernameToken><wsse:Username>identity</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">credential</wsse:Password></wsse:UsernameToken></wsse:Security></soapenv:Header><soapenv:Body><v01:createResourceRecord><transactionID /><resourceRecord ZoneName="jclouds.org." Type="15" DName="mail.jclouds.org." TTL="1800"><InfoValues Info1Value="10" Info2Value="maileast.jclouds.org." /></resourceRecord></v01:createResourceRecord></soapenv:Body></soapenv:Envelope>

View File

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

View File

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

View File

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

View File

@ -0,0 +1 @@
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v01="http://webservice.api.ultra.neustar.com/v01/"><soapenv:Header><wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsse:UsernameToken><wsse:Username>identity</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">credential</wsse:Password></wsse:UsernameToken></wsse:Security></soapenv:Header><soapenv:Body><v01:updateResourceRecord><transactionID /><resourceRecord Guid="04053D8E57C7931F" ZoneName="jclouds.org." Type="15" DName="mail.jclouds.org." TTL="1800"><InfoValues Info1Value="10" Info2Value="maileast.jclouds.org." /></resourceRecord></v01:updateResourceRecord></soapenv:Body></soapenv:Envelope>