added geo read-only commands to dynect

This commit is contained in:
adriancole 2013-04-17 21:56:48 -07:00
parent 47f6801612
commit 160fa9527b
25 changed files with 1954 additions and 53 deletions

View File

@ -30,6 +30,8 @@ import javax.ws.rs.PathParam;
import org.jclouds.Fallbacks.NullOnNotFoundOr404; import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.dynect.v3.domain.Job; import org.jclouds.dynect.v3.domain.Job;
import org.jclouds.dynect.v3.features.GeoRegionGroupApi;
import org.jclouds.dynect.v3.features.GeoServiceApi;
import org.jclouds.dynect.v3.features.RecordApi; import org.jclouds.dynect.v3.features.RecordApi;
import org.jclouds.dynect.v3.features.SessionApi; import org.jclouds.dynect.v3.features.SessionApi;
import org.jclouds.dynect.v3.features.ZoneApi; import org.jclouds.dynect.v3.features.ZoneApi;
@ -67,20 +69,32 @@ public interface DynECTApi extends Closeable {
Job getJob(@PathParam("jobId") long jobId); Job getJob(@PathParam("jobId") long jobId);
/** /**
* Provides synchronous access to Session features. * Provides access to Session features.
*/ */
@Delegate @Delegate
SessionApi getSessionApi(); SessionApi getSessionApi();
/** /**
* Provides synchronous access to Zone features. * Provides access to Zone features.
*/ */
@Delegate @Delegate
ZoneApi getZoneApi(); ZoneApi getZoneApi();
/** /**
* Provides synchronous access to Record features * Provides access to Record features
*/ */
@Delegate @Delegate
RecordApi getRecordApiForZone(@PathParam("zone") String zone); RecordApi getRecordApiForZone(@PathParam("zone") String zone);
/**
* Provides access to Geo features.
*/
@Delegate
GeoServiceApi getGeoServiceApi();
/**
* Provides access to Geo region group features
*/
@Delegate
GeoRegionGroupApi getGeoRegionGroupApiForService(@PathParam("serviceName") String serviceName);
} }

View File

@ -19,15 +19,27 @@
package org.jclouds.dynect.v3.config; package org.jclouds.dynect.v3.config;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.dynect.v3.domain.GeoService;
import org.jclouds.dynect.v3.domain.Node;
import org.jclouds.dynect.v3.domain.RecordSet;
import org.jclouds.dynect.v3.domain.RecordSet.Value;
import org.jclouds.dynect.v3.domain.RecordSet.Value.Builder;
import org.jclouds.dynect.v3.domain.GeoRegionGroup;
import org.jclouds.dynect.v3.domain.SessionCredentials; import org.jclouds.dynect.v3.domain.SessionCredentials;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer; import com.google.gson.JsonSerializer;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
@ -46,8 +58,9 @@ public class DynECTParserModule extends AbstractModule {
@Singleton @Singleton
public Map<Type, Object> provideCustomAdapterBindings() { public Map<Type, Object> provideCustomAdapterBindings() {
return new ImmutableMap.Builder<Type, Object>() return new ImmutableMap.Builder<Type, Object>()
.put(SessionCredentials.class, new SessionCredentialsTypeAdapter()) .put(SessionCredentials.class, new SessionCredentialsTypeAdapter())
.build(); .put(GeoRegionGroup.class, new GeoRegionGroupTypeAdapter())
.put(GeoService.class, new GeoServiceTypeAdapter()).build();
} }
private static class SessionCredentialsTypeAdapter implements JsonSerializer<SessionCredentials> { private static class SessionCredentialsTypeAdapter implements JsonSerializer<SessionCredentials> {
@ -59,4 +72,87 @@ public class DynECTParserModule extends AbstractModule {
return metadataObject; return metadataObject;
} }
} }
private static class GeoRegionGroupTypeAdapter implements JsonDeserializer<GeoRegionGroup> {
@Override
public GeoRegionGroup deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
CreepyGeoRegionGroup creepyGeoRegionGroup = context.deserialize(json, CreepyGeoRegionGroup.class);
GeoRegionGroup.Builder builder = GeoRegionGroup.builder();
builder.name(creepyGeoRegionGroup.name);
builder.serviceName(creepyGeoRegionGroup.service_name);
builder.countries(creepyGeoRegionGroup.countries);
ImmutableList.Builder<RecordSet> rsets = ImmutableList.builder();
for (Entry<String, List<Map<String, Object>>> entry : creepyGeoRegionGroup.rdata.entrySet()) {
if (entry.getValue().isEmpty())
continue;
// ex. spf_rdata -> SPF
String type = entry.getKey().substring(0, entry.getKey().indexOf('_')).toUpperCase();
// ex. dhcid_ttl
int ttl = creepyGeoRegionGroup.ttl.get(type.toLowerCase() + "_ttl");
RecordSet.Builder rset = RecordSet.builder();
rset.type(type);
rset.ttl(ttl);
// weight is only present for a couple record types
List<Integer> weights = creepyGeoRegionGroup.weight.get(type.toLowerCase() + "_weight");
if (weights == null)
weights = ImmutableList.of();
List<String> labels = creepyGeoRegionGroup.label.get(type.toLowerCase() + "_label");
for (int i = 0; i < entry.getValue().size(); i++) {
Builder elementBuilder = Value.builder().rdata(entry.getValue().get(i));
// chance of index out of bounds
if (i < labels.size())
elementBuilder.label(labels.get(i));
if (i < weights.size())
elementBuilder.weight(weights.get(i));
rset.add(elementBuilder.build());
}
rsets.add(rset.build());
}
builder.recordSets(rsets.build());
return builder.build();
}
}
private static class CreepyGeoRegionGroup {
String name;
// aaaa_weight
Map<String, List<Integer>> weight;
List<String> countries;
String service_name;
// spf_rdata
Map<String, List<Map<String, Object>>> rdata;
// a_label
Map<String, List<String>> label;
// dhcid_ttl
Map<String, Integer> ttl;
}
private static class GeoServiceTypeAdapter implements JsonDeserializer<GeoService> {
@Override
public GeoService deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
CreepyGeoService creepyGeoService = context.deserialize(json, CreepyGeoService.class);
GeoService.Builder builder = GeoService.builder();
builder.name(creepyGeoService.name);
builder.active("Y".equals(creepyGeoService.active));
builder.ttl(creepyGeoService.ttl);
builder.nodes(creepyGeoService.nodes);
builder.groups(creepyGeoService.groups);
return builder.build();
}
}
private static class CreepyGeoService {
String name;
String active;// creepy part
int ttl;
List<Node> nodes;
List<GeoRegionGroup> groups;
}
} }

View File

