From 21f3409c47c1db9dad8ac0b57fd48cdbe29c413d Mon Sep 17 00:00:00 2001 From: adriancole Date: Fri, 22 Feb 2013 01:04:25 -0800 Subject: [PATCH] ultradns rr crud --- .../ultradns/ws/ResourceTypeToValue.java | 161 ++++++++++++++ .../jclouds/ultradns/ws/UltraDNSWSApi.java | 11 + .../ultradns/ws/UltraDNSWSAsyncApi.java | 11 + .../binders/ZoneAndResourceRecordToXML.java | 72 +++++++ .../ws/config/UltraDNSWSRestClientModule.java | 3 + .../ultradns/ws/domain/ResourceRecord.java | 189 +++++++++++++++++ .../ws/domain/ResourceRecordMetadata.java | 181 ++++++++++++++++ .../ws/features/ResourceRecordApi.java | 117 +++++++++++ .../ws/features/ResourceRecordAsyncApi.java | 137 ++++++++++++ .../ws/handlers/UltraDNSWSErrorHandler.java | 2 + .../ws/xml/ResourceRecordListHandler.java | 64 ++++++ .../ws/xml/ResourceRecordMetadataHandler.java | 77 +++++++ .../ultradns/ws/ResourceTypeToValueTest.java | 46 ++++ .../ZoneAndResourceRecordToXMLTest.java | 54 +++++ .../features/ResourceRecordApiExpectTest.java | 157 ++++++++++++++ .../features/ResourceRecordApiLiveTest.java | 198 ++++++++++++++++++ .../handlers/UltraDNSWSErrorHandlerTest.java | 78 +++++-- ...ourceRecordsOfDNameByTypeResponseTest.java | 71 +++++++ ...ceRecordsOfResourceRecordResponseTest.java | 100 +++++++++ .../src/test/resources/create_rr.xml | 1 + .../src/test/resources/delete_rr.xml | 1 + .../src/test/resources/list_records.xml | 1 + .../test/resources/list_records_by_name.xml | 1 + .../list_records_by_name_and_type.xml | 1 + .../src/test/resources/records.xml | 36 ++++ .../resources/records_by_name_and_type.xml | 1 + .../src/test/resources/rr_already_exists.xml | 1 + .../src/test/resources/rr_created.xml | 1 + .../src/test/resources/rr_deleted.xml | 1 + .../src/test/resources/rr_doesnt_exist.xml | 1 + .../src/test/resources/rr_updated.xml | 1 + .../src/test/resources/update_rr.xml | 1 + 32 files changed, 1759 insertions(+), 18 deletions(-) create mode 100644 labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/ResourceTypeToValue.java create mode 100644 labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/binders/ZoneAndResourceRecordToXML.java create mode 100644 labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ResourceRecord.java create mode 100644 labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ResourceRecordMetadata.java create mode 100644 labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordApi.java create mode 100644 labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordAsyncApi.java create mode 100644 labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/ResourceRecordListHandler.java create mode 100644 labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/ResourceRecordMetadataHandler.java create mode 100644 labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/ResourceTypeToValueTest.java create mode 100644 labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/binders/ZoneAndResourceRecordToXMLTest.java create mode 100644 labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiExpectTest.java create mode 100644 labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiLiveTest.java create mode 100644 labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/GetResourceRecordsOfDNameByTypeResponseTest.java create mode 100644 labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/GetResourceRecordsOfResourceRecordResponseTest.java create mode 100644 labs/ultradns-ws/src/test/resources/create_rr.xml create mode 100644 labs/ultradns-ws/src/test/resources/delete_rr.xml create mode 100644 labs/ultradns-ws/src/test/resources/list_records.xml create mode 100644 labs/ultradns-ws/src/test/resources/list_records_by_name.xml create mode 100644 labs/ultradns-ws/src/test/resources/list_records_by_name_and_type.xml create mode 100644 labs/ultradns-ws/src/test/resources/records.xml create mode 100644 labs/ultradns-ws/src/test/resources/records_by_name_and_type.xml create mode 100644 labs/ultradns-ws/src/test/resources/rr_already_exists.xml create mode 100644 labs/ultradns-ws/src/test/resources/rr_created.xml create mode 100644 labs/ultradns-ws/src/test/resources/rr_deleted.xml create mode 100644 labs/ultradns-ws/src/test/resources/rr_doesnt_exist.xml create mode 100644 labs/ultradns-ws/src/test/resources/rr_updated.xml create mode 100644 labs/ultradns-ws/src/test/resources/update_rr.xml diff --git a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/ResourceTypeToValue.java b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/ResourceTypeToValue.java new file mode 100644 index 0000000000..f3e76d3ae1 --- /dev/null +++ b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/ResourceTypeToValue.java @@ -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 implements Function, + BiMap { + + /** + * 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 iana types. + * + */ + // 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 delegate() { + return lookup; + } + + private static final ImmutableBiMap lookup; + + static { + ImmutableBiMap.Builder 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 values() { + return lookup.values(); + } + + @Override + public BiMap inverse() { + return lookup.inverse(); + } + + @Override + public String apply(Object input) { + return lookup(checkNotNull(input, "resource type was null").toString()).toString(); + } +} diff --git a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApi.java b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApi.java index 4af45e9542..ed94b5d851 100644 --- a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApi.java +++ b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApi.java @@ -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. */ diff --git a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSAsyncApi.java b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSAsyncApi.java index 0d7c0c5076..dc0b9bf655 100644 --- a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSAsyncApi.java +++ b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSAsyncApi.java @@ -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. */ diff --git a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/binders/ZoneAndResourceRecordToXML.java b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/binders/ZoneAndResourceRecordToXML.java new file mode 100644 index 0000000000..b59ef7a6ea --- /dev/null +++ b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/binders/ZoneAndResourceRecordToXML.java @@ -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 = "%s"; + + @SuppressWarnings("unchecked") + @Override + public R bindToRequest(R request, Map 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(""); + 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(" R bindToRequest(R request, Object input) { + throw new UnsupportedOperationException("use map form"); + } +} \ No newline at end of file diff --git a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/config/UltraDNSWSRestClientModule.java b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/config/UltraDNSWSRestClientModule.java index 19d7bb3aac..04664db99e 100644 --- a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/config/UltraDNSWSRestClientModule.java +++ b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/config/UltraDNSWSRestClientModule.java @@ -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, Class> DELEGATE_MAP = ImmutableMap., Class> builder() .put(ZoneApi.class, ZoneAsyncApi.class) + .put(ResourceRecordApi.class, ResourceRecordAsyncApi.class) .put(TaskApi.class, TaskAsyncApi.class).build(); public UltraDNSWSRestClientModule() { diff --git a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ResourceRecord.java b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ResourceRecord.java new file mode 100644 index 0000000000..005d002d71 --- /dev/null +++ b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ResourceRecord.java @@ -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 infoValues; + + private ResourceRecord(String dName, UnsignedInteger type, UnsignedInteger ttl, List 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 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 infoValues = ImmutableList. 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()); + } + } +} diff --git a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ResourceRecordMetadata.java b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ResourceRecordMetadata.java new file mode 100644 index 0000000000..af9bf39b6e --- /dev/null +++ b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ResourceRecordMetadata.java @@ -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); + } + } +} diff --git a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordApi.java b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordApi.java new file mode 100644 index 0000000000..14de0435be --- /dev/null +++ b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordApi.java @@ -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 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 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 listByNameAndType(String hostName, UnsignedInteger rrType) + throws ResourceNotFoundException; + + /** + * @see #listByNameAndType(String, UnsignedInteger) + */ + FluentIterable listByNameAndType(String hostName, int rrType) + throws ResourceNotFoundException; + + /** + * @param type + * the literal type defined in {@link ResourceTypeToValue}. ex + * {@code AAAA} + * @see #listByNameAndType(String, UnsignedInteger) + */ + FluentIterable 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); +} diff --git a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordAsyncApi.java b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordAsyncApi.java new file mode 100644 index 0000000000..fac2b181c9 --- /dev/null +++ b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordAsyncApi.java @@ -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 + * @see + * @author Adrian Cole + */ +@RequestFilters(SOAPWrapWithPasswordAuth.class) +@VirtualHost +public interface ResourceRecordAsyncApi { + + /** + * @see ResourceRecordApi#create(ResourceRecordMetadata) + */ + @Named("createResourceRecord") + @POST + @XMLResponseParser(GuidHandler.class) + @MapBinder(ZoneAndResourceRecordToXML.class) + ListenableFuture create(@PayloadParam("resourceRecord") ResourceRecord toCreate) + throws ResourceAlreadyExistsException; + + /** + * @see ResourceRecordApi#update(String guid, BasicResourceRecord) + */ + @Named("updateResourceRecord") + @POST + @MapBinder(ZoneAndResourceRecordToXML.class) + ListenableFuture update(@PayloadParam("guid") String guid, + @PayloadParam("resourceRecord") ResourceRecord toCreate) throws ResourceNotFoundException; + + /** + * @see ResourceRecordApi#list() + */ + @Named("getResourceRecordsOfZone") + @POST + @XMLResponseParser(ResourceRecordListHandler.class) + @Payload("{zoneName}0") + ListenableFuture> list() throws ResourceNotFoundException; + + /** + * @see ResourceRecordApi#listByName(String) + */ + @Named("getResourceRecordsOfDNameByType") + @POST + @XMLResponseParser(ResourceRecordListHandler.class) + @Payload("{zoneName}{hostName}0") + ListenableFuture> listByName(@PayloadParam("hostName") String hostName) + throws ResourceNotFoundException; + + /** + * @see ResourceRecordApi#listByNameAndType(String, UnsignedInteger) + */ + @Named("getResourceRecordsOfDNameByType") + @POST + @XMLResponseParser(ResourceRecordListHandler.class) + @Payload("{zoneName}{hostName}{rrType}") + ListenableFuture> listByNameAndType( + @PayloadParam("hostName") String hostName, @PayloadParam("rrType") UnsignedInteger rrType) + throws ResourceNotFoundException; + + /** + * @see ResourceRecordApi#listByNameAndType(String, int) + */ + @Named("getResourceRecordsOfDNameByType") + @POST + @XMLResponseParser(ResourceRecordListHandler.class) + @Payload("{zoneName}{hostName}{rrType}") + ListenableFuture> listByNameAndType( + @PayloadParam("hostName") String hostName, @PayloadParam("rrType") int rrType) + throws ResourceNotFoundException; + + /** + * @see ResourceRecordApi#listByNameAndType(String, String) + */ + @Named("getResourceRecordsOfDNameByType") + @POST + @XMLResponseParser(ResourceRecordListHandler.class) + @Payload("{zoneName}{hostName}{rrType}") + ListenableFuture> listByNameAndType( + @PayloadParam("hostName") String hostName, + @PayloadParam("rrType") @ParamParser(ResourceTypeToValue.class) String rrType) + throws ResourceNotFoundException; + + /** + * @see ResourceRecordApi#delete(String) + */ + @Named("deleteResourceRecord") + @POST + @Payload("{guid}") + @Fallback(VoidOnNotFoundOr404.class) + ListenableFuture delete(@PayloadParam("guid") String guid); +} diff --git a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandler.java b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandler.java index ab56bad5c3..3e3cd7c675 100644 --- a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandler.java +++ b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandler.java @@ -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; diff --git a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/ResourceRecordListHandler.java b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/ResourceRecordListHandler.java new file mode 100644 index 0000000000..19652b6eb2 --- /dev/null +++ b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/ResourceRecordListHandler.java @@ -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> { + + private final ResourceRecordMetadataHandler resourceRecordHandler; + + private Builder rrs = ImmutableSet. builder(); + + @Inject + public ResourceRecordListHandler(ResourceRecordMetadataHandler resourceRecordHandler) { + this.resourceRecordHandler = resourceRecordHandler; + } + + @Override + public FluentIterable 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()); + } + } +} diff --git a/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/ResourceRecordMetadataHandler.java b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/ResourceRecordMetadataHandler.java new file mode 100644 index 0000000000..17265f2a56 --- /dev/null +++ b/labs/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/ResourceRecordMetadataHandler.java @@ -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 { + 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 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()); + } + } +} diff --git a/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/ResourceTypeToValueTest.java b/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/ResourceTypeToValueTest.java new file mode 100644 index 0000000000..e9f86d62be --- /dev/null +++ b/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/ResourceTypeToValueTest.java @@ -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"); + } +} diff --git a/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/binders/ZoneAndResourceRecordToXMLTest.java b/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/binders/ZoneAndResourceRecordToXMLTest.java new file mode 100644 index 0000000000..bc1f2271bf --- /dev/null +++ b/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/binders/ZoneAndResourceRecordToXMLTest.java @@ -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 = ""; + + 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 = ""; + + 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 = ""; + + public void testUpdate() { + assertEquals(ZoneAndResourceRecordToXML.update("ABCDEF", A), A_UPDATE); + } +} diff --git a/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiExpectTest.java b/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiExpectTest.java new file mode 100644 index 0000000000..2356f04afa --- /dev/null +++ b/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiExpectTest.java @@ -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"); + } +} diff --git a/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiLiveTest.java b/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiLiveTest.java new file mode 100644 index 0000000000..73f48733f4 --- /dev/null +++ b/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiLiveTest.java @@ -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 recordTypeCounts = CacheBuilder.newBuilder().build( + new CacheLoader() { + public AtomicLong load(UnsignedInteger key) throws Exception { + return new AtomicLong(); + } + }); + + private final static BiMap valueToType = new ResourceTypeToValue().inverse(); + + @AfterClass + void logSummary() { + getAnonymousLogger().info("zoneCount: " + zones); + for (Entry 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 byName = api(zoneName).listByName(mx.getName()).transform(toRecord); + assertTrue(byName.anyMatch(equalTo(mx))); + } + + @Test(dependsOnMethods = "testCreateRecord") + public void testListResourceRecordsByNameAndType() { + FluentIterable 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 toRecord = new Function() { + public ResourceRecord apply(ResourceRecordMetadata in) { + checkResourceRecordMetadata(in); + return in.getRecord(); + } + }; + + private FluentIterable listRRs(ResourceRecord mx) { + return api(zoneName).list().transform(toRecord); + } + + private ResourceRecordApi api(String zoneName) { + return context.getApi().getResourceRecordApiForZone(zoneName); + } +} diff --git a/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandlerTest.java b/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandlerTest.java index c84c7b279c..95ef12c03d 100644 --- a/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandlerTest.java +++ b/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/handlers/UltraDNSWSErrorHandlerTest.java @@ -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)), diff --git a/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/GetResourceRecordsOfDNameByTypeResponseTest.java b/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/GetResourceRecordsOfDNameByTypeResponseTest.java new file mode 100644 index 0000000000..7a04f66188 --- /dev/null +++ b/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/GetResourceRecordsOfDNameByTypeResponseTest.java @@ -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 expected = expected(); + + ResourceRecordListHandler handler = injector.getInstance(ResourceRecordListHandler.class); + FluentIterable result = factory.create(handler).parse(is); + + assertEquals(result.toList().toString(), expected.toList().toString()); + } + + public FluentIterable 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)); + } +} diff --git a/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/GetResourceRecordsOfResourceRecordResponseTest.java b/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/GetResourceRecordsOfResourceRecordResponseTest.java new file mode 100644 index 0000000000..6cd64d24a1 --- /dev/null +++ b/labs/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/GetResourceRecordsOfResourceRecordResponseTest.java @@ -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 expected = expected(); + + ResourceRecordListHandler handler = injector.getInstance(ResourceRecordListHandler.class); + FluentIterable result = factory.create(handler).parse(is); + + assertEquals(result.toList().toString(), expected.toList().toString()); + } + + public FluentIterable expected() { + Builder builder = ResourceRecordMetadata.builder().zoneId("0000000000000001").zoneName("jclouds.org."); + ImmutableList records = ImmutableList. 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); + } + +} diff --git a/labs/ultradns-ws/src/test/resources/create_rr.xml b/labs/ultradns-ws/src/test/resources/create_rr.xml new file mode 100644 index 0000000000..573734d90c --- /dev/null +++ b/labs/ultradns-ws/src/test/resources/create_rr.xml @@ -0,0 +1 @@ +identitycredential \ No newline at end of file diff --git a/labs/ultradns-ws/src/test/resources/delete_rr.xml b/labs/ultradns-ws/src/test/resources/delete_rr.xml new file mode 100644 index 0000000000..133805f818 --- /dev/null +++ b/labs/ultradns-ws/src/test/resources/delete_rr.xml @@ -0,0 +1 @@ +identitycredential04053D8E57C7931F \ No newline at end of file diff --git a/labs/ultradns-ws/src/test/resources/list_records.xml b/labs/ultradns-ws/src/test/resources/list_records.xml new file mode 100644 index 0000000000..6560f7bf21 --- /dev/null +++ b/labs/ultradns-ws/src/test/resources/list_records.xml @@ -0,0 +1 @@ +identitycredentialjclouds.org.0 \ No newline at end of file diff --git a/labs/ultradns-ws/src/test/resources/list_records_by_name.xml b/labs/ultradns-ws/src/test/resources/list_records_by_name.xml new file mode 100644 index 0000000000..85155b6f2a --- /dev/null +++ b/labs/ultradns-ws/src/test/resources/list_records_by_name.xml @@ -0,0 +1 @@ +identitycredentialjclouds.org.www.jclouds.org.0 \ No newline at end of file diff --git a/labs/ultradns-ws/src/test/resources/list_records_by_name_and_type.xml b/labs/ultradns-ws/src/test/resources/list_records_by_name_and_type.xml new file mode 100644 index 0000000000..c751b354f3 --- /dev/null +++ b/labs/ultradns-ws/src/test/resources/list_records_by_name_and_type.xml @@ -0,0 +1 @@ +identitycredentialjclouds.org.www.jclouds.org.1 \ No newline at end of file diff --git a/labs/ultradns-ws/src/test/resources/records.xml b/labs/ultradns-ws/src/test/resources/records.xml new file mode 100644 index 0000000000..a79e3d9e83 --- /dev/null +++ b/labs/ultradns-ws/src/test/resources/records.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/ultradns-ws/src/test/resources/records_by_name_and_type.xml b/labs/ultradns-ws/src/test/resources/records_by_name_and_type.xml new file mode 100644 index 0000000000..a128e81aad --- /dev/null +++ b/labs/ultradns-ws/src/test/resources/records_by_name_and_type.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/labs/ultradns-ws/src/test/resources/rr_already_exists.xml b/labs/ultradns-ws/src/test/resources/rr_already_exists.xml new file mode 100644 index 0000000000..e976cdc05b --- /dev/null +++ b/labs/ultradns-ws/src/test/resources/rr_already_exists.xml @@ -0,0 +1 @@ +soap:ServerFault occurred while processing.2111Resource Record of type 15 with these attributes already exists in the system. \ No newline at end of file diff --git a/labs/ultradns-ws/src/test/resources/rr_created.xml b/labs/ultradns-ws/src/test/resources/rr_created.xml new file mode 100644 index 0000000000..573734d90c --- /dev/null +++ b/labs/ultradns-ws/src/test/resources/rr_created.xml @@ -0,0 +1 @@ +identitycredential \ No newline at end of file diff --git a/labs/ultradns-ws/src/test/resources/rr_deleted.xml b/labs/ultradns-ws/src/test/resources/rr_deleted.xml new file mode 100644 index 0000000000..b6d0bd3d0e --- /dev/null +++ b/labs/ultradns-ws/src/test/resources/rr_deleted.xml @@ -0,0 +1 @@ +Successful \ No newline at end of file diff --git a/labs/ultradns-ws/src/test/resources/rr_doesnt_exist.xml b/labs/ultradns-ws/src/test/resources/rr_doesnt_exist.xml new file mode 100644 index 0000000000..6550a2a982 --- /dev/null +++ b/labs/ultradns-ws/src/test/resources/rr_doesnt_exist.xml @@ -0,0 +1 @@ +soap:ServerFault occurred while processing.2103No Resource Record with GUID found in the system AAAAAAAAAAAAAAAA \ No newline at end of file diff --git a/labs/ultradns-ws/src/test/resources/rr_updated.xml b/labs/ultradns-ws/src/test/resources/rr_updated.xml new file mode 100644 index 0000000000..3748e5f94a --- /dev/null +++ b/labs/ultradns-ws/src/test/resources/rr_updated.xml @@ -0,0 +1 @@ +Successful \ No newline at end of file diff --git a/labs/ultradns-ws/src/test/resources/update_rr.xml b/labs/ultradns-ws/src/test/resources/update_rr.xml new file mode 100644 index 0000000000..dfe08e6fda --- /dev/null +++ b/labs/ultradns-ws/src/test/resources/update_rr.xml @@ -0,0 +1 @@ +identitycredential \ No newline at end of file