mirror of https://github.com/apache/jclouds.git
complete route53 api
This commit is contained in:
parent
964ae3e2aa
commit
c993eda9fb
labs
aws-route53/src/test/java/org/jclouds/aws/route53/features
route53/src
main/java/org/jclouds/route53
InvalidChangeBatchException.javaRoute53Api.javaRoute53ApiMetadata.javaRoute53AsyncApi.java
binders
config
domain
features
functions
handlers
options
predicates
xml
test
java/org/jclouds/route53
Route53ApiExpectTest.java
features
RecordSetApiExpectTest.javaRecordSetApiLiveTest.javaResourceRecordSetApiExpectTest.javaResourceRecordSetApiLiveTest.javaZoneApiExpectTest.javaZoneApiLiveTest.java
handlers
internal
options
parse
predicates
resources
|
@ -18,15 +18,15 @@
|
|||
*/
|
||||
package org.jclouds.aws.route53.features;
|
||||
|
||||
import org.jclouds.route53.features.ResourceRecordSetApiLiveTest;
|
||||
import org.jclouds.route53.features.RecordSetApiLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", testName = "AWSResourceRecordSetApiLiveTest")
|
||||
public class AWSResourceRecordSetApiLiveTest extends ResourceRecordSetApiLiveTest {
|
||||
public AWSResourceRecordSetApiLiveTest() {
|
||||
public class AWSRecordSetApiLiveTest extends RecordSetApiLiveTest {
|
||||
public AWSRecordSetApiLiveTest() {
|
||||
provider = "aws-route53";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* 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.route53;
|
||||
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* @see <a href=
|
||||
* "http://docs.aws.amazon.com/Route53/latest/APIReference/API_ChangeResourceRecordSets.html"
|
||||
* />
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class InvalidChangeBatchException extends IllegalArgumentException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final ImmutableList<String> messages;
|
||||
|
||||
public InvalidChangeBatchException(ImmutableList<String> messages, HttpResponseException cause) {
|
||||
super(messages.toString(), cause);
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
public ImmutableList<String> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ import javax.ws.rs.PathParam;
|
|||
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.route53.domain.Change;
|
||||
import org.jclouds.route53.features.ResourceRecordSetApi;
|
||||
import org.jclouds.route53.features.RecordSetApi;
|
||||
import org.jclouds.route53.features.ZoneApi;
|
||||
|
||||
/**
|
||||
|
@ -52,8 +52,8 @@ public interface Route53Api {
|
|||
ZoneApi getZoneApi();
|
||||
|
||||
/**
|
||||
* Provides synchronous access to ResourceRecordSet features.
|
||||
* Provides synchronous access to record set features.
|
||||
*/
|
||||
@Delegate
|
||||
ResourceRecordSetApi getResourceRecordSetApiForZone(@PathParam("zoneId") String zoneId);
|
||||
RecordSetApi getRecordSetApiForZone(@PathParam("zoneId") String zoneId);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.route53;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.jclouds.Constants.PROPERTY_TIMEOUTS_PREFIX;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import org.jclouds.rest.annotations.RequestFilters;
|
|||
import org.jclouds.rest.annotations.VirtualHost;
|
||||
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||
import org.jclouds.route53.domain.Change;
|
||||
import org.jclouds.route53.features.ResourceRecordSetAsyncApi;
|
||||
import org.jclouds.route53.features.RecordSetAsyncApi;
|
||||
import org.jclouds.route53.features.ZoneAsyncApi;
|
||||
import org.jclouds.route53.filters.RestAuthentication;
|
||||
import org.jclouds.route53.xml.ChangeHandler;
|
||||
|
@ -67,8 +67,8 @@ public interface Route53AsyncApi {
|
|||
ZoneAsyncApi getZoneApi();
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to ResourceRecordSet features.
|
||||
* Provides asynchronous access to record set features.
|
||||
*/
|
||||
@Delegate
|
||||
ResourceRecordSetAsyncApi getResourceRecordSetApiForZone(@PathParam("zoneId") String zoneId);
|
||||
RecordSetAsyncApi getRecordSetApiForZone(@PathParam("zoneId") String zoneId);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* 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.route53.binders;
|
||||
|
||||
import static org.jclouds.io.Payloads.newStringPayload;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.rest.Binder;
|
||||
import org.jclouds.route53.domain.ChangeBatch;
|
||||
import org.jclouds.route53.domain.ChangeBatch.ActionOnResourceRecordSet;
|
||||
import org.jclouds.route53.functions.SerializeRRS;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class BindChangeBatch implements Binder {
|
||||
|
||||
private static final SerializeRRS xml = new SerializeRRS();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Object payload) {
|
||||
ChangeBatch from = ChangeBatch.class.cast(payload);
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("<ChangeResourceRecordSetsRequest xmlns=\"https://route53.amazonaws.com/doc/2012-02-29/\"><ChangeBatch>");
|
||||
if (from.getComment().isPresent())
|
||||
b.append("<Comment>").append(from.getComment().get()).append("</Comment>");
|
||||
b.append("<Changes>");
|
||||
for (ActionOnResourceRecordSet change : from)
|
||||
b.append("<Change>").append("<Action>").append(change.getAction()).append("</Action>")
|
||||
.append(xml.apply(change.getRRS())).append("</Change>");
|
||||
b.append("</Changes>");
|
||||
b.append("</ChangeBatch></ChangeResourceRecordSetsRequest>");
|
||||
Payload xmlPayload = newStringPayload(b.toString());
|
||||
xmlPayload.getContentMetadata().setContentType("application/xml");
|
||||
return (R) request.toBuilder().payload(xmlPayload).build();
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequest.Builder;
|
||||
import org.jclouds.rest.Binder;
|
||||
import org.jclouds.route53.domain.ResourceRecordSetIterable.NextRecord;
|
||||
import org.jclouds.route53.domain.RecordSetIterable.NextRecord;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -28,15 +28,20 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.aws.config.AWSRestClientModule;
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.annotation.Redirection;
|
||||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.RequestSigner;
|
||||
import org.jclouds.route53.Route53Api;
|
||||
import org.jclouds.route53.Route53AsyncApi;
|
||||
import org.jclouds.route53.features.ResourceRecordSetApi;
|
||||
import org.jclouds.route53.features.ResourceRecordSetAsyncApi;
|
||||
import org.jclouds.route53.features.RecordSetApi;
|
||||
import org.jclouds.route53.features.RecordSetAsyncApi;
|
||||
import org.jclouds.route53.features.ZoneApi;
|
||||
import org.jclouds.route53.features.ZoneAsyncApi;
|
||||
import org.jclouds.route53.filters.RestAuthentication;
|
||||
import org.jclouds.route53.handlers.Route53ErrorHandler;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Provides;
|
||||
|
@ -50,7 +55,7 @@ import com.google.inject.Provides;
|
|||
public class Route53RestClientModule extends AWSRestClientModule<Route53Api, Route53AsyncApi> {
|
||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
|
||||
.put(ZoneApi.class, ZoneAsyncApi.class)
|
||||
.put(ResourceRecordSetApi.class, ResourceRecordSetAsyncApi.class).build();
|
||||
.put(RecordSetApi.class, RecordSetAsyncApi.class).build();
|
||||
|
||||
public Route53RestClientModule() {
|
||||
super(typeToken(Route53Api.class), typeToken(Route53AsyncApi.class), DELEGATE_MAP);
|
||||
|
@ -67,4 +72,11 @@ public class Route53RestClientModule extends AWSRestClientModule<Route53Api, Rou
|
|||
RequestSigner provideRequestSigner(RestAuthentication in) {
|
||||
return in;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(Route53ErrorHandler.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(Route53ErrorHandler.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(Route53ErrorHandler.class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,8 +94,8 @@ public final class Change {
|
|||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
Change other = Change.class.cast(obj);
|
||||
return equal(this.id, other.id);
|
||||
Change that = Change.class.cast(obj);
|
||||
return equal(this.id, that.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
/**
|
||||
* 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.route53.domain;
|
||||
|
||||
import static com.google.common.base.Objects.equal;
|
||||
import static com.google.common.base.Objects.toStringHelper;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.route53.domain.ChangeBatch.ActionOnResourceRecordSet;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ForwardingList;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ChangeBatch extends ForwardingList<ActionOnResourceRecordSet> {
|
||||
|
||||
public static ChangeBatch createAll(Iterable<RecordSet> toCreate) {
|
||||
return builder().createAll(toCreate).build();
|
||||
}
|
||||
|
||||
public static ChangeBatch deleteAll(Iterable<RecordSet> toDelete) {
|
||||
return builder().deleteAll(toDelete).build();
|
||||
}
|
||||
|
||||
private final Optional<String> comment;
|
||||
private final List<ActionOnResourceRecordSet> changes;
|
||||
|
||||
public static enum Action {
|
||||
CREATE, DELETE;
|
||||
}
|
||||
|
||||
public static class ActionOnResourceRecordSet {
|
||||
private final Action action;
|
||||
private final RecordSet rrs;
|
||||
|
||||
private ActionOnResourceRecordSet(Action action, RecordSet rrs) {
|
||||
this.action = action;
|
||||
this.rrs = rrs;
|
||||
}
|
||||
|
||||
public Action getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public RecordSet getRRS() {
|
||||
return rrs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(action, rrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
ActionOnResourceRecordSet that = ActionOnResourceRecordSet.class.cast(obj);
|
||||
return equal(this.action, that.rrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper("").omitNullValues().add("action", action).add("rrs", rrs).toString();
|
||||
}
|
||||
}
|
||||
|
||||
private ChangeBatch(Optional<String> comment, ImmutableList<ActionOnResourceRecordSet> changes) {
|
||||
this.comment = checkNotNull(comment, "comment");
|
||||
this.changes = checkNotNull(changes, "changes%s", comment.isPresent() ? " for %s " + comment.get() : "");
|
||||
checkArgument(!changes.isEmpty(), "no changes%s", comment.isPresent() ? " for %s " + comment.get() : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Any comments you want to include about the changes in this change batch.
|
||||
*/
|
||||
public Optional<String> getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ActionOnResourceRecordSet> delegate() {
|
||||
return changes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(comment, changes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
ChangeBatch that = ChangeBatch.class.cast(obj);
|
||||
return equal(this.comment, that.comment) && equal(this.changes, that.changes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper("").omitNullValues().add("comment", comment.orNull()).add("changes", changes).toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public final static class Builder {
|
||||
private Optional<String> comment = Optional.absent();
|
||||
private ImmutableList.Builder<ActionOnResourceRecordSet> changes = ImmutableList.builder();
|
||||
|
||||
/**
|
||||
* @see ChangeBatch#getComment()
|
||||
*/
|
||||
public Builder comment(String comment) {
|
||||
this.comment = Optional.fromNullable(comment);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder create(RecordSet rrs) {
|
||||
this.changes.add(new ActionOnResourceRecordSet(Action.CREATE, rrs));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder createAll(Iterable<RecordSet> toCreate) {
|
||||
for (RecordSet rrs : toCreate)
|
||||
create(rrs);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder delete(RecordSet rrs) {
|
||||
this.changes.add(new ActionOnResourceRecordSet(Action.DELETE, rrs));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder deleteAll(Iterable<RecordSet> toDelete) {
|
||||
for (RecordSet rrs : toDelete)
|
||||
delete(rrs);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChangeBatch build() {
|
||||
return new ChangeBatch(comment, changes.build());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,394 @@
|
|||
/**
|
||||
* 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.route53.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.Set;
|
||||
|
||||
import org.jclouds.route53.domain.RecordSet.RecordSubset.Latency;
|
||||
import org.jclouds.route53.domain.RecordSet.RecordSubset.Weighted;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Objects.ToStringHelper;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class RecordSet {
|
||||
|
||||
protected final String name;
|
||||
protected final Type type;
|
||||
protected final Optional<Integer> ttl;
|
||||
protected final Set<String> values;
|
||||
protected final Optional<AliasTarget> aliasTarget;
|
||||
|
||||
public enum Type {
|
||||
A, AAAA, CNAME, MX, NS, PTR, SOA, SPF, SRV, TXT;
|
||||
}
|
||||
|
||||
/**
|
||||
* In this case, the rrs is an alias, and it points to another Route53 hosted
|
||||
* resource, such as an ELB, S3 bucket, or zone.
|
||||
*/
|
||||
public static class AliasTarget {
|
||||
|
||||
public static AliasTarget dnsNameInZone(String dnsName, String zoneId) {
|
||||
return new AliasTarget(dnsName, zoneId);
|
||||
}
|
||||
|
||||
private final String dnsName;
|
||||
private final String zoneId;
|
||||
|
||||
private AliasTarget(String dnsName, String zoneId) {
|
||||
this.dnsName = checkNotNull(dnsName, "dnsName");
|
||||
this.zoneId = checkNotNull(zoneId, "zoneId of %s", dnsName);
|
||||
}
|
||||
|
||||
public String getDNSName() {
|
||||
return dnsName;
|
||||
}
|
||||
|
||||
public String getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(zoneId, dnsName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
AliasTarget other = AliasTarget.class.cast(obj);
|
||||
return equal(this.dnsName, other.dnsName) && equal(this.zoneId, other.zoneId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper("").omitNullValues().add("dnsName", dnsName).add("zoneId", zoneId).toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A portion of a RRs who share the same name and type
|
||||
*/
|
||||
public static abstract class RecordSubset extends RecordSet {
|
||||
public static final class Weighted extends RecordSubset {
|
||||
|
||||
private final int weight;
|
||||
|
||||
private Weighted(String id, String name, Type type, int weight, Optional<Integer> ttl, Set<String> values,
|
||||
Optional<AliasTarget> aliasTarget) {
|
||||
super(id, name, type, ttl, values, aliasTarget);
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* determines what portion of traffic for the current resource record
|
||||
* set is routed to this subset.
|
||||
*/
|
||||
public int getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
@Override
|
||||
ToStringHelper differentiate(ToStringHelper in) {
|
||||
return in.add("weight", weight);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Latency extends RecordSubset {
|
||||
|
||||
private final String region;
|
||||
|
||||
private Latency(String id, String name, Type type, String region, Optional<Integer> ttl, Set<String> values,
|
||||
Optional<AliasTarget> aliasTarget) {
|
||||
super(id, name, type, ttl, values, aliasTarget);
|
||||
this.region = checkNotNull(region, "region of %s", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* The Amazon EC2 region where the resource that is specified in this
|
||||
* resource record set resides.
|
||||
*/
|
||||
public String getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
@Override
|
||||
ToStringHelper differentiate(ToStringHelper in) {
|
||||
return in.add("region", region);
|
||||
}
|
||||
}
|
||||
|
||||
private final String id;
|
||||
|
||||
private RecordSubset(String id, String name, Type type, Optional<Integer> ttl, Set<String> values,
|
||||
Optional<AliasTarget> aliasTarget) {
|
||||
super(name, type, ttl, values, aliasTarget);
|
||||
this.id = checkNotNull(id, "id of %s", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier that differentiates beyond {@code name} and {@code type}
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(super.hashCode(), id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj) && obj instanceof RecordSubset) {
|
||||
RecordSubset that = RecordSubset.class.cast(obj);
|
||||
return equal(this.id, that.id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
abstract ToStringHelper differentiate(ToStringHelper in);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return differentiate(toStringHelper("").omitNullValues().add("id", id).add("name", name).add("type", type))
|
||||
.add("ttl", ttl.orNull()).add("values", values.isEmpty() ? null : values).add("aliasTarget", aliasTarget.orNull())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private RecordSet(String name, Type type, Optional<Integer> ttl, Set<String> values, Optional<AliasTarget> aliasTarget) {
|
||||
this.name = checkNotNull(name, "name");
|
||||
this.type = checkNotNull(type, "type of %s", name);
|
||||
this.ttl = checkNotNull(ttl, "ttl for %s", name);
|
||||
this.values = checkNotNull(values, "values for %s", name);
|
||||
this.aliasTarget = checkNotNull(aliasTarget, "aliasTarget for %s", aliasTarget);
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the domain.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The resource record set type.
|
||||
*/
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Present in all resource record sets except aliases. The resource record
|
||||
* cache time to live (TTL), in seconds.
|
||||
*/
|
||||
public Optional<Integer> getTTL() {
|
||||
return ttl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type-specific values that differentiates the RRs in this set. Empty if
|
||||
* {@link #getType()} is {@link Type#A} or {@link Type#AAAA} and
|
||||
* {@link #getAliasTarget} is present.
|
||||
*/
|
||||
public Set<String> getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* When present, {@link #getType()} is {@link Type#A} or {@link Type#AAAA}.
|
||||
* Instead of {@link #getValues()} containing the corresponding IP addresses,
|
||||
* the server will follow this link and resolve one on-demand.
|
||||
*/
|
||||
public Optional<AliasTarget> getAliasTarget() {
|
||||
return aliasTarget;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(name, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
RecordSet other = RecordSet.class.cast(obj);
|
||||
return equal(this.name, other.name) && equal(this.type, other.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper("").omitNullValues().add("name", name).add("type", type).add("ttl", ttl.orNull())
|
||||
.add("values", values.isEmpty() ? null : values).add("aliasTarget", aliasTarget.orNull()).toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return builder().from(this);
|
||||
}
|
||||
|
||||
public final static class Builder {
|
||||
private String id;
|
||||
private String name;
|
||||
private Type type;
|
||||
private Optional<Integer> ttl = Optional.absent();
|
||||
private ImmutableSet.Builder<String> values = ImmutableSet.<String> builder();
|
||||
private String dnsName;
|
||||
private String zoneId;
|
||||
private Integer weight;
|
||||
private String region;
|
||||
|
||||
/**
|
||||
* @see RecordSubset#getId()
|
||||
*/
|
||||
public Builder id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RecordSet#getName()
|
||||
*/
|
||||
public Builder name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RecordSet#getType()
|
||||
*/
|
||||
public Builder type(Type type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RecordSet#getTTL()
|
||||
*/
|
||||
public Builder ttl(Integer ttl) {
|
||||
this.ttl = Optional.fromNullable(ttl);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RecordSet#getAliasTarget()
|
||||
*/
|
||||
public Builder dnsName(String dnsName) {
|
||||
this.dnsName = dnsName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RecordSet#getAliasTarget()
|
||||
*/
|
||||
public Builder zoneId(String zoneId) {
|
||||
this.zoneId = zoneId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RecordSet#getAliasTarget()
|
||||
*/
|
||||
public Builder aliasTarget(AliasTarget aliasTarget) {
|
||||
if (aliasTarget == null) {
|
||||
dnsName = null;
|
||||
zoneId = null;
|
||||
} else {
|
||||
dnsName = aliasTarget.dnsName;
|
||||
zoneId = aliasTarget.zoneId;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RecordSet#getValues()
|
||||
*/
|
||||
public Builder add(String values) {
|
||||
this.values.add(values);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RecordSet#getValues()
|
||||
*/
|
||||
public Builder addAll(Iterable<String> values) {
|
||||
this.values.addAll(values);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RecordSubset.Weighted
|
||||
*/
|
||||
public Builder weight(Integer weight) {
|
||||
this.weight = weight;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RecordSubset.Latency
|
||||
*/
|
||||
public Builder region(String region) {
|
||||
this.region = region;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RecordSet build() {
|
||||
Optional<AliasTarget> aliasTarget = dnsName != null ? Optional.fromNullable(AliasTarget.dnsNameInZone(dnsName, zoneId))
|
||||
: Optional.<AliasTarget> absent();
|
||||
if (weight != null) {
|
||||
return new RecordSubset.Weighted(id, name, type, weight, ttl, values.build(), aliasTarget);
|
||||
} else if (region != null) {
|
||||
return new RecordSubset.Latency(id, name, type, region, ttl, values.build(), aliasTarget);
|
||||
}
|
||||
return new RecordSet(name, type, ttl, values.build(), aliasTarget);
|
||||
}
|
||||
|
||||
public Builder from(RecordSet in) {
|
||||
if (in instanceof RecordSubset)
|
||||
id(RecordSubset.class.cast(in).id);
|
||||
if (in instanceof Weighted) {
|
||||
weight(Weighted.class.cast(in).weight);
|
||||
} else if (in instanceof Latency) {
|
||||
region(Latency.class.cast(in).region);
|
||||
}
|
||||
return this.name(in.name).type(in.type).ttl(in.ttl.orNull()).addAll(in.values)
|
||||
.aliasTarget(in.aliasTarget.orNull());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,7 +27,7 @@ import java.util.Iterator;
|
|||
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.route53.domain.ResourceRecordSet.Type;
|
||||
import org.jclouds.route53.domain.RecordSet.Type;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Optional;
|
||||
|
@ -37,12 +37,12 @@ import com.google.common.collect.ImmutableList;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ResourceRecordSetIterable extends IterableWithMarker<ResourceRecordSet> {
|
||||
public class RecordSetIterable extends IterableWithMarker<RecordSet> {
|
||||
|
||||
private final Iterable<ResourceRecordSet> items;
|
||||
private final Iterable<RecordSet> items;
|
||||
private final Optional<NextRecord> nextRecord;
|
||||
|
||||
private ResourceRecordSetIterable(Iterable<ResourceRecordSet> items, @Nullable NextRecord nextRecord) {
|
||||
private RecordSetIterable(Iterable<RecordSet> items, @Nullable NextRecord nextRecord) {
|
||||
this.items = checkNotNull(items, "items");
|
||||
this.nextRecord = Optional.fromNullable(nextRecord);
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ public class ResourceRecordSetIterable extends IterableWithMarker<ResourceRecord
|
|||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ResourceRecordSet> iterator() {
|
||||
public Iterator<RecordSet> iterator() {
|
||||
return items.iterator();
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ public class ResourceRecordSetIterable extends IterableWithMarker<ResourceRecord
|
|||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
ResourceRecordSetIterable that = ResourceRecordSetIterable.class.cast(obj);
|
||||
RecordSetIterable that = RecordSetIterable.class.cast(obj);
|
||||
return equal(this.items, that.items) && equal(this.nextRecord, that.nextRecord);
|
||||
}
|
||||
|
||||
|
@ -139,9 +139,9 @@ public class ResourceRecordSetIterable extends IterableWithMarker<ResourceRecord
|
|||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
NextRecord other = NextRecord.class.cast(obj);
|
||||
return equal(this.name, other.name) && equal(this.type, other.type)
|
||||
&& equal(this.identifier, other.identifier);
|
||||
NextRecord that = NextRecord.class.cast(obj);
|
||||
return equal(this.name, that.name) && equal(this.type, that.type)
|
||||
&& equal(this.identifier, that.identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -157,17 +157,17 @@ public class ResourceRecordSetIterable extends IterableWithMarker<ResourceRecord
|
|||
|
||||
public static final class Builder {
|
||||
|
||||
private ImmutableList.Builder<ResourceRecordSet> items = ImmutableList.<ResourceRecordSet> builder();
|
||||
private ImmutableList.Builder<RecordSet> items = ImmutableList.<RecordSet> builder();
|
||||
private String nextRecordName;
|
||||
private Type nextRecordType;
|
||||
private String nextRecordIdentifier;
|
||||
|
||||
public Builder add(ResourceRecordSet item) {
|
||||
public Builder add(RecordSet item) {
|
||||
this.items.add(item);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addAll(Iterable<ResourceRecordSet> items) {
|
||||
public Builder addAll(Iterable<RecordSet> items) {
|
||||
this.items.addAll(items);
|
||||
return this;
|
||||
}
|
||||
|
@ -187,10 +187,10 @@ public class ResourceRecordSetIterable extends IterableWithMarker<ResourceRecord
|
|||
return this;
|
||||
}
|
||||
|
||||
public ResourceRecordSetIterable build() {
|
||||
public RecordSetIterable build() {
|
||||
NextRecord nextRecord = nextRecordName != null ? new NextRecord(nextRecordName, nextRecordType,
|
||||
nextRecordIdentifier) : null;
|
||||
return new ResourceRecordSetIterable(items.build(), nextRecord);
|
||||
return new RecordSetIterable(items.build(), nextRecord);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,167 +0,0 @@
|
|||
/**
|
||||
* 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.route53.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.List;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ForwardingList;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public final class ResourceRecordSet extends ForwardingList<String> {
|
||||
|
||||
private final String name;
|
||||
private final Type type;
|
||||
private final Optional<Integer> ttl;
|
||||
private final ImmutableList<String> items;
|
||||
|
||||
private ResourceRecordSet(String name, Type type, Optional<Integer> ttl, ImmutableList<String> items) {
|
||||
this.name = checkNotNull(name, "name");
|
||||
this.type = checkNotNull(type, "type of %s", name);
|
||||
this.ttl = checkNotNull(ttl, "ttl for %s", name);
|
||||
this.items = checkNotNull(items, "items for %s", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the domain.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The resource record set type.
|
||||
*/
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Present in all resource record sets except aliases. The resource record
|
||||
* cache time to live (TTL), in seconds.
|
||||
*/
|
||||
public Optional<Integer> getTTL() {
|
||||
return ttl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(name, type, ttl, items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
ResourceRecordSet other = ResourceRecordSet.class.cast(obj);
|
||||
return equal(this.name, other.name) && equal(this.type, other.type) && equal(this.ttl, other.ttl)
|
||||
&& equal(this.items, other.items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper("").omitNullValues().add("name", name).add("type", type).add("ttl", ttl.orNull())
|
||||
.add("resourceRecords", items).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> delegate() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
A, AAAA, CNAME, MX, NS, PTR, SOA, SPF, SRV, TXT, UNRECOGNIZED;
|
||||
|
||||
public static Type fromValue(String type) {
|
||||
try {
|
||||
return valueOf(checkNotNull(type, "type"));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return builder().from(this);
|
||||
}
|
||||
|
||||
public final static class Builder {
|
||||
private String name;
|
||||
private Type type;
|
||||
private Optional<Integer> ttl = Optional.absent();
|
||||
private ImmutableList.Builder<String> items = ImmutableList.<String> builder();
|
||||
|
||||
/**
|
||||
* @see ResourceRecordSet#getName()
|
||||
*/
|
||||
public Builder name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResourceRecordSet#getType()
|
||||
*/
|
||||
public Builder type(Type type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResourceRecordSet#getTTL()
|
||||
*/
|
||||
public Builder ttl(Integer ttl) {
|
||||
this.ttl = Optional.fromNullable(ttl);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder add(String item) {
|
||||
this.items.add(item);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addAll(Iterable<String> items) {
|
||||
this.items.addAll(items);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ResourceRecordSet build() {
|
||||
return new ResourceRecordSet(name, type, ttl, items.build());
|
||||
}
|
||||
|
||||
public Builder from(ResourceRecordSet in) {
|
||||
return this.name(in.name).type(in.type).ttl(in.ttl.orNull()).addAll(in.items);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -88,9 +88,9 @@ public final class Zone {
|
|||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
Zone other = Zone.class.cast(obj);
|
||||
return equal(this.id, other.id) && equal(this.name, other.name)
|
||||
&& equal(this.callerReference, other.callerReference);
|
||||
Zone that = Zone.class.cast(obj);
|
||||
return equal(this.id, that.id) && equal(this.name, that.name)
|
||||
&& equal(this.callerReference, that.callerReference);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,32 +19,55 @@
|
|||
package org.jclouds.route53.features;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.route53.domain.ResourceRecordSet;
|
||||
import org.jclouds.route53.domain.ResourceRecordSetIterable;
|
||||
import org.jclouds.route53.domain.ResourceRecordSetIterable.NextRecord;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.route53.domain.Change;
|
||||
import org.jclouds.route53.domain.ChangeBatch;
|
||||
import org.jclouds.route53.domain.RecordSet;
|
||||
import org.jclouds.route53.domain.RecordSetIterable;
|
||||
import org.jclouds.route53.domain.RecordSetIterable.NextRecord;
|
||||
|
||||
/**
|
||||
* @see ResourceRecordSetAsyncApi
|
||||
* @see RecordSetAsyncApi
|
||||
* @see <a href=
|
||||
* "http://docs.aws.amazon.com/Route53/latest/APIReference/ActionsOnRRS.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface ResourceRecordSetApi {
|
||||
public interface RecordSetApi {
|
||||
|
||||
/**
|
||||
* schedules creation of the resource record set.
|
||||
*/
|
||||
Change create(RecordSet rrs);
|
||||
|
||||
/**
|
||||
* applies a batch of changes atomically.
|
||||
*/
|
||||
Change apply(ChangeBatch changes);
|
||||
|
||||
/**
|
||||
* returns all resource record sets in order.
|
||||
*/
|
||||
PagedIterable<ResourceRecordSet> list();
|
||||
PagedIterable<RecordSet> list();
|
||||
|
||||
/**
|
||||
* retrieves up to 100 resource record sets in order.
|
||||
*/
|
||||
ResourceRecordSetIterable listFirstPage();
|
||||
RecordSetIterable listFirstPage();
|
||||
|
||||
/**
|
||||
* retrieves up to 100 resource record sets in order, starting at {@code nextRecord}
|
||||
* retrieves up to 100 resource record sets in order, starting at
|
||||
* {@code nextRecord}
|
||||
*/
|
||||
ResourceRecordSetIterable listAt(NextRecord nextRecord);
|
||||
RecordSetIterable listAt(NextRecord nextRecord);
|
||||
|
||||
/**
|
||||
* This action deletes a resource record set.
|
||||
*
|
||||
* @param rrs
|
||||
* the resource record set to delete
|
||||
* @return null if not found or the change in progress
|
||||
*/
|
||||
@Nullable
|
||||
Change delete(RecordSet rrs);
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
/**
|
||||
* 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.route53.features;
|
||||
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_XML;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
|
||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.Fallback;
|
||||
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.Transform;
|
||||
import org.jclouds.rest.annotations.VirtualHost;
|
||||
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||
import org.jclouds.route53.binders.BindChangeBatch;
|
||||
import org.jclouds.route53.binders.BindNextRecord;
|
||||
import org.jclouds.route53.domain.Change;
|
||||
import org.jclouds.route53.domain.ChangeBatch;
|
||||
import org.jclouds.route53.domain.RecordSet;
|
||||
import org.jclouds.route53.domain.RecordSetIterable;
|
||||
import org.jclouds.route53.domain.RecordSetIterable.NextRecord;
|
||||
import org.jclouds.route53.filters.RestAuthentication;
|
||||
import org.jclouds.route53.functions.RecordSetIterableToPagedIterable;
|
||||
import org.jclouds.route53.functions.SerializeRRS;
|
||||
import org.jclouds.route53.xml.ChangeHandler;
|
||||
import org.jclouds.route53.xml.ListResourceRecordSetsResponseHandler;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* @see RecordSetApi
|
||||
* @see <a href=
|
||||
* "http://docs.aws.amazon.com/Route53/latest/APIReference/ActionsOnRRS.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@RequestFilters(RestAuthentication.class)
|
||||
@VirtualHost
|
||||
@Path("/{jclouds.api-version}/hostedzone/{zoneId}")
|
||||
public interface RecordSetAsyncApi {
|
||||
/**
|
||||
* @see RecordSetApi#create
|
||||
*/
|
||||
@Named("ChangeResourceRecordSets")
|
||||
@POST
|
||||
@Produces(APPLICATION_XML)
|
||||
@Path("/rrset")
|
||||
@Payload("<ChangeResourceRecordSetsRequest xmlns=\"https://route53.amazonaws.com/doc/2012-02-29/\"><ChangeBatch><Changes><Change><Action>CREATE</Action>{rrs}</Change></Changes></ChangeBatch></ChangeResourceRecordSetsRequest>")
|
||||
@XMLResponseParser(ChangeHandler.class)
|
||||
ListenableFuture<Change> create(@PayloadParam("rrs") @ParamParser(SerializeRRS.class) RecordSet rrs);
|
||||
|
||||
/**
|
||||
* @see RecordSetApi#apply
|
||||
*/
|
||||
@Named("ChangeResourceRecordSets")
|
||||
@POST
|
||||
@Produces(APPLICATION_XML)
|
||||
@Path("/rrset")
|
||||
@XMLResponseParser(ChangeHandler.class)
|
||||
ListenableFuture<Change> apply(@BinderParam(BindChangeBatch.class) ChangeBatch changes);
|
||||
|
||||
/**
|
||||
* @see RecordSetApi#list()
|
||||
*/
|
||||
@Named("ListResourceRecordSets")
|
||||
@GET
|
||||
@Path("/rrset")
|
||||
@XMLResponseParser(ListResourceRecordSetsResponseHandler.class)
|
||||
@Transform(RecordSetIterableToPagedIterable.class)
|
||||
ListenableFuture<PagedIterable<RecordSet>> list();
|
||||
|
||||
/**
|
||||
* @see RecordSetApi#listFirstPage
|
||||
*/
|
||||
@Named("ListResourceRecordSets")
|
||||
@GET
|
||||
@Path("/rrset")
|
||||
@XMLResponseParser(ListResourceRecordSetsResponseHandler.class)
|
||||
ListenableFuture<RecordSetIterable> listFirstPage();
|
||||
|
||||
/**
|
||||
* @see RecordSetApi#listAt(NextRecord)
|
||||
*/
|
||||
@Named("ListResourceRecordSets")
|
||||
@GET
|
||||
@Path("/rrset")
|
||||
@XMLResponseParser(ListResourceRecordSetsResponseHandler.class)
|
||||
ListenableFuture<RecordSetIterable> listAt(@BinderParam(BindNextRecord.class) NextRecord nextRecord);
|
||||
|
||||
/**
|
||||
* @see RecordSetApi#delete
|
||||
*/
|
||||
@Named("ChangeResourceRecordSets")
|
||||
@POST
|
||||
@Produces(APPLICATION_XML)
|
||||
@Path("/rrset")
|
||||
@Payload("<ChangeResourceRecordSetsRequest xmlns=\"https://route53.amazonaws.com/doc/2012-02-29/\"><ChangeBatch><Changes><Change><Action>DELETE</Action>{rrs}</Change></Changes></ChangeBatch></ChangeResourceRecordSetsRequest>")
|
||||
@XMLResponseParser(ChangeHandler.class)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
ListenableFuture<Change> delete(@PayloadParam("rrs") @ParamParser(SerializeRRS.class) RecordSet rrs);
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
/**
|
||||
* 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.route53.features;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.Transform;
|
||||
import org.jclouds.rest.annotations.VirtualHost;
|
||||
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||
import org.jclouds.route53.binders.BindNextRecord;
|
||||
import org.jclouds.route53.domain.ResourceRecordSet;
|
||||
import org.jclouds.route53.domain.ResourceRecordSetIterable;
|
||||
import org.jclouds.route53.domain.ResourceRecordSetIterable.NextRecord;
|
||||
import org.jclouds.route53.filters.RestAuthentication;
|
||||
import org.jclouds.route53.functions.ResourceRecordSetsToPagedIterable;
|
||||
import org.jclouds.route53.xml.ListResourceRecordSetsResponseHandler;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* @see ResourceRecordSetApi
|
||||
* @see <a href=
|
||||
* "http://docs.aws.amazon.com/Route53/latest/APIReference/ActionsOnRRS.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@RequestFilters(RestAuthentication.class)
|
||||
@VirtualHost
|
||||
@Path("/{jclouds.api-version}/hostedzone/{zoneId}")
|
||||
public interface ResourceRecordSetAsyncApi {
|
||||
|
||||
/**
|
||||
* @see ResourceRecordSetApi#list()
|
||||
*/
|
||||
@Named("ListResourceRecordSets")
|
||||
@GET
|
||||
@Path("/rrset")
|
||||
@XMLResponseParser(ListResourceRecordSetsResponseHandler.class)
|
||||
@Transform(ResourceRecordSetsToPagedIterable.class)
|
||||
ListenableFuture<PagedIterable<ResourceRecordSet>> list();
|
||||
|
||||
/**
|
||||
* @see ResourceRecordSetApi#listFirstPage
|
||||
*/
|
||||
@Named("ListResourceRecordSets")
|
||||
@GET
|
||||
@Path("/rrset")
|
||||
@XMLResponseParser(ListResourceRecordSetsResponseHandler.class)
|
||||
ListenableFuture<ResourceRecordSetIterable> listFirstPage();
|
||||
|
||||
/**
|
||||
* @see ResourceRecordSetApi#listAt(NextRecord)
|
||||
*/
|
||||
@Named("ListResourceRecordSets")
|
||||
@GET
|
||||
@Path("/rrset")
|
||||
@XMLResponseParser(ListResourceRecordSetsResponseHandler.class)
|
||||
ListenableFuture<ResourceRecordSetIterable> listAt(@BinderParam(BindNextRecord.class) NextRecord nextRecord);
|
||||
}
|
|
@ -26,7 +26,6 @@ import org.jclouds.route53.domain.Change.Status;
|
|||
import org.jclouds.route53.domain.NewZone;
|
||||
import org.jclouds.route53.domain.Zone;
|
||||
import org.jclouds.route53.domain.ZoneAndNameServers;
|
||||
import org.jclouds.route53.options.ListZonesOptions;
|
||||
|
||||
/**
|
||||
* @see ZoneAsyncApi
|
||||
|
@ -60,23 +59,21 @@ public interface ZoneApi {
|
|||
*/
|
||||
NewZone createWithReferenceAndComment(String name, String callerReference, String comment);
|
||||
|
||||
/**
|
||||
* The action retrieves a specified number of zones in order.
|
||||
*
|
||||
* <br/>
|
||||
* You can paginate the results using the
|
||||
* {@link ListZonesOptions parameter}
|
||||
*
|
||||
* @param options
|
||||
* the options describing the zones query
|
||||
*/
|
||||
IterableWithMarker<Zone> list(ListZonesOptions options);
|
||||
|
||||
/**
|
||||
* returns all zones in order.
|
||||
*/
|
||||
PagedIterable<Zone> list();
|
||||
|
||||
/**
|
||||
* retrieves up to 100 zones in order.
|
||||
*/
|
||||
IterableWithMarker<Zone> listFirstPage();
|
||||
|
||||
/**
|
||||
* retrieves up to 100 zones in order, starting at {@code nextMarker}
|
||||
*/
|
||||
IterableWithMarker<Zone> listAt(String nextMarker);
|
||||
|
||||
/**
|
||||
* Retrieves information about the specified zone, including its nameserver
|
||||
* configuration
|
||||
|
|
|
@ -27,6 +27,7 @@ import javax.ws.rs.POST;
|
|||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
|
||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
|
@ -44,7 +45,6 @@ import org.jclouds.route53.domain.Zone;
|
|||
import org.jclouds.route53.domain.ZoneAndNameServers;
|
||||
import org.jclouds.route53.filters.RestAuthentication;
|
||||
import org.jclouds.route53.functions.ZonesToPagedIterable;
|
||||
import org.jclouds.route53.options.ListZonesOptions;
|
||||
import org.jclouds.route53.xml.ChangeHandler;
|
||||
import org.jclouds.route53.xml.CreateHostedZoneResponseHandler;
|
||||
import org.jclouds.route53.xml.GetHostedZoneResponseHandler;
|
||||
|
@ -98,13 +98,22 @@ public interface ZoneAsyncApi {
|
|||
ListenableFuture<PagedIterable<Zone>> list();
|
||||
|
||||
/**
|
||||
* @see ZoneApi#list(ListZonesOptions)
|
||||
* @see ZoneApi#listFirstPage
|
||||
*/
|
||||
@Named("ListHostedZones")
|
||||
@GET
|
||||
@Path("/hostedzone")
|
||||
@XMLResponseParser(ListHostedZonesResponseHandler.class)
|
||||
ListenableFuture<IterableWithMarker<Zone>> list(ListZonesOptions options);
|
||||
ListenableFuture<IterableWithMarker<Zone>> listFirstPage();
|
||||
|
||||
/**
|
||||
* @see ZoneApi#listAt(String)
|
||||
*/
|
||||
@Named("ListHostedZones")
|
||||
@GET
|
||||
@Path("/hostedzone")
|
||||
@XMLResponseParser(ListHostedZonesResponseHandler.class)
|
||||
ListenableFuture<IterableWithMarker<Zone>> listAt(@QueryParam("marker") String nextMarker);
|
||||
|
||||
/**
|
||||
* @see ZoneApi#get()
|
||||
|
|
|
@ -25,9 +25,9 @@ import javax.inject.Inject;
|
|||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.internal.CallerArg0ToPagedIterable;
|
||||
import org.jclouds.route53.Route53Api;
|
||||
import org.jclouds.route53.domain.ResourceRecordSet;
|
||||
import org.jclouds.route53.domain.ResourceRecordSetIterable.NextRecord;
|
||||
import org.jclouds.route53.features.ResourceRecordSetApi;
|
||||
import org.jclouds.route53.domain.RecordSet;
|
||||
import org.jclouds.route53.domain.RecordSetIterable.NextRecord;
|
||||
import org.jclouds.route53.features.RecordSetApi;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Function;
|
||||
|
@ -36,23 +36,23 @@ import com.google.common.base.Function;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Beta
|
||||
public class ResourceRecordSetsToPagedIterable extends
|
||||
CallerArg0ToPagedIterable<ResourceRecordSet, ResourceRecordSetsToPagedIterable> {
|
||||
public class RecordSetIterableToPagedIterable extends
|
||||
CallerArg0ToPagedIterable<RecordSet, RecordSetIterableToPagedIterable> {
|
||||
|
||||
private final Route53Api api;
|
||||
|
||||
@Inject
|
||||
protected ResourceRecordSetsToPagedIterable(Route53Api api) {
|
||||
protected RecordSetIterableToPagedIterable(Route53Api api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<ResourceRecordSet>> markerToNextForCallingArg0(String zoneId) {
|
||||
final ResourceRecordSetApi resourceRecordSetApi = api.getResourceRecordSetApiForZone(zoneId);
|
||||
return new Function<Object, IterableWithMarker<ResourceRecordSet>>() {
|
||||
protected Function<Object, IterableWithMarker<RecordSet>> markerToNextForCallingArg0(String zoneId) {
|
||||
final RecordSetApi resourceRecordSetApi = api.getRecordSetApiForZone(zoneId);
|
||||
return new Function<Object, IterableWithMarker<RecordSet>>() {
|
||||
|
||||
@Override
|
||||
public IterableWithMarker<ResourceRecordSet> apply(Object input) {
|
||||
public IterableWithMarker<RecordSet> apply(Object input) {
|
||||
return resourceRecordSetApi.listAt(NextRecord.class.cast(input));
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* 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.route53.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.rest.annotations.ParamParser;
|
||||
import org.jclouds.route53.domain.RecordSet;
|
||||
import org.jclouds.route53.domain.RecordSet.RecordSubset;
|
||||
import org.jclouds.route53.domain.RecordSet.RecordSubset.Latency;
|
||||
import org.jclouds.route53.domain.RecordSet.RecordSubset.Weighted;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
* @see ParamParser
|
||||
*/
|
||||
public class SerializeRRS implements Function<Object, String> {
|
||||
@Override
|
||||
public String apply(Object in) {
|
||||
RecordSet rrs = RecordSet.class.cast(checkNotNull(in, "rrs"));
|
||||
StringBuilder builder = new StringBuilder().append("<ResourceRecordSet>");
|
||||
builder.append("<Name>").append(rrs.getName()).append("</Name>");
|
||||
builder.append("<Type>").append(rrs.getType()).append("</Type>");
|
||||
if (rrs instanceof RecordSubset) {
|
||||
String id = RecordSubset.class.cast(rrs).getId();
|
||||
builder.append("<ResourceRecordSubset>").append(id).append("</ResourceRecordSubset>");
|
||||
}
|
||||
if (rrs instanceof Weighted)
|
||||
builder.append("<Weight>").append(Weighted.class.cast(rrs).getWeight()).append("</Weight>");
|
||||
if (rrs instanceof Latency)
|
||||
builder.append("<Region>").append(Latency.class.cast(rrs).getRegion()).append("</Region>");
|
||||
if (rrs.getAliasTarget().isPresent()) {
|
||||
builder.append("<AliasTarget>");
|
||||
builder.append("<HostedZoneId>").append(rrs.getAliasTarget().get().getZoneId()).append("</HostedZoneId>");
|
||||
builder.append("<DNSName>").append(rrs.getAliasTarget().get().getDNSName()).append("</DNSName>");
|
||||
builder.append("</AliasTarget>");
|
||||
} else {
|
||||
builder.append("<TTL>").append(rrs.getTTL().or(0)).append("</TTL>");
|
||||
builder.append("<ResourceRecords>");
|
||||
for (String record : rrs.getValues())
|
||||
builder.append("<ResourceRecord>").append("<Value>").append(record).append("</Value>")
|
||||
.append("</ResourceRecord>");
|
||||
builder.append("</ResourceRecords>");
|
||||
}
|
||||
return builder.append("</ResourceRecordSet>").toString();
|
||||
}
|
||||
}
|
|
@ -27,7 +27,6 @@ import org.jclouds.collect.internal.CallerArg0ToPagedIterable;
|
|||
import org.jclouds.route53.Route53Api;
|
||||
import org.jclouds.route53.domain.Zone;
|
||||
import org.jclouds.route53.features.ZoneApi;
|
||||
import org.jclouds.route53.options.ListZonesOptions;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Function;
|
||||
|
@ -52,7 +51,7 @@ public class ZonesToPagedIterable extends CallerArg0ToPagedIterable<Zone, ZonesT
|
|||
|
||||
@Override
|
||||
public IterableWithMarker<Zone> apply(Object input) {
|
||||
return zoneApi.list(ListZonesOptions.Builder.afterMarker(input.toString()));
|
||||
return zoneApi.listAt(input.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
* 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.route53.handlers;
|
||||
|
||||
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
|
||||
import static org.jclouds.http.HttpUtils.releasePayload;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.AWSResponseException;
|
||||
import org.jclouds.aws.domain.AWSError;
|
||||
import org.jclouds.aws.xml.ErrorHandler;
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.http.functions.ParseSax.Factory;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.InsufficientResourcesException;
|
||||
import org.jclouds.rest.ResourceNotFoundException;
|
||||
import org.jclouds.route53.InvalidChangeBatchException;
|
||||
import org.jclouds.route53.xml.InvalidChangeBatchHandler;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class Route53ErrorHandler implements HttpErrorHandler {
|
||||
|
||||
private final Factory factory;
|
||||
private final Provider<ErrorHandler> handlers;
|
||||
private final Provider<InvalidChangeBatchHandler> batchHandlers;
|
||||
|
||||
@Inject
|
||||
Route53ErrorHandler(Factory factory, Provider<ErrorHandler> handlers,
|
||||
Provider<InvalidChangeBatchHandler> batchHandlers) {
|
||||
this.factory = factory;
|
||||
this.handlers = handlers;
|
||||
this.batchHandlers = batchHandlers;
|
||||
}
|
||||
|
||||
public void handleError(HttpCommand command, HttpResponse response) {
|
||||
Exception exception = new HttpResponseException(command, response);
|
||||
try {
|
||||
byte[] data = closeClientButKeepContentStream(response);
|
||||
String message = data != null ? new String(data) : null;
|
||||
if (message != null) {
|
||||
exception = new HttpResponseException(command, response, message);
|
||||
if (message.indexOf("ErrorResponse") != -1) {
|
||||
AWSError error = factory.create(handlers.get()).parse(message);
|
||||
exception = refineException(new AWSResponseException(command, response, error));
|
||||
} else if (message.indexOf("InvalidChangeBatch") != -1) {
|
||||
ImmutableList<String> errors = factory.create(batchHandlers.get()).parse(message);
|
||||
exception = new InvalidChangeBatchException(errors, new HttpResponseException(command, response));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
releasePayload(response);
|
||||
command.setException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
private Exception refineException(AWSResponseException in) {
|
||||
int statusCode = in.getResponse().getStatusCode();
|
||||
String errorCode = in.getError().getCode();
|
||||
String message = in.getError().getMessage();
|
||||
|
||||
if (statusCode == 403 || "RequestExpired".equals(errorCode))
|
||||
return new AuthorizationException(message, in);
|
||||
if (statusCode == 400) {
|
||||
if (ImmutableSet.of("InvalidAction", "AccessDenied").contains(errorCode))
|
||||
return new UnsupportedOperationException(message, in);
|
||||
else if ("Throttling".equals(errorCode))
|
||||
return new InsufficientResourcesException(message, in);
|
||||
else if (message.indexOf("not found") != -1)
|
||||
return new ResourceNotFoundException(message, in);
|
||||
return new IllegalArgumentException(message, in);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
/**
|
||||
* 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.route53.options;
|
||||
|
||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
/**
|
||||
* Options used to list available zones.
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://docs.aws.amazon.com/Route53/latest/APIReference/API_ListHostedZones.html"
|
||||
* />
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ListZonesOptions extends BaseHttpRequestOptions implements Cloneable {
|
||||
|
||||
private Integer maxItems;
|
||||
private Object afterMarker;
|
||||
|
||||
/**
|
||||
* corresponds to {@link org.jclouds.collect.IterableWithMarker#nextMarker}
|
||||
*/
|
||||
public ListZonesOptions afterMarker(Object afterMarker) {
|
||||
this.afterMarker = afterMarker;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this parameter only when paginating results to indicate the maximum
|
||||
* number of zone names you want in the response. If there are
|
||||
* additional zone names beyond the maximum you specify, the
|
||||
* IsTruncated response element is true.
|
||||
*/
|
||||
public ListZonesOptions maxItems(Integer maxItems) {
|
||||
this.maxItems = maxItems;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
* @see ListZonesOptions#afterMarker
|
||||
*/
|
||||
public static ListZonesOptions afterMarker(Object afterMarker) {
|
||||
return new ListZonesOptions().afterMarker(afterMarker);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ListZonesOptions#maxItems
|
||||
*/
|
||||
public static ListZonesOptions maxItems(Integer maxItems) {
|
||||
return new ListZonesOptions().maxItems(maxItems);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Multimap<String, String> buildQueryParameters() {
|
||||
Multimap<String, String> params = super.buildQueryParameters();
|
||||
if (afterMarker != null)
|
||||
params.put("marker", afterMarker.toString());
|
||||
if (maxItems != null)
|
||||
params.put("maxitems", maxItems.toString());
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(afterMarker, maxItems);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListZonesOptions clone() {
|
||||
return new ListZonesOptions().afterMarker(afterMarker).maxItems(maxItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ListZonesOptions other = ListZonesOptions.class.cast(obj);
|
||||
return Objects.equal(this.afterMarker, other.afterMarker) && Objects.equal(this.maxItems, other.maxItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper(this).omitNullValues().add("afterMarker", afterMarker).add("maxItems", maxItems).toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* 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.route53.predicates;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.route53.domain.RecordSet;
|
||||
import org.jclouds.route53.domain.RecordSet.Type;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
/**
|
||||
* Predicates handy when working with ResourceRecordSet Types
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class RecordSetPredicates {
|
||||
|
||||
/**
|
||||
* matches zones of the given type
|
||||
*/
|
||||
public static Predicate<RecordSet> typeEquals(final Type type) {
|
||||
checkNotNull(type, "type must be defined");
|
||||
|
||||
return new Predicate<RecordSet>() {
|
||||
@Override
|
||||
public boolean apply(RecordSet zone) {
|
||||
return type.equals(zone.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "typeEquals(" + type + ")";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* 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.route53.predicates;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.route53.domain.Zone;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
/**
|
||||
* Predicates handy when working with Zones
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ZonePredicates {
|
||||
|
||||
/**
|
||||
* matches zones of the given name
|
||||
*/
|
||||
public static Predicate<Zone> nameEquals(final String name) {
|
||||
checkNotNull(name, "name must be defined");
|
||||
|
||||
return new Predicate<Zone>() {
|
||||
@Override
|
||||
public boolean apply(Zone zone) {
|
||||
return name.equals(zone.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "nameEquals(" + name + ")";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* 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.route53.xml;
|
||||
|
||||
import static org.jclouds.util.SaxUtils.currentOrNull;
|
||||
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class InvalidChangeBatchHandler extends ParseSax.HandlerForGeneratedRequestWithResult<ImmutableList<String>> {
|
||||
|
||||
private StringBuilder currentText = new StringBuilder();
|
||||
private ImmutableList.Builder<String> builder = ImmutableList.builder();
|
||||
|
||||
@Override
|
||||
public ImmutableList<String> getResult() {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String name, String qName) {
|
||||
if (qName.equals("Message")) {
|
||||
builder.add(currentOrNull(currentText));
|
||||
}
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(char ch[], int start, int length) {
|
||||
currentText.append(ch, start, length);
|
||||
}
|
||||
}
|
|
@ -22,9 +22,9 @@ import static org.jclouds.util.SaxUtils.currentOrNull;
|
|||
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
|
||||
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.route53.domain.ResourceRecordSet.Type;
|
||||
import org.jclouds.route53.domain.ResourceRecordSetIterable;
|
||||
import org.jclouds.route53.domain.ResourceRecordSetIterable.Builder;
|
||||
import org.jclouds.route53.domain.RecordSet.Type;
|
||||
import org.jclouds.route53.domain.RecordSetIterable;
|
||||
import org.jclouds.route53.domain.RecordSetIterable.Builder;
|
||||
import org.xml.sax.Attributes;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
@ -37,12 +37,12 @@ import com.google.inject.Inject;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class ListResourceRecordSetsResponseHandler extends
|
||||
ParseSax.HandlerForGeneratedRequestWithResult<ResourceRecordSetIterable> {
|
||||
ParseSax.HandlerForGeneratedRequestWithResult<RecordSetIterable> {
|
||||
|
||||
private final ResourceRecordSetHandler resourceRecordSetHandler;
|
||||
|
||||
private StringBuilder currentText = new StringBuilder();
|
||||
private Builder builder = ResourceRecordSetIterable.builder();
|
||||
private Builder builder = RecordSetIterable.builder();
|
||||
|
||||
private boolean inResourceRecordSets;
|
||||
|
||||
|
@ -52,11 +52,11 @@ public class ListResourceRecordSetsResponseHandler extends
|
|||
}
|
||||
|
||||
@Override
|
||||
public ResourceRecordSetIterable getResult() {
|
||||
public RecordSetIterable getResult() {
|
||||
try {
|
||||
return builder.build();
|
||||
} finally {
|
||||
builder = ResourceRecordSetIterable.builder();
|
||||
builder = RecordSetIterable.builder();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,25 +21,25 @@ package org.jclouds.route53.xml;
|
|||
import static org.jclouds.util.SaxUtils.currentOrNull;
|
||||
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.route53.domain.ResourceRecordSet;
|
||||
import org.jclouds.route53.domain.ResourceRecordSet.Type;
|
||||
import org.jclouds.route53.domain.RecordSet;
|
||||
import org.jclouds.route53.domain.RecordSet.Type;
|
||||
import org.xml.sax.Attributes;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ResourceRecordSetHandler extends ParseSax.HandlerForGeneratedRequestWithResult<ResourceRecordSet> {
|
||||
public class ResourceRecordSetHandler extends ParseSax.HandlerForGeneratedRequestWithResult<RecordSet> {
|
||||
|
||||
private StringBuilder currentText = new StringBuilder();
|
||||
private ResourceRecordSet.Builder builder = ResourceRecordSet.builder();
|
||||
private RecordSet.Builder builder = RecordSet.builder();
|
||||
|
||||
@Override
|
||||
public ResourceRecordSet getResult() {
|
||||
public RecordSet getResult() {
|
||||
try {
|
||||
return builder.build();
|
||||
} finally {
|
||||
builder = ResourceRecordSet.builder();
|
||||
builder = RecordSet.builder();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,16 @@ public class ResourceRecordSetHandler extends ParseSax.HandlerForGeneratedReques
|
|||
builder.ttl(Integer.parseInt(currentOrNull(currentText)));
|
||||
} else if (qName.equals("Value")) {
|
||||
builder.add(currentOrNull(currentText));
|
||||
} else if (qName.equals("HostedZoneId")) {
|
||||
builder.zoneId(currentOrNull(currentText));
|
||||
} else if (qName.equals("SetIdentifier")) {
|
||||
builder.id(currentOrNull(currentText));
|
||||
} else if (qName.equals("DNSName")) {
|
||||
builder.dnsName(currentOrNull(currentText));
|
||||
} else if (qName.equals("Weight")) {
|
||||
builder.weight(Integer.parseInt(currentOrNull(currentText)));
|
||||
} else if (qName.equals("Region")) {
|
||||
builder.region(currentOrNull(currentText));
|
||||
}
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public class Route53ApiExpectTest extends BaseRoute53ApiExpectTest {
|
|||
.addHeader("Host", "route53.amazonaws.com")
|
||||
.addHeader("Date", "Mon, 21 Jan 02013 19:29:03 -0800")
|
||||
.addHeader("X-Amzn-Authorization",
|
||||
"AWS3-HTTPS AWSAccessKeyId=identity,Algorithm=HmacSHA256,Signature=pylxNiLcrsjNRZOsxyT161JCwytVPHyc2rFfmNCuZKI=")
|
||||
authForDate)
|
||||
.build();
|
||||
|
||||
HttpResponse getChangeResponse = HttpResponse.builder().statusCode(200)
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
/**
|
||||
* 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
|
||||
*
|
||||
* Unles 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 expres or implied. See the License for the
|
||||
* specific language governing permisions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.route53.features;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.rest.ResourceNotFoundException;
|
||||
import org.jclouds.route53.InvalidChangeBatchException;
|
||||
import org.jclouds.route53.Route53Api;
|
||||
import org.jclouds.route53.domain.ChangeBatch;
|
||||
import org.jclouds.route53.domain.RecordSet;
|
||||
import org.jclouds.route53.domain.RecordSet.Type;
|
||||
import org.jclouds.route53.domain.RecordSetIterable.NextRecord;
|
||||
import org.jclouds.route53.internal.BaseRoute53ApiExpectTest;
|
||||
import org.jclouds.route53.parse.GetChangeResponseTest;
|
||||
import org.jclouds.route53.parse.ListResourceRecordSetsResponseTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ResourceRecordSetApiExpectTest")
|
||||
public class RecordSetApiExpectTest extends BaseRoute53ApiExpectTest {
|
||||
|
||||
HttpRequest create = HttpRequest.builder().method("POST")
|
||||
.endpoint("https://route53.amazonaws.com/2012-02-29/hostedzone/Z1PA6795UKMFR9/rrset")
|
||||
.addHeader("Host", "route53.amazonaws.com")
|
||||
.addHeader("Date", "Mon, 21 Jan 02013 19:29:03 -0800")
|
||||
.addHeader("X-Amzn-Authorization", authForDate)
|
||||
.payload(payloadFromResourceWithContentType("/create_rrs_request.xml", "application/xml")).build();
|
||||
|
||||
HttpResponse jobResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType("/change.xml", "text/xml")).build();
|
||||
|
||||
public void testCreateWhenResponseIs2xx() {
|
||||
Route53Api success = requestSendsResponse(create, jobResponse);
|
||||
assertEquals(success.getRecordSetApiForZone("Z1PA6795UKMFR9").create(RecordSet.builder().name("jclouds.org.").type(Type.TXT).add("my texts").build()).toString(),
|
||||
new GetChangeResponseTest().expected().toString());
|
||||
}
|
||||
|
||||
HttpRequest apply = HttpRequest.builder().method("POST")
|
||||
.endpoint("https://route53.amazonaws.com/2012-02-29/hostedzone/Z1PA6795UKMFR9/rrset")
|
||||
.addHeader("Host", "route53.amazonaws.com")
|
||||
.addHeader("Date", "Mon, 21 Jan 02013 19:29:03 -0800")
|
||||
.addHeader("X-Amzn-Authorization", authForDate)
|
||||
.payload(payloadFromResourceWithContentType("/batch_rrs_request.xml", "application/xml")).build();
|
||||
|
||||
public void testApplyWhenResponseIs2xx() {
|
||||
Route53Api success = requestSendsResponse(apply, jobResponse);
|
||||
assertEquals(success.getRecordSetApiForZone("Z1PA6795UKMFR9").apply(
|
||||
ChangeBatch.builder()
|
||||
.delete(RecordSet.builder().name("jclouds.org.").type(Type.TXT).add("my texts").build())
|
||||
.create(RecordSet.builder().name("jclouds.org.").type(Type.TXT).add("my better texts").build())
|
||||
.build()).toString(),
|
||||
new GetChangeResponseTest().expected().toString());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = InvalidChangeBatchException.class, expectedExceptionsMessageRegExp = "\\[Tried to create resource record set duplicate.example.com. type A, but it already exists, Tried to delete resource record set noexist.example.com. type A, but it was not found\\]")
|
||||
public void testApplyWhenResponseIs4xx() {
|
||||
HttpResponse batchErrorFound = HttpResponse.builder().statusCode(400)
|
||||
.payload(payloadFromResourceWithContentType("/invalid_change_batch.xml", "application/xml")).build();
|
||||
|
||||
Route53Api fails = requestSendsResponse(apply, batchErrorFound);
|
||||
fails.getRecordSetApiForZone("Z1PA6795UKMFR9").apply(
|
||||
ChangeBatch.builder()
|
||||
.delete(RecordSet.builder().name("jclouds.org.").type(Type.TXT).add("my texts").build())
|
||||
.create(RecordSet.builder().name("jclouds.org.").type(Type.TXT).add("my better texts").build())
|
||||
.build());
|
||||
}
|
||||
|
||||
HttpRequest list = HttpRequest.builder().method("GET")
|
||||
.endpoint("https://route53.amazonaws.com/2012-02-29/hostedzone/Z1PA6795UKMFR9/rrset")
|
||||
.addHeader("Host", "route53.amazonaws.com")
|
||||
.addHeader("Date", "Mon, 21 Jan 02013 19:29:03 -0800")
|
||||
.addHeader("X-Amzn-Authorization", authForDate).build();
|
||||
|
||||
HttpResponse listResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType("/rrsets.xml", "text/xml")).build();
|
||||
|
||||
public void testListWhenResponseIs2xx() {
|
||||
Route53Api success = requestSendsResponse(list, listResponse);
|
||||
assertEquals(success.getRecordSetApiForZone("Z1PA6795UKMFR9").list().get(0).toString(), new ListResourceRecordSetsResponseTest().expected()
|
||||
.toString());
|
||||
}
|
||||
|
||||
// TODO: this should really be an empty set
|
||||
@Test(expectedExceptions = ResourceNotFoundException.class)
|
||||
public void testListWhenResponseIs404() {
|
||||
Route53Api fail = requestSendsResponse(list, notFound);
|
||||
assertEquals(fail.getRecordSetApiForZone("Z1PA6795UKMFR9").list().get(0).toSet(), ImmutableSet.of());
|
||||
}
|
||||
|
||||
HttpRequest listAt = HttpRequest.builder().method("GET")
|
||||
.endpoint("https://route53.amazonaws.com/2012-02-29/hostedzone/Z1PA6795UKMFR9/rrset?name=testdoc2.example.com&type=NS")
|
||||
.addHeader("Host", "route53.amazonaws.com")
|
||||
.addHeader("Date", "Mon, 21 Jan 02013 19:29:03 -0800")
|
||||
.addHeader("X-Amzn-Authorization", authForDate).build();
|
||||
|
||||
public void testListAtWhenResponseIs2xx() {
|
||||
Route53Api apiWhenAtExist = requestSendsResponse(listAt, listResponse);
|
||||
NextRecord next = NextRecord.nameAndType("testdoc2.example.com", Type.NS);
|
||||
assertEquals(apiWhenAtExist.getRecordSetApiForZone("Z1PA6795UKMFR9").listAt(next).toString(),
|
||||
new ListResourceRecordSetsResponseTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testList2PagesWhenResponseIs2xx() {
|
||||
HttpResponse noMore = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromStringWithContentType("<ListResourceRecordSetsResponse />", "text/xml")).build();
|
||||
|
||||
Route53Api success = requestsSendResponses(list, listResponse, listAt, noMore);
|
||||
assertEquals(success.getRecordSetApiForZone("Z1PA6795UKMFR9").list().concat().toSet(), new ListResourceRecordSetsResponseTest().expected()
|
||||
.toSet());
|
||||
}
|
||||
|
||||
HttpRequest delete = HttpRequest.builder().method("POST")
|
||||
.endpoint("https://route53.amazonaws.com/2012-02-29/hostedzone/Z1PA6795UKMFR9/rrset")
|
||||
.addHeader("Host", "route53.amazonaws.com")
|
||||
.addHeader("Date", "Mon, 21 Jan 02013 19:29:03 -0800")
|
||||
.addHeader("X-Amzn-Authorization", authForDate)
|
||||
.payload(payloadFromResourceWithContentType("/delete_rrs_request.xml", "application/xml")).build();
|
||||
|
||||
public void testDeleteWhenResponseIs2xx() {
|
||||
Route53Api success = requestSendsResponse(delete, jobResponse);
|
||||
assertEquals(success.getRecordSetApiForZone("Z1PA6795UKMFR9").create(RecordSet.builder().name("jclouds.org.").type(Type.TXT).add("my texts").build()).toString(),
|
||||
new GetChangeResponseTest().expected().toString());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
/**
|
||||
* 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.route53.features;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Predicates.not;
|
||||
import static com.google.common.base.Predicates.or;
|
||||
import static java.util.logging.Logger.getAnonymousLogger;
|
||||
import static org.jclouds.route53.domain.ChangeBatch.createAll;
|
||||
import static org.jclouds.route53.domain.ChangeBatch.deleteAll;
|
||||
import static org.jclouds.route53.domain.RecordSet.Type.NS;
|
||||
import static org.jclouds.route53.domain.RecordSet.Type.SOA;
|
||||
import static org.jclouds.route53.domain.RecordSet.Type.TXT;
|
||||
import static org.jclouds.route53.predicates.RecordSetPredicates.typeEquals;
|
||||
import static org.jclouds.route53.predicates.ZonePredicates.nameEquals;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.JcloudsVersion;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.route53.domain.Change;
|
||||
import org.jclouds.route53.domain.NewZone;
|
||||
import org.jclouds.route53.domain.RecordSet;
|
||||
import org.jclouds.route53.domain.RecordSet.RecordSubset;
|
||||
import org.jclouds.route53.domain.RecordSet.RecordSubset.Latency;
|
||||
import org.jclouds.route53.domain.RecordSet.RecordSubset.Weighted;
|
||||
import org.jclouds.route53.domain.Zone;
|
||||
import org.jclouds.route53.internal.BaseRoute53ApiLiveTest;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", testName = "ResourceRecordSetApiLiveTest")
|
||||
public class RecordSetApiLiveTest extends BaseRoute53ApiLiveTest {
|
||||
|
||||
private void checkRRS(RecordSet rrs) {
|
||||
checkNotNull(rrs.getName(), "Name: ResourceRecordSet %s", rrs);
|
||||
checkNotNull(rrs.getType(), "Type: ResourceRecordSet %s", rrs);
|
||||
checkNotNull(rrs.getTTL(), "TTL: ResourceRecordSet %s", rrs);
|
||||
checkNotNull(rrs.getAliasTarget(), "AliasTarget: ResourceRecordSet %s", rrs);
|
||||
if (rrs.getAliasTarget().isPresent()) {
|
||||
assertTrue(rrs.getValues().isEmpty(), "Values present on aliasTarget ResourceRecordSet: " + rrs);
|
||||
} else {
|
||||
assertTrue(!rrs.getValues().isEmpty(), "Values absent on ResourceRecordSet: " + rrs);
|
||||
}
|
||||
if (rrs instanceof RecordSubset) {
|
||||
checkNotNull(RecordSubset.class.cast(rrs).getId(), "Id: ResourceRecordSubset %s", rrs);
|
||||
}
|
||||
if (rrs instanceof Weighted) {
|
||||
assertTrue(Weighted.class.cast(rrs).getWeight() >= 0, "Weight negative: ResourceRecordSubset " + rrs);
|
||||
}
|
||||
if (rrs instanceof Latency) {
|
||||
checkNotNull(Latency.class.cast(rrs).getRegion(), "Region: ResourceRecordSubset %s", rrs);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
private void testListRRSs() {
|
||||
for (Zone zone : zones().concat()) {
|
||||
checkAllRRs(zone.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAllRRs(String zoneId) {
|
||||
Zone zone = context.getApi().getZoneApi().get(zoneId).getZone();
|
||||
List<RecordSet> records = api(zone.getId()).list().concat().toList();
|
||||
assertEquals(zone.getResourceRecordSetCount(), records.size());
|
||||
|
||||
for (RecordSet rrs : records) {
|
||||
checkRRS(rrs);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteRRSNotFound() {
|
||||
for (Zone zone : zones().concat()) {
|
||||
assertNull(api(zone.getId()).delete(
|
||||
RecordSet.builder().name("krank.foo.bar.").type(TXT).add("kranko").build()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cannot delete a zone without at least one of each
|
||||
*/
|
||||
private static final Predicate<RecordSet> requiredRRTypes = or(typeEquals(SOA), typeEquals(NS));
|
||||
|
||||
@Test
|
||||
public void testCreateAndDeleteBulkRecords() {
|
||||
String name = System.getProperty("user.name").replace('.', '-') + ".bulk.route53test.jclouds.org.";
|
||||
clearAndDeleteZonesNamed(name);
|
||||
|
||||
ImmutableList<RecordSet> records = ImmutableList.<RecordSet> builder()
|
||||
.add(RecordSet.builder().name("dom1." + name).type(TXT).add("\"somehow\" \" somewhere\"").build())
|
||||
.add(RecordSet.builder().name("dom2." + name).type(TXT).add("\"goodies\"").build()).build();
|
||||
|
||||
String nonce = name + " @ " + new Date();
|
||||
String comment = name + " for " + JcloudsVersion.get();
|
||||
NewZone newZone = context.getApi().getZoneApi().createWithReferenceAndComment(name, nonce, comment);
|
||||
String zoneId = newZone.getZone().getId();
|
||||
getAnonymousLogger().info("created zone: " + newZone);
|
||||
try {
|
||||
assertTrue(inSync.apply(newZone.getChange()), "zone didn't sync " + newZone);
|
||||
sync(api(zoneId).apply(createAll(records)));
|
||||
|
||||
checkAllRRs(zoneId);
|
||||
|
||||
sync(api(zoneId).apply(deleteAll(records)));
|
||||
|
||||
PagedIterable<RecordSet> refreshed = refresh(zoneId);
|
||||
assertTrue(refreshed.concat().filter(not(requiredRRTypes)).isEmpty(), "zone still has optional records: "
|
||||
+ refreshed);
|
||||
|
||||
} finally {
|
||||
clearAndDeleteZonesNamed(name);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearAndDeleteZonesNamed(String name) {
|
||||
for (Zone zone : context.getApi().getZoneApi().list().concat().filter(nameEquals(name))) {
|
||||
getAnonymousLogger().info("clearing and deleting zone: " + zone);
|
||||
Set<RecordSet> remaining = refresh(zone.getId()).concat().filter(not(requiredRRTypes)).toSet();
|
||||
if (!remaining.isEmpty())
|
||||
sync(api(zone.getId()).apply(deleteAll(remaining)));
|
||||
sync(context.getApi().getZoneApi().delete(zone.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
private void sync(Change job) {
|
||||
assertTrue(inSync.apply(job), "job didn't sync " + job);
|
||||
}
|
||||
|
||||
private PagedIterable<RecordSet> refresh(String zoneId) {
|
||||
return api(zoneId).list();
|
||||
}
|
||||
|
||||
private PagedIterable<Zone> zones() {
|
||||
PagedIterable<Zone> zones = context.getApi().getZoneApi().list();
|
||||
if (zones.get(0).isEmpty())
|
||||
throw new SkipException("no zones in context: " + context);
|
||||
return zones;
|
||||
}
|
||||
|
||||
private RecordSetApi api(String zoneId) {
|
||||
return context.getApi().getRecordSetApiForZone(zoneId);
|
||||
}
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
/**
|
||||
* 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
|
||||
*
|
||||
* Unles 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 expres or implied. See the License for the
|
||||
* specific language governing permisions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.route53.features;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.rest.ResourceNotFoundException;
|
||||
import org.jclouds.route53.Route53Api;
|
||||
import org.jclouds.route53.domain.ResourceRecordSet.Type;
|
||||
import org.jclouds.route53.domain.ResourceRecordSetIterable.NextRecord;
|
||||
import org.jclouds.route53.internal.BaseRoute53ApiExpectTest;
|
||||
import org.jclouds.route53.parse.ListResourceRecordSetsResponseTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ResourceRecordSetApiExpectTest")
|
||||
public class ResourceRecordSetApiExpectTest extends BaseRoute53ApiExpectTest {
|
||||
|
||||
HttpRequest list = HttpRequest.builder().method("GET")
|
||||
.endpoint("https://route53.amazonaws.com/2012-02-29/hostedzone/Z1PA6795UKMFR9/rrset")
|
||||
.addHeader("Host", "route53.amazonaws.com")
|
||||
.addHeader("Date", "Mon, 21 Jan 02013 19:29:03 -0800")
|
||||
.addHeader("X-Amzn-Authorization",
|
||||
"AWS3-HTTPS AWSAccessKeyId=identity,Algorithm=HmacSHA256,Signature=pylxNiLcrsjNRZOsxyT161JCwytVPHyc2rFfmNCuZKI=")
|
||||
.build();
|
||||
|
||||
HttpResponse listResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType("/rrsets.xml", "text/xml")).build();
|
||||
|
||||
public void testListWhenResponseIs2xx() {
|
||||
Route53Api success = requestSendsResponse(list, listResponse);
|
||||
assertEquals(success.getResourceRecordSetApiForZone("Z1PA6795UKMFR9").list().get(0).toString(), new ListResourceRecordSetsResponseTest().expected()
|
||||
.toString());
|
||||
}
|
||||
|
||||
// TODO: this should really be an empty set
|
||||
@Test(expectedExceptions = ResourceNotFoundException.class)
|
||||
public void testListWhenResponseIs404() {
|
||||
Route53Api fail = requestSendsResponse(list, notFound);
|
||||
assertEquals(fail.getResourceRecordSetApiForZone("Z1PA6795UKMFR9").list().get(0).toSet(), ImmutableSet.of());
|
||||
}
|
||||
|
||||
HttpRequest listAt = HttpRequest.builder().method("GET")
|
||||
.endpoint("https://route53.amazonaws.com/2012-02-29/hostedzone/Z1PA6795UKMFR9/rrset?name=testdoc2.example.com&type=NS")
|
||||
.addHeader("Host", "route53.amazonaws.com")
|
||||
.addHeader("Date", "Mon, 21 Jan 02013 19:29:03 -0800")
|
||||
.addHeader("X-Amzn-Authorization",
|
||||
"AWS3-HTTPS AWSAccessKeyId=identity,Algorithm=HmacSHA256,Signature=pylxNiLcrsjNRZOsxyT161JCwytVPHyc2rFfmNCuZKI=")
|
||||
.build();
|
||||
|
||||
public void testListAtWhenResponseIs2xx() {
|
||||
Route53Api apiWhenAtExist = requestSendsResponse(listAt, listResponse);
|
||||
NextRecord next = NextRecord.nameAndType("testdoc2.example.com", Type.NS);
|
||||
assertEquals(apiWhenAtExist.getResourceRecordSetApiForZone("Z1PA6795UKMFR9").listAt(next).toString(),
|
||||
new ListResourceRecordSetsResponseTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testList2PagesWhenResponseIs2xx() {
|
||||
HttpResponse noMore = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromStringWithContentType("<ListResourceRecordSetsResponse />", "text/xml")).build();
|
||||
|
||||
Route53Api success = requestsSendResponses(list, listResponse, listAt, noMore);
|
||||
assertEquals(success.getResourceRecordSetApiForZone("Z1PA6795UKMFR9").list().concat().toSet(), new ListResourceRecordSetsResponseTest().expected()
|
||||
.toSet());
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/**
|
||||
* 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.route53.features;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.route53.domain.ResourceRecordSet;
|
||||
import org.jclouds.route53.domain.Zone;
|
||||
import org.jclouds.route53.internal.BaseRoute53ApiLiveTest;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", testName = "ResourceRecordSetApiLiveTest")
|
||||
public class ResourceRecordSetApiLiveTest extends BaseRoute53ApiLiveTest {
|
||||
|
||||
private void checkResourceRecordSet(ResourceRecordSet resourceRecordSet) {
|
||||
checkNotNull(resourceRecordSet.getName(), "Id cannot be null for a ResourceRecordSet %s", resourceRecordSet);
|
||||
checkNotNull(resourceRecordSet.getType(), "Type cannot be null for a ResourceRecordSet %s", resourceRecordSet);
|
||||
checkNotNull(resourceRecordSet.getTTL(),
|
||||
"While TTL can be null for a ResourceRecordSet, its Optional wrapper cannot %s", resourceRecordSet);
|
||||
}
|
||||
|
||||
@Test
|
||||
protected void testListResourceRecordSets() {
|
||||
IterableWithMarker<Zone> zones = context.getApi().getZoneApi().list().get(0);
|
||||
if (zones.isEmpty())
|
||||
throw new SkipException("no zones in context: " + context);
|
||||
|
||||
Zone zone = zones.first().get();
|
||||
List<ResourceRecordSet> records = api(zone.getId()).list().concat().toList();
|
||||
assertEquals(zone.getResourceRecordSetCount(), records.size());
|
||||
|
||||
for (ResourceRecordSet resourceRecordSet : records) {
|
||||
checkResourceRecordSet(resourceRecordSet);
|
||||
}
|
||||
}
|
||||
|
||||
protected ResourceRecordSetApi api(String zoneId) {
|
||||
return context.getApi().getResourceRecordSetApiForZone(zoneId);
|
||||
}
|
||||
}
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.route53.features;
|
||||
|
||||
import static org.jclouds.route53.options.ListZonesOptions.Builder.afterMarker;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
|
||||
|
@ -45,7 +44,7 @@ public class ZoneApiExpectTest extends BaseRoute53ApiExpectTest {
|
|||
.addHeader("Host", "route53.amazonaws.com")
|
||||
.addHeader("Date", "Mon, 21 Jan 02013 19:29:03 -0800")
|
||||
.addHeader("X-Amzn-Authorization",
|
||||
"AWS3-HTTPS AWSAccessKeyId=identity,Algorithm=HmacSHA256,Signature=pylxNiLcrsjNRZOsxyT161JCwytVPHyc2rFfmNCuZKI=")
|
||||
authForDate)
|
||||
.payload(
|
||||
payloadFromStringWithContentType(
|
||||
"<CreateHostedZoneRequest xmlns=\"https://route53.amazonaws.com/doc/2012-02-29/\"><Name>jclouds.org.</Name><CallerReference>expect</CallerReference></CreateHostedZoneRequest>",
|
||||
|
@ -65,7 +64,7 @@ public class ZoneApiExpectTest extends BaseRoute53ApiExpectTest {
|
|||
.addHeader("Host", "route53.amazonaws.com")
|
||||
.addHeader("Date", "Mon, 21 Jan 02013 19:29:03 -0800")
|
||||
.addHeader("X-Amzn-Authorization",
|
||||
"AWS3-HTTPS AWSAccessKeyId=identity,Algorithm=HmacSHA256,Signature=pylxNiLcrsjNRZOsxyT161JCwytVPHyc2rFfmNCuZKI=")
|
||||
authForDate)
|
||||
.payload(
|
||||
payloadFromStringWithContentType(
|
||||
"<CreateHostedZoneRequest xmlns=\"https://route53.amazonaws.com/doc/2012-02-29/\"><Name>jclouds.org.</Name><CallerReference>expect</CallerReference><HostedZoneConfig><Comment>comment</Comment></HostedZoneConfig></CreateHostedZoneRequest>",
|
||||
|
@ -82,7 +81,7 @@ public class ZoneApiExpectTest extends BaseRoute53ApiExpectTest {
|
|||
.addHeader("Host", "route53.amazonaws.com")
|
||||
.addHeader("Date", "Mon, 21 Jan 02013 19:29:03 -0800")
|
||||
.addHeader("X-Amzn-Authorization",
|
||||
"AWS3-HTTPS AWSAccessKeyId=identity,Algorithm=HmacSHA256,Signature=pylxNiLcrsjNRZOsxyT161JCwytVPHyc2rFfmNCuZKI=")
|
||||
authForDate)
|
||||
.build();
|
||||
|
||||
HttpResponse getResponse = HttpResponse.builder().statusCode(200)
|
||||
|
@ -104,7 +103,7 @@ public class ZoneApiExpectTest extends BaseRoute53ApiExpectTest {
|
|||
.addHeader("Host", "route53.amazonaws.com")
|
||||
.addHeader("Date", "Mon, 21 Jan 02013 19:29:03 -0800")
|
||||
.addHeader("X-Amzn-Authorization",
|
||||
"AWS3-HTTPS AWSAccessKeyId=identity,Algorithm=HmacSHA256,Signature=pylxNiLcrsjNRZOsxyT161JCwytVPHyc2rFfmNCuZKI=")
|
||||
authForDate)
|
||||
.build();
|
||||
|
||||
HttpResponse listResponse = HttpResponse.builder().statusCode(200)
|
||||
|
@ -123,17 +122,17 @@ public class ZoneApiExpectTest extends BaseRoute53ApiExpectTest {
|
|||
assertEquals(fail.getZoneApi().list().get(0).toSet(), ImmutableSet.of());
|
||||
}
|
||||
|
||||
HttpRequest listWithOptions = HttpRequest.builder().method("GET")
|
||||
HttpRequest listAt = HttpRequest.builder().method("GET")
|
||||
.endpoint("https://route53.amazonaws.com/2012-02-29/hostedzone?marker=Z333333YYYYYYY")
|
||||
.addHeader("Host", "route53.amazonaws.com")
|
||||
.addHeader("Date", "Mon, 21 Jan 02013 19:29:03 -0800")
|
||||
.addHeader("X-Amzn-Authorization",
|
||||
"AWS3-HTTPS AWSAccessKeyId=identity,Algorithm=HmacSHA256,Signature=pylxNiLcrsjNRZOsxyT161JCwytVPHyc2rFfmNCuZKI=")
|
||||
authForDate)
|
||||
.build();
|
||||
|
||||
public void testListWithOptionsWhenResponseIs2xx() {
|
||||
Route53Api apiWhenWithOptionsExist = requestSendsResponse(listWithOptions, listResponse);
|
||||
assertEquals(apiWhenWithOptionsExist.getZoneApi().list(afterMarker("Z333333YYYYYYY")).toString(),
|
||||
public void testListAtWhenResponseIs2xx() {
|
||||
Route53Api apiWhenAtExist = requestSendsResponse(listAt, listResponse);
|
||||
assertEquals(apiWhenAtExist.getZoneApi().listAt("Z333333YYYYYYY").toString(),
|
||||
new ListHostedZonesResponseTest().expected().toString());
|
||||
}
|
||||
|
||||
|
@ -141,7 +140,7 @@ public class ZoneApiExpectTest extends BaseRoute53ApiExpectTest {
|
|||
HttpResponse noMore = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromStringWithContentType("<ListHostedZonesResponse />", "text/xml")).build();
|
||||
|
||||
Route53Api success = requestsSendResponses(list, listResponse, listWithOptions, noMore);
|
||||
Route53Api success = requestsSendResponses(list, listResponse, listAt, noMore);
|
||||
assertEquals(success.getZoneApi().list().concat().toString(), new ListHostedZonesResponseTest().expected()
|
||||
.toString());
|
||||
}
|
||||
|
@ -151,7 +150,7 @@ public class ZoneApiExpectTest extends BaseRoute53ApiExpectTest {
|
|||
.addHeader("Host", "route53.amazonaws.com")
|
||||
.addHeader("Date", "Mon, 21 Jan 02013 19:29:03 -0800")
|
||||
.addHeader("X-Amzn-Authorization",
|
||||
"AWS3-HTTPS AWSAccessKeyId=identity,Algorithm=HmacSHA256,Signature=pylxNiLcrsjNRZOsxyT161JCwytVPHyc2rFfmNCuZKI=")
|
||||
authForDate)
|
||||
.build();
|
||||
|
||||
HttpResponse deleteResponse = HttpResponse.builder().statusCode(200)
|
||||
|
|
|
@ -17,74 +17,49 @@
|
|||
* under the License.
|
||||
*/
|
||||
package org.jclouds.route53.features;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.jclouds.route53.domain.Change.Status.INSYNC;
|
||||
import static java.lang.String.format;
|
||||
import static java.util.logging.Logger.getAnonymousLogger;
|
||||
import static org.jclouds.route53.domain.Change.Status.PENDING;
|
||||
import static org.jclouds.util.Predicates2.retry;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jclouds.JcloudsVersion;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.route53.domain.Change;
|
||||
import org.jclouds.route53.domain.NewZone;
|
||||
import org.jclouds.route53.domain.Zone;
|
||||
import org.jclouds.route53.internal.BaseRoute53ApiLiveTest;
|
||||
import org.jclouds.route53.options.ListZonesOptions;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", testName = "ZoneApiLiveTest")
|
||||
public class ZoneApiLiveTest extends BaseRoute53ApiLiveTest {
|
||||
private Predicate<Change> inSync;
|
||||
|
||||
@BeforeClass(groups = "live")
|
||||
@Override
|
||||
public void setupContext() {
|
||||
super.setupContext();
|
||||
inSync = retry(new Predicate<Change>() {
|
||||
public boolean apply(Change input) {
|
||||
return context.getApi().getChange(input.getId()).getStatus() == INSYNC;
|
||||
}
|
||||
}, 600, 1, 5, SECONDS);
|
||||
}
|
||||
|
||||
private void checkZone(Zone zone) {
|
||||
checkNotNull(zone.getId(), "Id cannot be null for a Zone %s", zone);
|
||||
checkNotNull(zone.getName(), "Name cannot be null for a Zone %s", zone);
|
||||
checkNotNull(zone.getCallerReference(), "CallerReference cannot be null for a Zone %s", zone);
|
||||
getAnonymousLogger().info(format("zone %s rrs: %s", zone.getName(), zone.getResourceRecordSetCount()));
|
||||
|
||||
checkNotNull(zone.getId(), "Id: Zone %s", zone);
|
||||
checkNotNull(zone.getName(), "Name: Zone %s", zone);
|
||||
checkNotNull(zone.getCallerReference(), "CallerReference: Zone %s", zone);
|
||||
checkNotNull(zone.getComment(), "While Comment can be null for a Zone, its Optional wrapper cannot %s", zone);
|
||||
}
|
||||
|
||||
@Test
|
||||
protected void testListZones() {
|
||||
IterableWithMarker<Zone> response = api().list().get(0);
|
||||
ImmutableList<Zone> zones = api().list().concat().toList();
|
||||
getAnonymousLogger().info("zones: " + zones.size());
|
||||
|
||||
for (Zone zone : response) {
|
||||
for (Zone zone : zones) {
|
||||
checkZone(zone);
|
||||
}
|
||||
|
||||
if (response.size() > 0) {
|
||||
Zone zone = response.iterator().next();
|
||||
assertEquals(api().get(zone.getId()).getZone(), zone);
|
||||
}
|
||||
|
||||
// Test with a Marker, even if it's null
|
||||
response = api().list(ListZonesOptions.Builder.afterMarker(response.nextMarker().orNull()));
|
||||
for (Zone zone : response) {
|
||||
checkZone(zone);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -103,7 +78,7 @@ public class ZoneApiLiveTest extends BaseRoute53ApiLiveTest {
|
|||
String nonce = name + " @ " + new Date();
|
||||
String comment = name + " for " + JcloudsVersion.get();
|
||||
NewZone newZone = api().createWithReferenceAndComment(name, nonce, comment);
|
||||
Logger.getAnonymousLogger().info("created zone: " + newZone);
|
||||
getAnonymousLogger().info("created zone: " + newZone);
|
||||
try {
|
||||
checkZone(newZone.getZone());
|
||||
assertEquals(newZone.getChange().getStatus(), PENDING, "invalid status on zone " + newZone);
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
/**
|
||||
* 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.route53.handlers;
|
||||
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static org.jclouds.rest.internal.BaseRestApiExpectTest.payloadFromStringWithContentType;
|
||||
import static org.jclouds.util.Strings2.toStringAndClose;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jclouds.aws.AWSResponseException;
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.config.SaxParserModule;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.rest.ResourceNotFoundException;
|
||||
import org.jclouds.route53.InvalidChangeBatchException;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Guice;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit" )
|
||||
public class Route53ErrorHandlerTest {
|
||||
Route53ErrorHandler function = Guice.createInjector(new SaxParserModule()).getInstance(Route53ErrorHandler.class);
|
||||
|
||||
HttpRequest request = HttpRequest.builder().method("POST")
|
||||
.endpoint("https://route53.amazonaws.com/2012-02-29/hostedzone/Z1PA6795UKMFR9/rrset")
|
||||
.addHeader("Host", "route53.amazonaws.com")
|
||||
.addHeader("Date", "Mon, 21 Jan 02013 19:29:03 -0800")
|
||||
.addHeader("X-Amzn-Authorization", "AWS3-HTTPS AWSAccessKeyId=identity,Algorithm=HmacSHA256,Signature=pylxNiLcrsjNRZOsxyT161JCwytVPHyc2rFfmNCuZKI=")
|
||||
.payload(payloadFromResource("/batch_rrs_request.xml")).build();
|
||||
HttpCommand command = new HttpCommand(request);
|
||||
|
||||
@Test
|
||||
public void testInvalidChangeBatchException() throws IOException {
|
||||
HttpResponse response = HttpResponse.builder().statusCode(400)
|
||||
.payload(payloadFromResource("/invalid_change_batch.xml")).build();
|
||||
function.handleError(command, response);
|
||||
|
||||
InvalidChangeBatchException exception = InvalidChangeBatchException.class.cast(command.getException());
|
||||
|
||||
assertEquals(exception.getMessages(), ImmutableSet.of(
|
||||
"Tried to create resource record set duplicate.example.com. type A, but it already exists",
|
||||
"Tried to delete resource record set noexist.example.com. type A, but it was not found"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteNotFound() throws IOException {
|
||||
|
||||
HttpResponse response = HttpResponse.builder().statusCode(400)
|
||||
.payload(
|
||||
payloadFromStringWithContentType(
|
||||
"<ErrorResponse><Error><Type>Sender</Type><Code>InvalidChangeBatch</Code>"
|
||||
+ "<Message>Tried to delete resource record set krank.foo.bar., type TXT but it was not found</Message>"
|
||||
+ "</Error></ErrorResponse>", "application/xml")).build();
|
||||
|
||||
function.handleError(command, response);
|
||||
|
||||
assertEquals(command.getException().getClass(), ResourceNotFoundException.class);
|
||||
assertEquals(command.getException().getMessage(), "Tried to delete resource record set krank.foo.bar., type TXT but it was not found");
|
||||
|
||||
AWSResponseException exception = AWSResponseException.class.cast(command.getException().getCause());
|
||||
|
||||
assertEquals(exception.getError().getCode(), "InvalidChangeBatch");
|
||||
}
|
||||
|
||||
private Payload payloadFromResource(String resource) {
|
||||
try {
|
||||
return payloadFromStringWithContentType(toStringAndClose(getClass().getResourceAsStream(resource)),
|
||||
"application/xml");
|
||||
} catch (IOException e) {
|
||||
throw propagate(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,13 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.route53.internal;
|
||||
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.route53.Route53Api;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BaseRoute53ApiExpectTest extends BaseRoute53ExpectTest<Route53Api> {
|
||||
protected HttpResponse notFound = HttpResponse.builder().statusCode(404).build();
|
||||
}
|
||||
|
|
|
@ -18,13 +18,20 @@
|
|||
*/
|
||||
package org.jclouds.route53.internal;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.jclouds.route53.domain.Change.Status.INSYNC;
|
||||
import static org.jclouds.util.Predicates2.retry;
|
||||
|
||||
import org.jclouds.apis.BaseContextLiveTest;
|
||||
import org.jclouds.route53.Route53ApiMetadata;
|
||||
import org.jclouds.route53.Route53AsyncApi;
|
||||
import org.jclouds.route53.Route53Api;
|
||||
import org.jclouds.route53.domain.Change;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
|
@ -39,9 +46,21 @@ public class BaseRoute53ApiLiveTest extends
|
|||
provider = "route53";
|
||||
}
|
||||
|
||||
protected Predicate<Change> inSync;
|
||||
|
||||
@BeforeClass(groups = "live")
|
||||
@Override
|
||||
public void setupContext() {
|
||||
super.setupContext();
|
||||
inSync = retry(new Predicate<Change>() {
|
||||
public boolean apply(Change input) {
|
||||
return context.getApi().getChange(input.getId()).getStatus() == INSYNC;
|
||||
}
|
||||
}, 600, 1, 5, SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TypeToken<RestContext<? extends Route53Api, ? extends Route53AsyncApi>> contextType() {
|
||||
return Route53ApiMetadata.CONTEXT_TOKEN;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,9 +19,10 @@
|
|||
package org.jclouds.route53.internal;
|
||||
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.route53.config.Route53RestClientModule;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.internal.BaseRestApiExpectTest;
|
||||
import org.jclouds.route53.config.Route53RestClientModule;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
|
@ -44,6 +45,9 @@ public class BaseRoute53ExpectTest<T> extends BaseRestApiExpectTest<T> {
|
|||
}
|
||||
}
|
||||
|
||||
protected final HttpResponse notFound = HttpResponse.builder().statusCode(404).build();
|
||||
protected final String authForDate = "AWS3-HTTPS AWSAccessKeyId=identity,Algorithm=HmacSHA256,Signature=pylxNiLcrsjNRZOsxyT161JCwytVPHyc2rFfmNCuZKI=";
|
||||
|
||||
@Override
|
||||
protected Module createModule() {
|
||||
return new TestRoute53RestClientModule();
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
/**
|
||||
* 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.route53.options;
|
||||
|
||||
import static org.jclouds.route53.options.ListZonesOptions.Builder.afterMarker;
|
||||
import static org.jclouds.route53.options.ListZonesOptions.Builder.maxItems;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code ListZonesOptions}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ListZonesOptionsTest")
|
||||
public class ListZonesOptionsTest {
|
||||
|
||||
public void testMarker() {
|
||||
ListZonesOptions options = new ListZonesOptions().afterMarker("FFFFF");
|
||||
assertEquals(ImmutableSet.of("FFFFF"), options.buildQueryParameters().get("marker"));
|
||||
}
|
||||
|
||||
public void testMarkerStatic() {
|
||||
ListZonesOptions options = afterMarker("FFFFF");
|
||||
assertEquals(ImmutableSet.of("FFFFF"), options.buildQueryParameters().get("marker"));
|
||||
}
|
||||
|
||||
public void testMaxItems() {
|
||||
ListZonesOptions options = new ListZonesOptions().maxItems(1000);
|
||||
assertEquals(ImmutableSet.of("1000"), options.buildQueryParameters().get("maxitems"));
|
||||
}
|
||||
|
||||
public void testMaxItemsStatic() {
|
||||
ListZonesOptions options = maxItems(1000);
|
||||
assertEquals(ImmutableSet.of("1000"), options.buildQueryParameters().get("maxitems"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* 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.route53.parse;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.jclouds.route53.xml.InvalidChangeBatchHandler;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
// NOTE:without testName, this will not call @Before* and fail w/NPE during
|
||||
// surefire
|
||||
@Test(groups = "unit", testName = "InvalidChangeBatchResponseTest")
|
||||
public class InvalidChangeBatchResponseTest extends BaseHandlerTest {
|
||||
|
||||
public void test() {
|
||||
InputStream is = getClass().getResourceAsStream("/invalid_change_batch.xml");
|
||||
|
||||
InvalidChangeBatchHandler handler = injector.getInstance(InvalidChangeBatchHandler.class);
|
||||
ImmutableList<String> result = factory.create(handler).parse(is);
|
||||
|
||||
assertEquals(result, ImmutableList.of(
|
||||
"Tried to create resource record set duplicate.example.com. type A, but it already exists",
|
||||
"Tried to delete resource record set noexist.example.com. type A, but it was not found"));
|
||||
}
|
||||
}
|
|
@ -23,9 +23,9 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.io.InputStream;
|
||||
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.jclouds.route53.domain.ResourceRecordSet;
|
||||
import org.jclouds.route53.domain.ResourceRecordSet.Type;
|
||||
import org.jclouds.route53.domain.ResourceRecordSetIterable;
|
||||
import org.jclouds.route53.domain.RecordSet;
|
||||
import org.jclouds.route53.domain.RecordSet.Type;
|
||||
import org.jclouds.route53.domain.RecordSetIterable;
|
||||
import org.jclouds.route53.xml.ListResourceRecordSetsResponseHandler;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -40,24 +40,24 @@ public class ListResourceRecordSetsResponseTest extends BaseHandlerTest {
|
|||
public void test() {
|
||||
InputStream is = getClass().getResourceAsStream("/rrsets.xml");
|
||||
|
||||
ResourceRecordSetIterable expected = expected();
|
||||
RecordSetIterable expected = expected();
|
||||
|
||||
ListResourceRecordSetsResponseHandler handler = injector.getInstance(ListResourceRecordSetsResponseHandler.class);
|
||||
ResourceRecordSetIterable result = factory.create(handler).parse(is);
|
||||
RecordSetIterable result = factory.create(handler).parse(is);
|
||||
|
||||
assertEquals(result.toString(), expected.toString());
|
||||
|
||||
}
|
||||
|
||||
public ResourceRecordSetIterable expected() {
|
||||
return ResourceRecordSetIterable.builder()
|
||||
.add(ResourceRecordSet.builder()
|
||||
public RecordSetIterable expected() {
|
||||
return RecordSetIterable.builder()
|
||||
.add(RecordSet.builder()
|
||||
.name("example.com.")
|
||||
.type(Type.SOA)
|
||||
.ttl(900)
|
||||
.add("ns-2048.awsdns-64.net. hostmaster.awsdns.com. 1 7200 900 1209600 86400")
|
||||
.build())
|
||||
.add(ResourceRecordSet.builder()
|
||||
.add(RecordSet.builder()
|
||||
.name("example.com.")
|
||||
.type(Type.NS)
|
||||
.ttl(172800)
|
||||
|
|
|
@ -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.route53.predicates;
|
||||
|
||||
import static org.jclouds.route53.domain.RecordSet.Type.AAAA;
|
||||
import static org.jclouds.route53.domain.RecordSet.Type.NS;
|
||||
import static org.jclouds.route53.predicates.RecordSetPredicates.typeEquals;
|
||||
|
||||
import org.jclouds.route53.domain.RecordSet;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ResourceRecordSetPredicatesTest")
|
||||
public class RecordSetPredicatesTest {
|
||||
RecordSet rrs = RecordSet.builder().name("jclouds.org.").type(NS).add("ns-119.awsdns-14.com.")
|
||||
.build();
|
||||
|
||||
@Test
|
||||
public void testTypeEqualsWhenEqual() {
|
||||
assert typeEquals(NS).apply(rrs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeEqualsWhenNotEqual() {
|
||||
assert !typeEquals(AAAA).apply(rrs);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* 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.route53.predicates;
|
||||
|
||||
import static org.jclouds.route53.predicates.ZonePredicates.nameEquals;
|
||||
|
||||
import org.jclouds.route53.domain.Zone;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ZonePredicatesTest")
|
||||
public class ZonePredicatesTest {
|
||||
Zone zone = Zone.builder().id("EEEFFFEEE").callerReference("goog").name("jclouds.org.").build();
|
||||
|
||||
@Test
|
||||
public void testNameEqualsWhenEqual() {
|
||||
assert nameEquals("jclouds.org.").apply(zone);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNameEqualsWhenNotEqual() {
|
||||
assert !nameEquals("kclouds.org.").apply(zone);
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
<ChangeResourceRecordSetsRequest xmlns="https://route53.amazonaws.com/doc/2012-02-29/"><ChangeBatch><Changes><Change><Action>DELETE</Action><ResourceRecordSet><Name>jclouds.org.</Name><Type>TXT</Type><TTL>0</TTL><ResourceRecords><ResourceRecord><Value>my texts</Value></ResourceRecord></ResourceRecords></ResourceRecordSet></Change><Change><Action>CREATE</Action><ResourceRecordSet><Name>jclouds.org.</Name><Type>TXT</Type><TTL>0</TTL><ResourceRecords><ResourceRecord><Value>my better texts</Value></ResourceRecord></ResourceRecords></ResourceRecordSet></Change></Changes></ChangeBatch></ChangeResourceRecordSetsRequest>
|
|
@ -0,0 +1 @@
|
|||
<ChangeResourceRecordSetsRequest xmlns="https://route53.amazonaws.com/doc/2012-02-29/"><ChangeBatch><Changes><Change><Action>CREATE</Action><ResourceRecordSet><Name>jclouds.org.</Name><Type>TXT</Type><TTL>0</TTL><ResourceRecords><ResourceRecord><Value>my texts</Value></ResourceRecord></ResourceRecords></ResourceRecordSet></Change></Changes></ChangeBatch></ChangeResourceRecordSetsRequest>
|
|
@ -0,0 +1 @@
|
|||
<ChangeResourceRecordSetsRequest xmlns="https://route53.amazonaws.com/doc/2012-02-29/"><ChangeBatch><Changes><Change><Action>CREATE</Action><ResourceRecordSet><Name>jclouds.org.</Name><Type>TXT</Type><TTL>0</TTL><ResourceRecords><ResourceRecord><Value>my texts</Value></ResourceRecord></ResourceRecords></ResourceRecordSet></Change></Changes></ChangeBatch></ChangeResourceRecordSetsRequest>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0"?>
|
||||
<InvalidChangeBatch xmlns="https://route53.amazonaws.com/doc/2012-02-29/">
|
||||
<Messages>
|
||||
<Message>Tried to create resource record set duplicate.example.com. type A, but it already exists</Message>
|
||||
<Message>Tried to delete resource record set noexist.example.com. type A, but it was not found</Message>
|
||||
</Messages>
|
||||
</InvalidChangeBatch>
|
Loading…
Reference in New Issue