@ -0,0 +1,193 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, String 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.dynect.v3.domain;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.List;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
/**
* @author Adrian Cole
*/
public class GeoRegionGroup {
private final Optional<String> serviceName;
private final String name;
private final List<String> countries;
private final List<RecordSet> recordSets;
private GeoRegionGroup(Optional<String> serviceName, String name, List<String> countries, List<RecordSet> recordSets) {
this.serviceName = checkNotNull(serviceName, "serviceName");
this.name = checkNotNull(name, "name");
this.countries = checkNotNull(countries, "countries of %s/%s", serviceName, name);
this.recordSets = checkNotNull(recordSets, "recordSets of %s", name);
}
/**
* Name of the Geo Service. Absent, if a member of {@link GeoService}
*/
public Optional<String> getServiceName() {
return serviceName;
}
/**
* Name of the Region Group
*/
public String getName() {
return name;
}
/**
* A list of ISO-3166 two letter codes to represent the names of countries
* and their subdivisions or one of the predefined groups.
*/
public List<String> getCountries() {
return countries;
}
/**
* record sets assigned to this region group.
*/
public List<RecordSet> getRecordSets() {
return recordSets;
}
@Override
public int hashCode() {
return Objects.hashCode(serviceName, name, countries, recordSets);
}
/**
* permits equals comparisons with subtypes
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || !(obj instanceof GeoRegionGroup))
return false;
GeoRegionGroup that = GeoRegionGroup.class.cast(obj);
return equal(this.serviceName, that.serviceName) && equal(this.name, that.name)
&& equal(this.countries, that.countries) && equal(this.recordSets, that.recordSets);
}
@Override
public String toString() {
return toStringHelper(this).add("serviceName", serviceName.orNull()).add("name", name)
.add("countries", countries).add("recordSets", recordSets).toString();
}
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return builder().from(this);
}
public static class Builder {
private Optional<String> serviceName = Optional.absent();
private String name;
private ImmutableList.Builder<String> countries = ImmutableList.builder();
private ImmutableList.Builder<RecordSet> recordSets = ImmutableList.builder();
/**
* @see GeoRegionGroup#getServiceName()
*/
public Builder serviceName(String serviceName) {
this.serviceName = Optional.fromNullable(serviceName);
return this;
}
/**
* @see GeoRegionGroup#getName()
*/
public Builder name(String name) {
this.name = name;
return this;
}
/**
* @see GeoRegionGroup#getCountries()
*/
public Builder addCountry(String country) {
this.countries.add(country);
return this;
}
/**
* replaces current record sets
*
* @see GeoRegionGroup#getCountries()
*/
public Builder countries(Iterable<String> countries) {
this.countries = ImmutableList.<String> builder().addAll(countries);
return this;
}
/**
* @see GeoRegionGroup#getCountries()
*/
public Builder addAllCountries(Iterable<String> countries) {
this.countries.addAll(countries);
return this;
}
/**
* @see GeoRegionGroup#getRecordSets()
*/
public Builder addRecordSet(RecordSet recordSet) {
this.recordSets.add(recordSet);
return this;
}
/**
* replaces current record sets
*
* @see GeoRegionGroup#getRecordSets()
*/
public Builder recordSets(Iterable<RecordSet> recordSets) {
this.recordSets = ImmutableList.<RecordSet> builder().addAll(recordSets);
return this;
}
/**
* @see GeoRegionGroup#getRecordSets()
*/
public Builder addAllRecordSets(Iterable<RecordSet> recordSets) {
this.recordSets.addAll(recordSets);
return this;
}
public GeoRegionGroup build() {
return new GeoRegionGroup(serviceName, name, countries.build(), recordSets.build());
}
public Builder from(GeoRegionGroup in) {
return serviceName(in.serviceName.orNull()).name(in.name).countries(in.countries).recordSets(in.recordSets);
}
}
}

View File

@ -0,0 +1,195 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, String 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.dynect.v3.domain;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.List;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
/**
* @author Adrian Cole
*/
public class GeoService {
private final String name;
private final boolean active;
private final int ttl;
private final List<Node> nodes;
private final List<GeoRegionGroup> groups;
private GeoService(String name, boolean active, int ttl, List<Node> nodes, List<GeoRegionGroup> groups) {
this.name = checkNotNull(name, "name");
this.active = checkNotNull(active, "active");
this.ttl = checkNotNull(ttl, "ttl");
this.nodes = checkNotNull(nodes, "nodes of %s", name);
this.groups = checkNotNull(groups, "groups of %s", name);
}
public String getName() {
return name;
}
public boolean isActive() {
return active;
}
public int getTTL() {
return ttl;
}
public List<Node> getNodes() {
return nodes;
}
public List<GeoRegionGroup> getGroups() {
return groups;
}
@Override
public int hashCode() {
return Objects.hashCode(active, name, nodes, groups);
}
/**
* permits equals comparisons with subtypes
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || !(obj instanceof GeoService))
return false;
GeoService that = GeoService.class.cast(obj);
return equal(this.active, that.active) && equal(this.name, that.name) && equal(this.ttl, that.ttl)
&& equal(this.nodes, that.nodes) && equal(this.groups, that.groups);
}
@Override
public String toString() {
return toStringHelper(this).add("active", active).add("name", name).add("ttl", ttl).add("nodes", nodes).add("groups", groups)
.toString();
}
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return builder().from(this);
}
public static class Builder {
private String name;
private boolean active;
protected int ttl = -1;
private ImmutableList.Builder<Node> nodes = ImmutableList.builder();
private ImmutableList.Builder<GeoRegionGroup> groups = ImmutableList.builder();
/**
* @see GeoService#getName()
*/
public Builder name(String name) {
this.name = name;
return this;
}
/**
* @see GeoService#isActive()
*/
public Builder active(boolean active) {
this.active = active;
return this;
}
/**
* @see Builder#getTTL()
*/
public Builder ttl(int ttl) {
this.ttl = ttl;
return this;
}
/**
* @see GeoService#getNodes()
*/
public Builder addNode(Node node) {
this.nodes.add(node);
return this;
}
/**
* replaces current region groups
*
* @see GeoService#getNodes()
*/
public Builder nodes(Iterable<Node> nodes) {
this.nodes = ImmutableList.<Node> builder().addAll(nodes);
return this;
}
/**
* @see GeoService#getNodes()
*/
public Builder addAllNodes(Iterable<Node> nodes) {
this.nodes.addAll(nodes);
return this;
}
/**
* @see GeoService#getGroups()
*/
public Builder addGroup(GeoRegionGroup group) {
this.groups.add(group);
return this;
}
/**
* replaces current region groups
*
* @see GeoService#getGroups()
*/
public Builder groups(Iterable<GeoRegionGroup> groups) {
this.groups = ImmutableList.<GeoRegionGroup> builder().addAll(groups);
return this;
}
/**
* @see GeoService#getGroups()
*/
public Builder addAllGroups(Iterable<GeoRegionGroup> groups) {
this.groups.addAll(groups);
return this;
}
public GeoService build() {
return new GeoService(name, active, ttl, nodes.build(), groups.build());
}
public Builder from(GeoService in) {
return name(in.name).active(in.active).ttl(in.ttl).nodes(in.nodes).groups(in.groups);
}
}
}

View File

@ -0,0 +1,77 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, String 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.dynect.v3.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import com.google.common.base.Objects;
public class Node {
public static Node create(String fqdn, String zone) {
return new Node(fqdn, zone);
}
private final String fqdn;
private final String zone;
@ConstructorProperties({ "fqdn", "zone" })
protected Node(String fqdn, String zone) {
this.fqdn = checkNotNull(fqdn, "fqdn");
this.zone = checkNotNull(zone, "zone for %s", fqdn);
}
/**
* Fully qualified domain name of a node in the zone
*/
public String getFQDN() {
return fqdn;
}
/**
* Name of the zone
*/
public String getZone() {
return zone;
}
@Override
public int hashCode() {
return Objects.hashCode(fqdn, zone);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node that = Node.class.cast(obj);
return Objects.equal(this.fqdn, that.fqdn) && Objects.equal(this.zone, that.zone);
}
@Override
public String toString() {
return Objects.toStringHelper("").add("fqdn", fqdn).add("zone", zone).toString();
}
}

View File

@ -30,35 +30,18 @@ import com.google.common.base.Objects.ToStringHelper;
/** /**
* @author Adrian Cole * @author Adrian Cole
*/ */
public class RecordId { public class RecordId extends Node {
private final long id; private final long id;
private final String zone;
private final String fqdn;
private final String type; private final String type;
@ConstructorProperties({ "zone", "fqdn", "record_type", "record_id" }) @ConstructorProperties({"fqdn", "zone", "record_type", "record_id" })
RecordId(String zone, String fqdn, String type, long id) { RecordId(String fqdn, String zone, String type, long id) {
super(fqdn, zone);
this.id = checkNotNull(id, "id"); this.id = checkNotNull(id, "id");
this.fqdn = checkNotNull(fqdn, "fqdn of %s", id);
this.zone = checkNotNull(zone, "zone of %s", id);
this.type = checkNotNull(type, "type of %s", id); this.type = checkNotNull(type, "type of %s", id);
} }
/**
* Name of the zone
*/
public String getZone() {
return zone;
}
/**
* Fully qualified domain name of a node in the zone
*/
public String getFQDN() {
return fqdn;
}
/** /**
* The RRType of the record * The RRType of the record
*/ */
@ -75,7 +58,7 @@ public class RecordId {
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hashCode(zone, fqdn, type, id); return Objects.hashCode(getZone(), getFQDN(), type, id);
} }
/** /**
@ -88,8 +71,7 @@ public class RecordId {
if (obj == null || !(obj instanceof RecordId)) if (obj == null || !(obj instanceof RecordId))
return false; return false;
RecordId that = RecordId.class.cast(obj); RecordId that = RecordId.class.cast(obj);
return equal(this.zone, that.zone) && equal(this.fqdn, that.fqdn) && equal(this.type, that.type) return super.equals(obj) && equal(this.type, that.type) && equal(this.id, that.id);
&& equal(this.id, that.id);
} }
@Override @Override
@ -98,7 +80,7 @@ public class RecordId {
} }
protected ToStringHelper string() { protected ToStringHelper string() {
return toStringHelper(this).add("zone", zone).add("fqdn", fqdn).add("type", type).add("id", id); return toStringHelper(this).add("fqdn", getFQDN()).add("zone", getZone()).add("type", type).add("id", id);
} }
public static Builder<?> recordIdBuilder() { public static Builder<?> recordIdBuilder() {
@ -112,24 +94,24 @@ public class RecordId {
public abstract static class Builder<B extends Builder<B>> { public abstract static class Builder<B extends Builder<B>> {
protected abstract B self(); protected abstract B self();
protected String zone;
protected String fqdn; protected String fqdn;
protected String zone;
protected String type; protected String type;
protected long id; protected long id;
/** /**
* @see RecordId#getZone() * @see Node#getFQDN()
*/ */
public B zone(String zone) { public B fqdn(String fqdn) {
this.zone = zone; this.fqdn = fqdn;
return self(); return self();
} }
/** /**
* @see RecordId#getFQDN() * @see Node#getZone()
*/ */
public B fqdn(String fqdn) { public B zone(String zone) {
this.fqdn = fqdn; this.zone = zone;
return self(); return self();
} }
@ -150,11 +132,11 @@ public class RecordId {
} }
public RecordId build() { public RecordId build() {
return new RecordId(zone, fqdn, type, id); return new RecordId(fqdn, zone, type, id);
} }
public B from(RecordId in) { public B from(RecordId in) {
return zone(in.zone).fqdn(in.fqdn).type(in.type).id(in.id); return fqdn(in.getFQDN()).zone(in.getZone()).type(in.type).id(in.id);
} }
} }

View File

@ -0,0 +1,238 @@
package org.jclouds.dynect.v3.domain;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.List;
import java.util.Map;
import org.jclouds.dynect.v3.domain.RecordSet.Value;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.collect.ForwardingList;
import com.google.common.collect.ImmutableList;
/**
* A set of records which shared the same name, type, and ttl
*
* @author Adrian Cole
*/
public class RecordSet extends ForwardingList<Value> {
private final String type;
private final int ttl;
private transient final List<Value> values;
private RecordSet(String type, int ttl, List<Value> values) {
this.type = checkNotNull(type, "type");
this.ttl = ttl;
checkArgument(ttl >= 0, "ttl must be >=0");
this.values = checkNotNull(values, "values");
}
/**
* @see Record#getType()
*/
public String getType() {
return type;
}
/**
* @see Record#getTTL()
*/
public int getTTL() {
return ttl;
}
public static class Value {
private final Optional<String> label;
private final Optional<Integer> weight;
private final Map<String, Object> rdata;
private Value(Optional<String> label, Optional<Integer> weight, Map<String, Object> rdata) {
this.label = checkNotNull(label, "label");
this.weight = checkNotNull(weight, "weight");
this.rdata = checkNotNull(rdata, "rdata");
}
/**
* The label of the value.
*/
public Optional<String> getLabel() {
return label;
}
/**
* The relative weight of the value.
*/
public Optional<Integer> getWeight() {
return weight;
}
/**
* @see Record#getRData()
*/
public Map<String, Object> getRData() {
return rdata;
}
@Override
public int hashCode() {
return Objects.hashCode(label, weight, rdata);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
Value that = Value.class.cast(obj);
return equal(this.label, that.label) && equal(this.weight, that.weight) && equal(this.rdata, that.rdata);
}
@Override
public String toString() {
return toStringHelper("").omitNullValues().add("label", label.orNull()).add("weight", weight.orNull())
.add("rdata", rdata).toString();
}
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return new Builder().from(this);
}
public final static class Builder {
private Optional<String> label = Optional.absent();
private Optional<Integer> weight = Optional.absent();
private Map<String, Object> rdata;
/**
* @see Value#getLabel()
*/
public Builder label(String label) {
this.label = Optional.fromNullable(label);
return this;
}
/**
* @see Value#getWeight()
*/
public Builder weight(Integer weight) {
this.weight = Optional.fromNullable(weight);
return this;
}
/**
* @see Record#getRData()
*/
public Builder rdata(Map<String, Object> rdata) {
this.rdata = rdata;
return this;
}
public Value build() {
return new Value(label, weight, rdata);
}
public Builder from(Value in) {
return label(in.label.orNull()).weight(in.weight.orNull()).rdata(in.rdata);
}
}
}
@Override
public int hashCode() {
return Objects.hashCode(type, ttl, values);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
RecordSet that = RecordSet.class.cast(obj);
return equal(this.type, that.type) && equal(this.ttl, that.ttl) && equal(this.values, that.values);
}
@Override
public String toString() {
return toStringHelper("").omitNullValues().add("type", type).add("ttl", ttl).add("values", values).toString();
}
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return new Builder().from(this);
}
public final static class Builder {
private String type;
private int ttl = -1;
private ImmutableList.Builder<Value> values = ImmutableList.builder();
/**
* @see RecordSet#getType()
*/
public Builder type(String type) {
this.type = type;
return this;
}
/**
* @see RecordSet#getTTL()
*/
public Builder ttl(int ttl) {
this.ttl = ttl;
return this;
}
/**
* @see RecordSet#iterator()
*/
public Builder add(Value value) {
this.values.add(value);
return this;
}
/**
* replaces current values
*
* @see RecordSet#iterator()
*/
public Builder values(Iterable<Value> values) {
this.values = ImmutableList.<Value> builder().addAll(values);
return this;
}
/**
* @see RecordSet#iterator()
*/
public Builder addAll(Iterable<Value> values) {
this.values.addAll(values);
return this;
}
public RecordSet build() {
return new RecordSet(type, ttl, values.build());
}
public Builder from(RecordSet in) {
return type(in.type).ttl(in.ttl).values(in.values);
}
}
@Override
protected List<Value> delegate() {
return values;
}
}

View File

@ -0,0 +1,80 @@
/**
* 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.dynect.v3.features;
import javax.inject.Named;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.dynect.v3.DynECTExceptions.JobStillRunningException;
import org.jclouds.dynect.v3.domain.GeoRegionGroup;
import org.jclouds.dynect.v3.filters.AlwaysAddContentType;
import org.jclouds.dynect.v3.filters.SessionManager;
import org.jclouds.dynect.v3.functions.ExtractLastPathComponent;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.Transform;
import com.google.common.collect.FluentIterable;
/**
* @see <a
* href="https://manage.dynect.net/help/docs/api2/rest/resources/Geo.html"
* />
* @author Adrian Cole
*/
@Headers(keys = "API-Version", values = "{jclouds.api-version}")
@Path("/GeoRegionGroup/{serviceName}")
@RequestFilters({ AlwaysAddContentType.class, SessionManager.class })
public interface GeoRegionGroupApi {
/**
* Lists all geo region group names.
*
* @throws JobStillRunningException
* if a different job in the session is still running
*/
@Named("ListGeoRegionGroupNames")
@GET
@SelectJson("data")
@Transform(ExtractLastPathComponent.class)
FluentIterable<String> list() throws JobStillRunningException;
/**
* Retrieves information about the specified geo region group
*
* @param groupName
* name of the group to get information about. ex
* {@code api-prod}
* @return null if not found
* @throws JobStillRunningException
* if a different job in the session is still running
*/
@Named("GetGeoRegionGroup")
@GET
@Path("/{groupName}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
GeoRegionGroup get(@PathParam("groupName") String groupName) throws JobStillRunningException;
}

View File

@ -0,0 +1,80 @@
/**
* 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.dynect.v3.features;
import javax.inject.Named;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.dynect.v3.DynECTExceptions.JobStillRunningException;
import org.jclouds.dynect.v3.domain.GeoService;
import org.jclouds.dynect.v3.filters.AlwaysAddContentType;
import org.jclouds.dynect.v3.filters.SessionManager;
import org.jclouds.dynect.v3.functions.ExtractLastPathComponent;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.Transform;
import com.google.common.collect.FluentIterable;
/**
* @see <a
* href="https://manage.dynect.net/help/docs/api2/rest/resources/Geo.html"
* />
* @author Adrian Cole
*/
@Headers(keys = "API-Version", values = "{jclouds.api-version}")
@Path("/Geo")
@RequestFilters({ AlwaysAddContentType.class, SessionManager.class })
public interface GeoServiceApi {
/**
* Lists all geo service names.
*
* @throws JobStillRunningException
* if a different job in the session is still running
*/
@Named("ListGeoServiceNames")
@GET
@SelectJson("data")
@Transform(ExtractLastPathComponent.class)
FluentIterable<String> list() throws JobStillRunningException;
/**
* Retrieves information about the specified geo service.
*
* @param serviceName
* name of the service to get information about. ex
* {@code api-prod}
* @return null if not found
* @throws JobStillRunningException
* if a different job in the session is still running
*/
@Named("GetGeoService")
@GET
@Path("/{serviceName}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
GeoService get(@PathParam("serviceName") String serviceName) throws JobStillRunningException;
}

View File

@ -40,7 +40,7 @@ import org.jclouds.dynect.v3.domain.Zone;
import org.jclouds.dynect.v3.domain.Zone.SerialStyle; import org.jclouds.dynect.v3.domain.Zone.SerialStyle;
import org.jclouds.dynect.v3.filters.AlwaysAddContentType; import org.jclouds.dynect.v3.filters.AlwaysAddContentType;
import org.jclouds.dynect.v3.filters.SessionManager; import org.jclouds.dynect.v3.filters.SessionManager;
import org.jclouds.dynect.v3.functions.ExtractZoneNames; import org.jclouds.dynect.v3.functions.ExtractLastPathComponent;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.BinderParam;
@ -72,7 +72,7 @@ public interface ZoneApi {
@GET @GET
@Path("/Zone") @Path("/Zone")
@SelectJson("data") @SelectJson("data")
@Transform(ExtractZoneNames.class) @Transform(ExtractLastPathComponent.class)
FluentIterable<String> list() throws JobStillRunningException; FluentIterable<String> list() throws JobStillRunningException;
/** /**

View File

@ -18,28 +18,34 @@
*/ */
package org.jclouds.dynect.v3.functions; package org.jclouds.dynect.v3.functions;
import static com.google.common.base.Preconditions.checkState;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.FluentIterable; import com.google.common.collect.FluentIterable;
/** /**
* Zones come back encoded in REST paths, such as * Zones, Geo Services, and Geo region groups come back encoded in REST paths, such as
* {@code /REST/Zone/jclouds.org/} * {@code /REST/Geo/srv-global/}
* *
* @author Adrian Cole * @author Adrian Cole
* *
*/ */
public final class ExtractZoneNames implements Function<FluentIterable<String>, FluentIterable<String>> { public final class ExtractLastPathComponent implements Function<FluentIterable<String>, FluentIterable<String>> {
public FluentIterable<String> apply(FluentIterable<String> in) { public FluentIterable<String> apply(FluentIterable<String> in) {
return in.transform(ExtractNameInPath.INSTANCE); return in.transform(ExtractNameInPath.INSTANCE);
} }
static enum ExtractNameInPath implements Function<String, String> { static enum ExtractNameInPath implements Function<String, String> {
INSTANCE; INSTANCE;
public static final Pattern DEFAULT_PATTERN = Pattern.compile("/REST.*/([^/]+)/?$");
final int position = "/REST/Zone/".length();
public String apply(String in) { public String apply(String in) {
return in.substring(position, in.length() - 1); Matcher matcher = DEFAULT_PATTERN.matcher(in);
checkState(matcher.find() && matcher.groupCount() == 1, "%s didn't match %s", in, DEFAULT_PATTERN);
return matcher.group(1);
} }
} }
} }

View File

@ -0,0 +1,67 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, String 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.dynect.v3.features;
import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
import static javax.ws.rs.HttpMethod.GET;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.Response.Status.OK;
import static org.testng.Assert.assertEquals;
import org.jclouds.dynect.v3.DynECTApi;
import org.jclouds.dynect.v3.internal.BaseDynECTApiExpectTest;
import org.jclouds.dynect.v3.parse.ListGeoRegionGroupsResponseTest;
import org.jclouds.dynect.v3.parse.GetGeoRegionGroupResponseTest;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.testng.annotations.Test;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "GeoRegionGroupApiExpectTest")
public class GeoRegionGroupApiExpectTest extends BaseDynECTApiExpectTest {
HttpRequest list = HttpRequest.builder().method(GET).endpoint("https://api2.dynect.net/REST/GeoRegionGroup/srv")
.addHeader("API-Version", "3.3.8").addHeader(CONTENT_TYPE, APPLICATION_JSON)
.addHeader("Auth-Token", authToken).build();
HttpResponse listResponse = HttpResponse.builder().statusCode(OK.getStatusCode())
.payload(payloadFromResourceWithContentType("/list_geo_regiongroups.json", APPLICATION_JSON)).build();
public void testListWhenResponseIs2xx() {
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, list, listResponse);
assertEquals(success.getGeoRegionGroupApiForService("srv").list().toString(),
new ListGeoRegionGroupsResponseTest().expected().toString());
}
HttpRequest get = HttpRequest.builder().method(GET)
.endpoint("https://api2.dynect.net/REST/GeoRegionGroup/srv/Everywhere%20Else")
.addHeader("API-Version", "3.3.8").addHeader(CONTENT_TYPE, APPLICATION_JSON)
.addHeader("Auth-Token", authToken).build();
HttpResponse getResponse = HttpResponse.builder().statusCode(OK.getStatusCode())
.payload(payloadFromResourceWithContentType("/get_geo_regiongroup.json", APPLICATION_JSON)).build();
public void testGetWhenResponseIs2xx() {
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, get, getResponse);
assertEquals(success.getGeoRegionGroupApiForService("srv").get("Everywhere Else").toString(),
new GetGeoRegionGroupResponseTest().expected().toString());
}
}

View File

@ -0,0 +1,81 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, String 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.dynect.v3.features;
import static java.util.logging.Logger.getAnonymousLogger;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import org.jclouds.dynect.v3.domain.RecordSet;
import org.jclouds.dynect.v3.domain.RecordSet.Value;
import org.jclouds.dynect.v3.domain.GeoRegionGroup;
import org.jclouds.dynect.v3.internal.BaseDynECTApiLiveTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
/**
* @author Adrian Cole
*/
@Test(groups = "live", singleThreaded = true, testName = "GeoRegionGroupApiLiveTest")
public class GeoRegionGroupApiLiveTest extends BaseDynECTApiLiveTest {
@Test
protected void testListAndGetGeoRegionGroups() {
for (String service : geoApi().list()) {
GeoRegionGroupApi api = api(service);
ImmutableList<String> groups = api.list().toList();
getAnonymousLogger().info("geo service: " + service + " group count: " + groups.size());
for (String group : groups) {
GeoRegionGroup groupDetail = api.get(group);
assertNotNull(groupDetail.getServiceName().get(), "ServiceName cannot be null " + groupDetail);
checkGeoRegionGroup(groupDetail);
}
}
}
static void checkGeoRegionGroup(GeoRegionGroup group) {
assertNotNull(group.getName(), "Name cannot be null " + group);
assertTrue(group.getCountries().size() > 0, "countries must be assigned " + group);
assertTrue(group.getRecordSets().size() > 0, "RecordSets must be assigned " + group);
for (RecordSet recordSet : group.getRecordSets())
checkRecordSet(recordSet);
}
static void checkRecordSet(RecordSet rset) {
assertNotNull(rset.getType(), "Type cannot be null " + rset);
assertTrue(rset.getTTL() >= 0, "TTL cannot be negative " + rset);
for (Value value : rset)
checkValue(value);
}
static void checkValue(Value value) {
assertNotNull(value.getLabel(), "Label cannot be null " + value);
assertNotNull(value.getWeight(), "Weight cannot be null " + value);
assertTrue(value.getRData().size() > 0, "RData entries should be present: " + value);
}
protected GeoRegionGroupApi api(String serviceName) {
return api.getGeoRegionGroupApiForService(serviceName);
}
protected GeoServiceApi geoApi() {
return api.getGeoServiceApi();
}
}

View File

@ -0,0 +1,66 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, String 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.dynect.v3.features;
import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
import static javax.ws.rs.HttpMethod.GET;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.Response.Status.OK;
import static org.testng.Assert.assertEquals;
import org.jclouds.dynect.v3.DynECTApi;
import org.jclouds.dynect.v3.internal.BaseDynECTApiExpectTest;
import org.jclouds.dynect.v3.parse.GetGeoServiceResponseTest;
import org.jclouds.dynect.v3.parse.ListGeoServicesResponseTest;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.testng.annotations.Test;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "GeoServiceApiExpectTest")
public class GeoServiceApiExpectTest extends BaseDynECTApiExpectTest {
HttpRequest list = HttpRequest.builder().method(GET).endpoint("https://api2.dynect.net/REST/Geo")
.addHeader("API-Version", "3.3.8").addHeader(CONTENT_TYPE, APPLICATION_JSON)
.addHeader("Auth-Token", authToken).build();
HttpResponse listResponse = HttpResponse.builder().statusCode(OK.getStatusCode())
.payload(payloadFromResourceWithContentType("/list_geo_services.json", APPLICATION_JSON)).build();
public void testListWhenResponseIs2xx() {
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, list, listResponse);
assertEquals(success.getGeoServiceApi().list().toString(), new ListGeoServicesResponseTest().expected()
.toString());
}
HttpRequest get = HttpRequest.builder().method(GET).endpoint("https://api2.dynect.net/REST/Geo/srv")
.addHeader("API-Version", "3.3.8").addHeader(CONTENT_TYPE, APPLICATION_JSON)
.addHeader("Auth-Token", authToken).build();
HttpResponse getResponse = HttpResponse.builder().statusCode(OK.getStatusCode())
.payload(payloadFromResourceWithContentType("/get_geo_service.json", APPLICATION_JSON)).build();
public void testGetWhenResponseIs2xx() {
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, get, getResponse);
assertEquals(success.getGeoServiceApi().get("srv").toString(), new GetGeoServiceResponseTest().expected()
.toString());
}
}

View File

@ -0,0 +1,60 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, String 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.dynect.v3.features;
import static java.util.logging.Logger.getAnonymousLogger;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import org.jclouds.dynect.v3.domain.GeoService;
import org.jclouds.dynect.v3.domain.GeoRegionGroup;
import org.jclouds.dynect.v3.internal.BaseDynECTApiLiveTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
/**
* @author Adrian Cole
*/
@Test(groups = "live", singleThreaded = true, testName = "GeoServiceApiLiveTest")
public class GeoServiceApiLiveTest extends BaseDynECTApiLiveTest {
@Test
protected void testListAndGetGeoServices() {
ImmutableList<String> geos = api().list().toList();
getAnonymousLogger().info("geo services: " + geos.size());
for (String fqdn : geos) {
GeoService geo = api().get(fqdn);
checkGeoService(geo);
}
}
static void checkGeoService(GeoService service) {
assertNotNull(service.getName(), "Name cannot be null " + service);
assertTrue(service.getTTL() >= 0, "TTL cannot be negative " + service);
assertTrue(service.getNodes().size() > 0, "Nodes must be assigned " + service);
assertTrue(service.getGroups().size() > 0, "Groups must be assigned " + service);
for (GeoRegionGroup group : service.getGroups())
GeoRegionGroupApiLiveTest.checkGeoRegionGroup(group);
}
protected GeoServiceApi api() {
return api.getGeoServiceApi();
}
}

View File

@ -21,7 +21,7 @@ package org.jclouds.dynect.v3.functions;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import org.jclouds.dynect.v3.functions.ExtractZoneNames.ExtractNameInPath; import org.jclouds.dynect.v3.functions.ExtractLastPathComponent.ExtractNameInPath;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.FluentIterable; import com.google.common.collect.FluentIterable;
@ -31,14 +31,14 @@ import com.google.common.collect.ImmutableSet;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "unit") @Test(groups = "unit")
public class ExtractZoneNamesTest { public class ExtractLastPathComponentTest {
ExtractZoneNames fn = new ExtractZoneNames(); ExtractLastPathComponent fn = new ExtractLastPathComponent();
public void testExtractNameInPath() { public void testExtractNameInPath() {
assertEquals(ExtractNameInPath.INSTANCE.apply("/REST/Zone/jclouds.org/"), "jclouds.org"); assertEquals(ExtractNameInPath.INSTANCE.apply("/REST/Zone/jclouds.org/"), "jclouds.org");
} }
public void testExtractZoneNames() { public void testExtractLastPathComponent() {
assertEquals(fn.apply(FluentIterable.from(ImmutableSet.of("/REST/Zone/jclouds.org/"))).toSet(), assertEquals(fn.apply(FluentIterable.from(ImmutableSet.of("/REST/Zone/jclouds.org/"))).toSet(),
ImmutableSet.of("jclouds.org")); ImmutableSet.of("jclouds.org"));
} }

View File

@ -0,0 +1,67 @@
/**
* 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.dynect.v3.parse;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import org.jclouds.dynect.v3.domain.RecordSet;
import org.jclouds.dynect.v3.domain.RecordSet.Value;
import org.jclouds.dynect.v3.domain.GeoRegionGroup;
import org.jclouds.dynect.v3.internal.BaseDynECTParseTest;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
/**
* @author Adrian Cole
*/
@Test(groups = "unit")
public class GetGeoRegionGroupResponseTest extends BaseDynECTParseTest<GeoRegionGroup> {
@Override
public String resource() {
return "/get_geo_regiongroup.json";
}
@Override
@SelectJson("data")
@Consumes(MediaType.APPLICATION_JSON)
public GeoRegionGroup expected() {
return GeoRegionGroup
.builder()
.name("Everywhere Else")
.countries(ImmutableList.of("11", "16", "12", "17", "15", "14"))
.serviceName("CCS")
.addRecordSet(
RecordSet
.builder()
.ttl(0)
.type("CNAME")
.add(Value
.builder()
.rdata(
ImmutableMap.<String, Object> builder()
.put("cname", "srv-938089264.us-east-1.elb.amazonaws.com.").build()).build())
.build()).build();
}
}

View File

@ -0,0 +1,107 @@
/**
* 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.dynect.v3.parse;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import org.jclouds.dynect.v3.domain.GeoService;
import org.jclouds.dynect.v3.domain.Node;
import org.jclouds.dynect.v3.domain.RecordSet;
import org.jclouds.dynect.v3.domain.GeoRegionGroup;
import org.jclouds.dynect.v3.domain.RecordSet.Value;
import org.jclouds.dynect.v3.internal.BaseDynECTParseTest;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
/**
* @author Adrian Cole
*/
@Test(groups = "unit")
public class GetGeoServiceResponseTest extends BaseDynECTParseTest<GeoService> {
@Override
public String resource() {
return "/get_geo_service.json";
}
@Override
@SelectJson("data")
@Consumes(MediaType.APPLICATION_JSON)
public GeoService expected() {
return GeoService
.builder()
.name("CCS")
.active(true)
.ttl(30)
.addNode(Node.create("srv.jclouds.org", "jclouds.org"))
.addGroup(
GeoRegionGroup
.builder()
.name("Everywhere Else")
.countries(ImmutableList.of("11", "16", "12", "17", "15", "14"))
.addRecordSet(
RecordSet
.builder()
.ttl(0)
.type("CNAME")
.add(Value
.builder()
.rdata(
ImmutableMap.<String, Object> builder()
.put("cname", "srv-000000001.us-east-1.elb.amazonaws.com.")
.build()).build()).build()).build())
.addGroup(
GeoRegionGroup
.builder()
.name("Europe")
.countries(ImmutableList.of("13"))
.addRecordSet(
RecordSet
.builder()
.ttl(0)
.type("CNAME")
.add(Value
.builder()
.rdata(
ImmutableMap.<String, Object> builder()
.put("cname", "srv-000000001.eu-west-1.elb.amazonaws.com.")
.build()).build()).build()).build())
.addGroup(
GeoRegionGroup
.builder()
.name("Fallback")
.countries(ImmutableList.of("@!", "@@"))
.addRecordSet(
RecordSet
.builder()
.ttl(0)
.type("CNAME")
.add(Value
.builder()
.rdata(
ImmutableMap.<String, Object> builder()
.put("cname", "srv-000000002.us-east-1.elb.amazonaws.com.")
.build()).build()).build()).build()).build();
}
}

View File

@ -0,0 +1,58 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.dynect.v3.parse;
import static com.google.common.base.Functions.compose;
import org.jclouds.dynect.v3.functions.ExtractLastPathComponent;
import org.jclouds.dynect.v3.internal.BaseDynECTParseTest;
import org.jclouds.http.HttpResponse;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Injector;
/**
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ListGeoRegionGroupsResponseTest extends BaseDynECTParseTest<FluentIterable<String>> {
@Override
public String resource() {
return "/list_geo_regiongroups.json";
}
@Override
@SelectJson("data")
public FluentIterable<String> expected() {
return FluentIterable.from(ImmutableSet.of("Everywhere Else", "Europe", "Fallback"));
}
// TODO: currently our parsing of annotations on expected() ignores
// @Transform
@Override
protected Function<HttpResponse, FluentIterable<String>> parser(Injector i) {
return compose(new ExtractLastPathComponent(), super.parser(i));
}
}

View File

@ -0,0 +1,58 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.dynect.v3.parse;
import static com.google.common.base.Functions.compose;
import org.jclouds.dynect.v3.functions.ExtractLastPathComponent;
import org.jclouds.dynect.v3.internal.BaseDynECTParseTest;
import org.jclouds.http.HttpResponse;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Injector;
/**
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ListGeoServicesResponseTest extends BaseDynECTParseTest<FluentIterable<String>> {
@Override
public String resource() {
return "/list_geo_services.json";
}
@Override
@SelectJson("data")
public FluentIterable<String> expected() {
return FluentIterable.from(ImmutableSet.of("srv", "srv-log"));
}
// TODO: currently our parsing of annotations on expected() ignores
// @Transform
@Override
protected Function<HttpResponse, FluentIterable<String>> parser(Injector i) {
return compose(new ExtractLastPathComponent(), super.parser(i));
}
}

View File

@ -21,7 +21,7 @@ package org.jclouds.dynect.v3.parse;
import static com.google.common.base.Functions.compose; import static com.google.common.base.Functions.compose;
import org.jclouds.dynect.v3.functions.ExtractZoneNames; import org.jclouds.dynect.v3.functions.ExtractLastPathComponent;
import org.jclouds.dynect.v3.internal.BaseDynECTParseTest; import org.jclouds.dynect.v3.internal.BaseDynECTParseTest;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.rest.annotations.SelectJson; import org.jclouds.rest.annotations.SelectJson;
@ -52,6 +52,6 @@ public class ListZonesResponseTest extends BaseDynECTParseTest<FluentIterable<St
// TODO: currently our parsing of annotations on expected() ignores @Transform // TODO: currently our parsing of annotations on expected() ignores @Transform
@Override @Override
protected Function<HttpResponse, FluentIterable<String>> parser(Injector i) { protected Function<HttpResponse, FluentIterable<String>> parser(Injector i) {
return compose(new ExtractZoneNames(), super.parser(i)); return compose(new ExtractLastPathComponent(), super.parser(i));
} }
} }

View File

@ -0,0 +1,92 @@
{
"status": "success",
"data": {
"name": "Everywhere Else",
"weight": {
"aaaa_weight": [],
"a_weight": [],
"cname_weight": []
},
"countries": ["11", "16", "12", "17", "15", "14"],
"service_name": "CCS",
"rdata": {
"spf_rdata": [],
"px_rdata": [],
"srv_rdata": [],
"txt_rdata": [],
"soa_rdata": [],
"rp_rdata": [],
"ipseckey_rdata": [],
"dhcid_rdata": [],
"kx_rdata": [],
"key_rdata": [],
"aaaa_rdata": [],
"mx_rdata": [],
"dnskey_rdata": [],
"naptr_rdata": [],
"a_rdata": [],
"cname_rdata": [{
"cname": "srv-938089264.us-east-1.elb.amazonaws.com."
}
],
"cert_rdata": [],
"nsap_rdata": [],
"ptr_rdata": [],
"ds_rdata": [],
"sshfp_rdata": [],
"dname_rdata": [],
"ns_rdata": [],
"loc_rdata": []
},
"label": {
"a_label": [],
"key_label": [],
"ptr_label": [],
"srv_label": [],
"txt_label": [],
"spf_label": [],
"mx_label": [],
"rp_label": [],
"sshfp_label": [],
"dnskey_label": [],
"aaaa_label": [],
"dhcid_label": [],
"nsap_label": [],
"loc_label": [],
"px_label": [],
"cname_label": [],
"cert_label": []
},
"ttl": {
"dhcid_ttl": 0,
"key_ttl": 0,
"ptr_ttl": 0,
"srv_ttl": 0,
"mx_ttl": 0,
"aaaa_ttl": 0,
"rp_ttl": 0,
"loc_ttl": 0,
"dnskey_ttl": 0,
"cname_ttl": 0,
"cert_ttl": 0,
"nsap_ttl": 0,
"a_ttl": 0,
"px_ttl": 0,
"sshfp_ttl": 0,
"spf_ttl": 0,
"txt_ttl": 0
},
"serve_count": {
"a_serve_count": "",
"aaaa_serve_count": ""
}
},
"job_id": 321503845,
"msgs": [{
"INFO": "detail_region_groups: Here is your group",
"SOURCE": "BLL",
"ERR_CD": null,
"LVL": "INFO"
}
]
}

View File

@ -0,0 +1,260 @@
{
"status": "success",
"data": {
"active": "Y",
"nodes": [{
"fqdn": "srv.jclouds.org",
"zone": "jclouds.org"
}
],
"name": "CCS",
"groups": [{
"name": "Everywhere Else",
"weight": {
"aaaa_weight": [],
"a_weight": [],
"cname_weight": []
},
"countries": ["11", "16", "12", "17", "15", "14"],
"rdata": {
"spf_rdata": [],
"px_rdata": [],
"srv_rdata": [],
"txt_rdata": [],
"soa_rdata": [],
"rp_rdata": [],
"ipseckey_rdata": [],
"dhcid_rdata": [],
"kx_rdata": [],
"key_rdata": [],
"aaaa_rdata": [],
"mx_rdata": [],
"dnskey_rdata": [],
"naptr_rdata": [],
"a_rdata": [],
"cname_rdata": [{
"cname": "srv-000000001.us-east-1.elb.amazonaws.com."
}
],
"cert_rdata": [],
"nsap_rdata": [],
"ptr_rdata": [],
"ds_rdata": [],
"sshfp_rdata": [],
"dname_rdata": [],
"ns_rdata": [],
"loc_rdata": []
},
"label": {
"a_label": [],
"key_label": [],
"ptr_label": [],
"srv_label": [],
"txt_label": [],
"spf_label": [],
"mx_label": [],
"rp_label": [],
"sshfp_label": [],
"dnskey_label": [],
"aaaa_label": [],
"dhcid_label": [],
"nsap_label": [],
"loc_label": [],
"px_label": [],
"cname_label": [],
"cert_label": []
},
"ttl": {
"dhcid_ttl": 0,
"key_ttl": 0,
"ptr_ttl": 0,
"srv_ttl": 0,
"mx_ttl": 0,
"aaaa_ttl": 0,
"rp_ttl": 0,
"loc_ttl": 0,
"dnskey_ttl": 0,
"cname_ttl": 0,
"cert_ttl": 0,
"nsap_ttl": 0,
"a_ttl": 0,
"px_ttl": 0,
"sshfp_ttl": 0,
"spf_ttl": 0,
"txt_ttl": 0
},
"serve_count": {
"a_serve_count": "",
"aaaa_serve_count": ""
}
}, {
"name": "Europe",
"weight": {
"aaaa_weight": [],
"a_weight": [],
"cname_weight": []
},
"countries": ["13"],
"rdata": {
"spf_rdata": [],
"px_rdata": [],
"srv_rdata": [],
"txt_rdata": [],
"soa_rdata": [],
"rp_rdata": [],
"ipseckey_rdata": [],
"dhcid_rdata": [],
"kx_rdata": [],
"key_rdata": [],
"aaaa_rdata": [],
"mx_rdata": [],
"dnskey_rdata": [],
"naptr_rdata": [],
"a_rdata": [],
"cname_rdata": [{
"cname": "srv-000000001.eu-west-1.elb.amazonaws.com."
}
],
"cert_rdata": [],
"nsap_rdata": [],
"ptr_rdata": [],
"ds_rdata": [],
"sshfp_rdata": [],
"dname_rdata": [],
"ns_rdata": [],
"loc_rdata": []
},
"label": {
"a_label": [],
"key_label": [],
"ptr_label": [],
"srv_label": [],
"txt_label": [],
"spf_label": [],
"mx_label": [],
"rp_label": [],
"sshfp_label": [],
"dnskey_label": [],
"aaaa_label": [],
"dhcid_label": [],
"nsap_label": [],
"loc_label": [],
"px_label": [],
"cname_label": [],
"cert_label": []
},
"ttl": {
"dhcid_ttl": 0,
"key_ttl": 0,
"ptr_ttl": 0,
"srv_ttl": 0,
"mx_ttl": 0,
"aaaa_ttl": 0,
"rp_ttl": 0,
"loc_ttl": 0,
"dnskey_ttl": 0,
"cname_ttl": 0,
"cert_ttl": 0,
"nsap_ttl": 0,
"a_ttl": 0,
"px_ttl": 0,
"sshfp_ttl": 0,
"spf_ttl": 0,
"txt_ttl": 0
},
"serve_count": {
"a_serve_count": "",
"aaaa_serve_count": ""
}
}, {
"name": "Fallback",
"weight": {
"aaaa_weight": [],
"a_weight": [],
"cname_weight": []
},
"countries": ["@!", "@@"],
"rdata": {
"spf_rdata": [],
"px_rdata": [],
"srv_rdata": [],
"txt_rdata": [],
"soa_rdata": [],
"rp_rdata": [],
"ipseckey_rdata": [],
"dhcid_rdata": [],
"kx_rdata": [],
"key_rdata": [],
"aaaa_rdata": [],
"mx_rdata": [],
"dnskey_rdata": [],
"naptr_rdata": [],
"a_rdata": [],
"cname_rdata": [{
"cname": "srv-000000002.us-east-1.elb.amazonaws.com."
}
],
"cert_rdata": [],
"nsap_rdata": [],
"ptr_rdata": [],
"ds_rdata": [],
"sshfp_rdata": [],
"dname_rdata": [],
"ns_rdata": [],
"loc_rdata": []
},
"label": {
"a_label": [],
"key_label": [],
"ptr_label": [],
"srv_label": [],
"txt_label": [],
"spf_label": [],
"mx_label": [],
"rp_label": [],
"sshfp_label": [],
"dnskey_label": [],
"aaaa_label": [],
"dhcid_label": [],
"nsap_label": [],
"loc_label": [],
"px_label": [],
"cname_label": [],
"cert_label": []
},
"ttl": {
"dhcid_ttl": 0,
"key_ttl": 0,
"ptr_ttl": 0,
"srv_ttl": 0,
"mx_ttl": 0,
"aaaa_ttl": 0,
"rp_ttl": 0,
"loc_ttl": 0,
"dnskey_ttl": 0,
"cname_ttl": 0,
"cert_ttl": 0,
"nsap_ttl": 0,
"a_ttl": 0,
"px_ttl": 0,
"sshfp_ttl": 0,
"spf_ttl": 0,
"txt_ttl": 0
},
"serve_count": {
"a_serve_count": "",
"aaaa_serve_count": ""
}
}
],
"ttl": 30
},
"job_id": 321488519,
"msgs": [{
"INFO": "detail: Here is your service",
"SOURCE": "BLL",
"ERR_CD": null,
"LVL": "INFO"
}
]
}

View File

@ -0,0 +1,12 @@
{
"status": "success",
"data": ["/REST/GeoRegionGroup/srv/Everywhere Else", "/REST/GeoRegionGroup/srv/Europe", "/REST/GeoRegionGroup/srv/Fallback"],
"job_id": 321503402,
"msgs": [{
"INFO": "get_region_groups: Here are your groups",
"SOURCE": "BLL",
"ERR_CD": null,
"LVL": "INFO"
}
]
}

View File

@ -0,0 +1,12 @@
{
"status": "success",
"data": ["/REST/Geo/srv/", "/REST/Geo/srv-log/"],
"job_id": 321483166,
"msgs": [{
"INFO": "GET: Found 2 services",
"SOURCE": "BLL",
"ERR_CD": null,
"LVL": "INFO"
}
]
}