mirror of https://github.com/apache/jclouds.git
The Metadata API for Load Balancers and Nodes in Rackspace Cloud Load Balancers.
This commit is contained in:
parent
5e241d96bd
commit
b7d76e7b8d
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.rackspace.cloudloadbalancers.binders;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.json.Json;
|
||||||
|
import org.jclouds.rest.Binder;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds the metadata to the request as a JSON payload.
|
||||||
|
*
|
||||||
|
* @author Everett Toews
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class BindMetadataToJsonPayload implements Binder {
|
||||||
|
|
||||||
|
protected final Json jsonBinder;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public BindMetadataToJsonPayload(Json jsonBinder) {
|
||||||
|
this.jsonBinder = checkNotNull(jsonBinder, "jsonBinder");
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
|
||||||
|
checkArgument(checkNotNull(input, "input") instanceof Map, "This binder is only valid for Map<String, String>");
|
||||||
|
checkNotNull(request, "request");
|
||||||
|
|
||||||
|
Map<String, String> metadata = (Map<String, String>) input;
|
||||||
|
List<Map<String, String>> clbMetadata = Lists.newArrayList();
|
||||||
|
|
||||||
|
for (String key: metadata.keySet()) {
|
||||||
|
clbMetadata.add(ImmutableMap.<String, String> of(
|
||||||
|
"key", key,
|
||||||
|
"value", metadata.get(key)));
|
||||||
|
}
|
||||||
|
|
||||||
|
String json = jsonBinder.toJson(ImmutableMap.of("metadata", clbMetadata));
|
||||||
|
request.setPayload(json);
|
||||||
|
request.getPayload().getContentMetadata().setContentType("application/json");
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,6 +50,7 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
|
||||||
private final SSLTermination sslTermination;
|
private final SSLTermination sslTermination;
|
||||||
private final SourceAddresses sourceAddresses;
|
private final SourceAddresses sourceAddresses;
|
||||||
private final Set<AccessRuleWithId> accessRules;
|
private final Set<AccessRuleWithId> accessRules;
|
||||||
|
private final Metadata metadata;
|
||||||
|
|
||||||
public LoadBalancer(String region, int id, String name, String protocol, @Nullable Integer port, Set<Node> nodes,
|
public LoadBalancer(String region, int id, String name, String protocol, @Nullable Integer port, Set<Node> nodes,
|
||||||
@Nullable Integer timeout, @Nullable Boolean halfClosed, @Nullable Algorithm algorithm, Status status,
|
@Nullable Integer timeout, @Nullable Boolean halfClosed, @Nullable Algorithm algorithm, Status status,
|
||||||
|
@ -57,10 +58,9 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
|
||||||
String clusterName, Date created, Date updated, @Nullable Map<String, Boolean> connectionLogging,
|
String clusterName, Date created, Date updated, @Nullable Map<String, Boolean> connectionLogging,
|
||||||
@Nullable ConnectionThrottle connectionThrottle, boolean contentCaching, int nodeCount,
|
@Nullable ConnectionThrottle connectionThrottle, boolean contentCaching, int nodeCount,
|
||||||
@Nullable HealthMonitor healthMonitor, @Nullable SSLTermination sslTermination,
|
@Nullable HealthMonitor healthMonitor, @Nullable SSLTermination sslTermination,
|
||||||
SourceAddresses sourceAddresses, Set<AccessRuleWithId> accessRules,
|
SourceAddresses sourceAddresses, Set<AccessRuleWithId> accessRules, Metadata metadata) {
|
||||||
@Nullable Set<Metadata> metadata) {
|
|
||||||
super(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging,
|
super(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging,
|
||||||
connectionThrottle, healthMonitor, metadata);
|
connectionThrottle, healthMonitor);
|
||||||
this.region = checkNotNull(region, "region");
|
this.region = checkNotNull(region, "region");
|
||||||
checkArgument(id != -1, "id must be specified");
|
checkArgument(id != -1, "id must be specified");
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
@ -74,6 +74,7 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
|
||||||
this.sslTermination = sslTermination;
|
this.sslTermination = sslTermination;
|
||||||
this.sourceAddresses = sourceAddresses;
|
this.sourceAddresses = sourceAddresses;
|
||||||
this.accessRules = accessRules == null ? ImmutableSet.<AccessRuleWithId> of() : ImmutableSet.copyOf(accessRules);
|
this.accessRules = accessRules == null ? ImmutableSet.<AccessRuleWithId> of() : ImmutableSet.copyOf(accessRules);
|
||||||
|
this.metadata = metadata == null ? new Metadata() : metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRegion() {
|
public String getRegion() {
|
||||||
|
@ -153,10 +154,20 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
|
||||||
return sourceAddresses;
|
return sourceAddresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see AccessRule
|
||||||
|
*/
|
||||||
public Set<AccessRuleWithId> getAccessRules() {
|
public Set<AccessRuleWithId> getAccessRules() {
|
||||||
return accessRules;
|
return accessRules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Metadata
|
||||||
|
*/
|
||||||
|
public Metadata getMetadata() {
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
protected ToStringHelper string() {
|
protected ToStringHelper string() {
|
||||||
return Objects.toStringHelper(this).omitNullValues().add("id", id).add("region", region).add("status", status)
|
return Objects.toStringHelper(this).omitNullValues().add("id", id).add("region", region).add("status", status)
|
||||||
.add("name", name).add("protocol", protocol).add("port", port).add("nodeCount", getNodeCount())
|
.add("name", name).add("protocol", protocol).add("port", port).add("nodeCount", getNodeCount())
|
||||||
|
@ -260,6 +271,7 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
|
||||||
private SSLTermination sslTermination;
|
private SSLTermination sslTermination;
|
||||||
private SourceAddresses sourceAddresses;
|
private SourceAddresses sourceAddresses;
|
||||||
private Set<AccessRuleWithId> accessRules;
|
private Set<AccessRuleWithId> accessRules;
|
||||||
|
private Metadata metadata;
|
||||||
|
|
||||||
public Builder region(String region) {
|
public Builder region(String region) {
|
||||||
this.region = region;
|
this.region = region;
|
||||||
|
@ -324,6 +336,10 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder metadata(Metadata metadata) {
|
||||||
|
this.metadata = checkNotNull(metadata, "metadata");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public LoadBalancer build() {
|
public LoadBalancer build() {
|
||||||
return new LoadBalancer(region, id, name, protocol, port, nodes, timeout, halfClosed, algorithm, status,
|
return new LoadBalancer(region, id, name, protocol, port, nodes, timeout, halfClosed, algorithm, status,
|
||||||
|
@ -344,8 +360,8 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Builder node(Node nodes) {
|
public Builder node(Node node) {
|
||||||
this.nodes.add(checkNotNull(nodes, "nodes"));
|
this.nodes.add(checkNotNull(node, "nodes"));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,14 +445,6 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
|
||||||
return Builder.class.cast(super.healthMonitor(healthMonitor));
|
return Builder.class.cast(super.healthMonitor(healthMonitor));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Builder metadata(@Nullable Set<Metadata> metadata) {
|
|
||||||
return Builder.class.cast(super.metadata(metadata));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Builder from(LoadBalancer in) {
|
public Builder from(LoadBalancer in) {
|
||||||
return Builder.class.cast(super.from(in)).region(in.getRegion()).id(in.getId()).status(in.getStatus())
|
return Builder.class.cast(super.from(in)).region(in.getRegion()).id(in.getId()).status(in.getStatus())
|
||||||
|
|
|
@ -41,13 +41,14 @@ public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalan
|
||||||
|
|
||||||
private final Set<Map<String, String>> virtualIps;
|
private final Set<Map<String, String>> virtualIps;
|
||||||
private final Set<AccessRule> accessRules;
|
private final Set<AccessRule> accessRules;
|
||||||
|
private final Map<String, String> metadata;
|
||||||
|
|
||||||
public LoadBalancerRequest(String name, String protocol, @Nullable Integer port, Set<NodeRequest> nodes,
|
public LoadBalancerRequest(String name, String protocol, @Nullable Integer port, Set<NodeRequest> nodes,
|
||||||
@Nullable Algorithm algorithm, @Nullable Integer timeout, @Nullable Boolean halfClosed,
|
@Nullable Algorithm algorithm, @Nullable Integer timeout, @Nullable Boolean halfClosed,
|
||||||
@Nullable Map<String, SessionPersistenceType> sessionPersistenceType,
|
@Nullable Map<String, SessionPersistenceType> sessionPersistenceType,
|
||||||
@Nullable Map<String, Boolean> connectionLogging, @Nullable ConnectionThrottle connectionThrottle,
|
@Nullable Map<String, Boolean> connectionLogging, @Nullable ConnectionThrottle connectionThrottle,
|
||||||
@Nullable HealthMonitor healthMonitor, @Nullable Set<AccessRule> accessRules,
|
@Nullable HealthMonitor healthMonitor, @Nullable Set<AccessRule> accessRules,
|
||||||
@Nullable Set<Metadata> metadata, VirtualIP.Type virtualIPType, Integer virtualIPId) {
|
@Nullable Map<String, String> metadata, VirtualIP.Type virtualIPType, Integer virtualIPId) {
|
||||||
this(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging,
|
this(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging,
|
||||||
connectionThrottle, healthMonitor, accessRules, metadata,
|
connectionThrottle, healthMonitor, accessRules, metadata,
|
||||||
getVirtualIPsFromOptions(virtualIPType, virtualIPId));
|
getVirtualIPsFromOptions(virtualIPType, virtualIPId));
|
||||||
|
@ -58,11 +59,20 @@ public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalan
|
||||||
@Nullable Map<String, SessionPersistenceType> sessionPersistenceType,
|
@Nullable Map<String, SessionPersistenceType> sessionPersistenceType,
|
||||||
@Nullable Map<String, Boolean> connectionLogging, @Nullable ConnectionThrottle connectionThrottle,
|
@Nullable Map<String, Boolean> connectionLogging, @Nullable ConnectionThrottle connectionThrottle,
|
||||||
@Nullable HealthMonitor healthMonitor, @Nullable Set<AccessRule> accessRules,
|
@Nullable HealthMonitor healthMonitor, @Nullable Set<AccessRule> accessRules,
|
||||||
@Nullable Set<Metadata> metadata, Set<Map<String, String>> virtualIPsFromOptions) {
|
@Nullable Map<String, String> metadata, Set<Map<String, String>> virtualIPsFromOptions) {
|
||||||
super(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging,
|
super(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging,
|
||||||
connectionThrottle, healthMonitor, metadata);
|
connectionThrottle, healthMonitor);
|
||||||
this.virtualIps = checkNotNull(virtualIPsFromOptions, "virtualIPsFromOptions");
|
this.virtualIps = checkNotNull(virtualIPsFromOptions, "virtualIPsFromOptions");
|
||||||
this.accessRules = accessRules;
|
this.accessRules = accessRules;
|
||||||
|
this.metadata = metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getMetadata() {
|
||||||
|
return metadata != null ? metadata : ImmutableMap.<String, String> of();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<AccessRule> getAccessRules() {
|
||||||
|
return accessRules != null ? accessRules : ImmutableSet.<AccessRule> of();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Set<Map<String, String>> getVirtualIPsFromOptions(VirtualIP.Type virtualIPType, Integer virtualIPId) {
|
static Set<Map<String, String>> getVirtualIPsFromOptions(VirtualIP.Type virtualIPType, Integer virtualIPId) {
|
||||||
|
@ -95,6 +105,7 @@ public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalan
|
||||||
private Integer virtualIPId;
|
private Integer virtualIPId;
|
||||||
private Set<Map<String, String>> virtualIps;
|
private Set<Map<String, String>> virtualIps;
|
||||||
private Set<AccessRule> accessRules;
|
private Set<AccessRule> accessRules;
|
||||||
|
private Map<String, String> metadata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see VirtualIP
|
* @see VirtualIP
|
||||||
|
@ -131,6 +142,14 @@ public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalan
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information (metadata) that can be associated with each load balancer for the client's personal use.
|
||||||
|
*/
|
||||||
|
public Builder metadata(Map<String, String> metadata) {
|
||||||
|
this.metadata = ImmutableMap.<String, String> copyOf(checkNotNull(metadata, "metadata"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public LoadBalancerRequest build() {
|
public LoadBalancerRequest build() {
|
||||||
if (virtualIps == null) {
|
if (virtualIps == null) {
|
||||||
return new LoadBalancerRequest(name, protocol, port, nodes, algorithm, timeout, halfClosed,
|
return new LoadBalancerRequest(name, protocol, port, nodes, algorithm, timeout, halfClosed,
|
||||||
|
|
|
@ -18,94 +18,53 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudloadbalancers.domain;
|
package org.jclouds.rackspace.cloudloadbalancers.domain;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import java.util.Map;
|
||||||
import com.google.common.base.Objects.ToStringHelper;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.google.common.collect.ForwardingMap;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Key and value must be 256 characters or less. All UTF-8 characters are valid.
|
||||||
|
* </p>
|
||||||
|
* Use the *Id methods when you need to get a metadata id for updating and removal.
|
||||||
|
*
|
||||||
* @author Everett Toews
|
* @author Everett Toews
|
||||||
*/
|
*/
|
||||||
public class Metadata {
|
public class Metadata extends ForwardingMap<String, String> {
|
||||||
private int id;
|
private Map<String, String> metadata = Maps.newHashMap();
|
||||||
private String key;
|
private Map<String, Integer> keyToId = Maps.newHashMap();
|
||||||
private String value;
|
|
||||||
|
|
||||||
private Metadata(Integer id, String key, String value) {
|
public Metadata(Metadata metadata) {
|
||||||
this.id = id;
|
super();
|
||||||
this.key = key;
|
this.metadata.putAll(metadata);
|
||||||
this.value = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
public Metadata() {
|
||||||
return id;
|
super();
|
||||||
}
|
|
||||||
|
|
||||||
public String getKey() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
protected Map<String, String> delegate() {
|
||||||
return Objects.hashCode(id);
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public int getId(String key) {
|
||||||
public boolean equals(Object obj) {
|
return keyToId.get(key);
|
||||||
if (this == obj) return true;
|
|
||||||
if (obj == null || getClass() != obj.getClass()) return false;
|
|
||||||
Metadata that = Metadata.class.cast(obj);
|
|
||||||
|
|
||||||
return Objects.equal(this.id, that.id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ToStringHelper string() {
|
public Integer putId(String key, int id) {
|
||||||
return Objects.toStringHelper(this).omitNullValues()
|
return keyToId.put(key, id);
|
||||||
.add("id", id).add("key", key).add("value", value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public Iterable<Integer> getIds() {
|
||||||
public String toString() {
|
Set<Integer> ids = Sets.newHashSet();
|
||||||
return string().toString();
|
|
||||||
|
for (String key: keyToId.keySet()) {
|
||||||
|
ids.add(keyToId.get(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
return ids;
|
||||||
private Integer id;
|
|
||||||
private String key;
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
public Builder id(Integer id) {
|
|
||||||
this.id = id;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder key(String key) {
|
|
||||||
this.key = key;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder value(String value) {
|
|
||||||
this.value = value;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Metadata build() {
|
|
||||||
return new Metadata(id, key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder from(Metadata in) {
|
|
||||||
return id(in.getId()).key(in.getKey()).value(in.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Builder builder() {
|
|
||||||
return new Builder();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder toBuilder() {
|
|
||||||
return new Builder().from(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,16 +56,18 @@ public class Node extends BaseNode<Node> {
|
||||||
|
|
||||||
private int id;
|
private int id;
|
||||||
private Status status;
|
private Status status;
|
||||||
|
private Metadata metadata = new Metadata();
|
||||||
|
|
||||||
// for serialization only
|
// for serialization only
|
||||||
Node() {
|
protected Node() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node(int id, String address, int port, Condition condition, Type type, Status status, Integer weight) {
|
public Node(String address, int port, Condition condition, Type type, Integer weight, int id, Status status, Metadata metadata) {
|
||||||
super(address, port, condition, type, weight);
|
super(address, port, condition, type, weight);
|
||||||
checkArgument(id != -1, "id must be specified");
|
checkArgument(id != -1, "id must be specified");
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.status = checkNotNull(status, "status");
|
this.status = checkNotNull(status, "status");
|
||||||
|
this.metadata = metadata != null ? metadata : this.metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
|
@ -76,10 +78,14 @@ public class Node extends BaseNode<Node> {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Metadata getMetadata() {
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
protected ToStringHelper string() {
|
protected ToStringHelper string() {
|
||||||
return Objects.toStringHelper(this).omitNullValues()
|
return Objects.toStringHelper(this).omitNullValues()
|
||||||
.add("id", id).add("address", address).add("port", port).add("condition", condition)
|
.add("id", id).add("address", address).add("port", port).add("condition", condition)
|
||||||
.add("type", type).add("weight", weight).add("status", status);
|
.add("type", type).add("weight", weight).add("status", status).add("metadata", metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -136,6 +142,7 @@ public class Node extends BaseNode<Node> {
|
||||||
public static class Builder extends BaseNode.Builder<Node> {
|
public static class Builder extends BaseNode.Builder<Node> {
|
||||||
private int id = -1;
|
private int id = -1;
|
||||||
private Status status;
|
private Status status;
|
||||||
|
private Metadata metadata;
|
||||||
|
|
||||||
public Builder id(int id) {
|
public Builder id(int id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
@ -150,9 +157,14 @@ public class Node extends BaseNode<Node> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder metadata(Metadata metadata) {
|
||||||
|
this.metadata = checkNotNull(metadata, "metadata");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node build() {
|
public Node build() {
|
||||||
return new Node(id, address, port, condition, type, status, weight);
|
return new Node(address, port, condition, type, weight, id, status, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -196,7 +208,7 @@ public class Node extends BaseNode<Node> {
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public Builder from(Node in) {
|
public Builder from(Node in) {
|
||||||
return Builder.class.cast(super.from(in)).id(in.getId()).status(in.getStatus());
|
return Builder.class.cast(super.from(in)).id(in.getId()).status(in.getStatus()).metadata(in.getMetadata());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.ConnectionThrottle;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.ConnectionThrottle;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.HealthMonitor;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.HealthMonitor;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.Metadata;
|
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.features.LoadBalancerApi;
|
import org.jclouds.rackspace.cloudloadbalancers.features.LoadBalancerApi;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
|
@ -61,7 +60,6 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
|
||||||
protected Map<String, Boolean> connectionLogging;
|
protected Map<String, Boolean> connectionLogging;
|
||||||
protected ConnectionThrottle connectionThrottle;
|
protected ConnectionThrottle connectionThrottle;
|
||||||
protected HealthMonitor healthMonitor;
|
protected HealthMonitor healthMonitor;
|
||||||
protected Set<Metadata> metadata;
|
|
||||||
|
|
||||||
// for serialization only
|
// for serialization only
|
||||||
protected BaseLoadBalancer() {
|
protected BaseLoadBalancer() {
|
||||||
|
@ -71,7 +69,7 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
|
||||||
@Nullable Algorithm algorithm, @Nullable Integer timeout, @Nullable Boolean halfClosed,
|
@Nullable Algorithm algorithm, @Nullable Integer timeout, @Nullable Boolean halfClosed,
|
||||||
@Nullable Map<String, SessionPersistenceType> sessionPersistence,
|
@Nullable Map<String, SessionPersistenceType> sessionPersistence,
|
||||||
@Nullable Map<String, Boolean> connectionLogging, @Nullable ConnectionThrottle connectionThrottle,
|
@Nullable Map<String, Boolean> connectionLogging, @Nullable ConnectionThrottle connectionThrottle,
|
||||||
@Nullable HealthMonitor healthMonitor, @Nullable Set<Metadata> metadata) {
|
@Nullable HealthMonitor healthMonitor) {
|
||||||
this.name = checkNotNull(name, "name");
|
this.name = checkNotNull(name, "name");
|
||||||
this.protocol = protocol;// null on deleted LB
|
this.protocol = protocol;// null on deleted LB
|
||||||
this.port = port;// null on deleted LB
|
this.port = port;// null on deleted LB
|
||||||
|
@ -83,7 +81,6 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
|
||||||
this.connectionLogging = connectionLogging;
|
this.connectionLogging = connectionLogging;
|
||||||
this.connectionThrottle = connectionThrottle;
|
this.connectionThrottle = connectionThrottle;
|
||||||
this.healthMonitor = healthMonitor;
|
this.healthMonitor = healthMonitor;
|
||||||
this.metadata = metadata;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -167,20 +164,12 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
|
||||||
return healthMonitor;
|
return healthMonitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return metadata, which may be null if metadata has not been set.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public Set<Metadata> getMetadata() {
|
|
||||||
return metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ToStringHelper string() {
|
protected ToStringHelper string() {
|
||||||
return Objects.toStringHelper(this).omitNullValues().add("name", name).add("protocol", protocol)
|
return Objects.toStringHelper(this).omitNullValues().add("name", name).add("protocol", protocol)
|
||||||
.add("port", port).add("nodes", nodes).add("timeout", timeout).add("algorithm", algorithm)
|
.add("port", port).add("nodes", nodes).add("timeout", timeout).add("algorithm", algorithm)
|
||||||
.add("timeout", timeout).add("sessionPersistenceType", getSessionPersistenceType())
|
.add("timeout", timeout).add("sessionPersistenceType", getSessionPersistenceType())
|
||||||
.add("connectionLogging", connectionLogging).add("connectionThrottle", connectionThrottle)
|
.add("connectionLogging", connectionLogging).add("connectionThrottle", connectionThrottle)
|
||||||
.add("healthMonitor", healthMonitor).add("metadata", metadata);
|
.add("healthMonitor", healthMonitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -288,7 +277,6 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
|
||||||
protected Map<String, Boolean> connectionLogging;
|
protected Map<String, Boolean> connectionLogging;
|
||||||
protected ConnectionThrottle connectionThrottle;
|
protected ConnectionThrottle connectionThrottle;
|
||||||
protected HealthMonitor healthMonitor;
|
protected HealthMonitor healthMonitor;
|
||||||
protected Set<Metadata> metadata;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Required. Name of the load balancer to create. The name must be 128 characters or less in length, and all
|
* Required. Name of the load balancer to create. The name must be 128 characters or less in length, and all
|
||||||
|
@ -414,17 +402,9 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Information (metadata) that can be associated with each load balancer for the client's personal use.
|
|
||||||
*/
|
|
||||||
public Builder<N, T> metadata(@Nullable Set<Metadata> metadata) {
|
|
||||||
this.metadata = metadata;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseLoadBalancer<N, T> build() {
|
public BaseLoadBalancer<N, T> build() {
|
||||||
return new BaseLoadBalancer<N, T>(name, protocol, port, nodes, algorithm, timeout, halfClosed,
|
return new BaseLoadBalancer<N, T>(name, protocol, port, nodes, algorithm, timeout, halfClosed,
|
||||||
sessionPersistence, connectionLogging, connectionThrottle, healthMonitor, metadata);
|
sessionPersistence, connectionLogging, connectionThrottle, healthMonitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder<N, T> from(T baseLB) {
|
public Builder<N, T> from(T baseLB) {
|
||||||
|
@ -432,7 +412,7 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
|
||||||
.algorithm(baseLB.getAlgorithm()).timeout(baseLB.getTimeout()).halfClosed(baseLB.isHalfClosed())
|
.algorithm(baseLB.getAlgorithm()).timeout(baseLB.getTimeout()).halfClosed(baseLB.isHalfClosed())
|
||||||
.nodes(baseLB.getNodes()).sessionPersistenceType(baseLB.getSessionPersistenceType())
|
.nodes(baseLB.getNodes()).sessionPersistenceType(baseLB.getSessionPersistenceType())
|
||||||
.connectionLogging(baseLB.isConnectionLogging()).connectionThrottle(baseLB.getConnectionThrottle())
|
.connectionLogging(baseLB.isConnectionLogging()).connectionThrottle(baseLB.getConnectionThrottle())
|
||||||
.healthMonitor(baseLB.getHealthMonitor()).metadata(baseLB.getMetadata());
|
.healthMonitor(baseLB.getHealthMonitor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudloadbalancers.features;
|
package org.jclouds.rackspace.cloudloadbalancers.features;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jclouds.collect.IterableWithMarker;
|
import org.jclouds.collect.IterableWithMarker;
|
||||||
import org.jclouds.collect.PagedIterable;
|
import org.jclouds.collect.PagedIterable;
|
||||||
import org.jclouds.http.HttpResponseException;
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
@ -25,6 +27,7 @@ import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerAttributes;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerAttributes;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerRequest;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerRequest;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Metadata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides synchronous access to CloudLoadBalancers LoadBalancer features.
|
* Provides synchronous access to CloudLoadBalancers LoadBalancer features.
|
||||||
|
@ -104,4 +107,43 @@ public interface LoadBalancerApi {
|
||||||
* to remove
|
* to remove
|
||||||
*/
|
*/
|
||||||
void remove(int id);
|
void remove(int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When a metadata item is added, it is assigned a unique identifier that can be used for mutating operations such
|
||||||
|
* as changing the value attribute or removing it. Key and value must be 256 characters or less.
|
||||||
|
* All UTF-8 characters are valid.
|
||||||
|
*/
|
||||||
|
Metadata createMetadata(int id, Map<String, String> metadata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List a load balancer's metadata.
|
||||||
|
*/
|
||||||
|
Metadata getMetadata(int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update metadatum. Key and value must be 256 characters or less. All UTF-8 characters are valid.
|
||||||
|
*
|
||||||
|
* @return true on a successful update, false if the metadatum was not found
|
||||||
|
*/
|
||||||
|
boolean updateMetadatum(int id, int metadatumId, String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove metadatum.
|
||||||
|
*
|
||||||
|
* @see LoadBalancerApi#remove(int, Iterable)
|
||||||
|
*
|
||||||
|
* @return true on a successful removal, false if the metadatum was not found
|
||||||
|
*/
|
||||||
|
boolean removeMetadatum(int id, int metadatumId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Batch delete metadata given the specified ids.
|
||||||
|
*
|
||||||
|
* The current default limit is ten ids per request. Any and all configuration data is immediately purged and is
|
||||||
|
* not recoverable. If one or more of the items in the list cannot be removed due to its current status, an
|
||||||
|
* exception is thrown along with the ids of the ones the system identified as potential failures for this request.
|
||||||
|
*
|
||||||
|
* @return true on a successful removal, false if the metadata was not found
|
||||||
|
*/
|
||||||
|
boolean removeMetadata(int id, Iterable<Integer> metadataIds);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudloadbalancers.features;
|
package org.jclouds.rackspace.cloudloadbalancers.features;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
|
@ -25,9 +27,13 @@ import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.PUT;
|
import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.Fallbacks.EmptyMapOnNotFoundOr404;
|
||||||
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
||||||
|
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
|
||||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||||
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
|
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
|
||||||
import org.jclouds.collect.IterableWithMarker;
|
import org.jclouds.collect.IterableWithMarker;
|
||||||
|
@ -35,12 +41,18 @@ import org.jclouds.collect.PagedIterable;
|
||||||
import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
|
import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
|
||||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.binders.BindMetadataToJsonPayload;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerAttributes;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerAttributes;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerRequest;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerRequest;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Metadata;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.functions.ParseLoadBalancer;
|
import org.jclouds.rackspace.cloudloadbalancers.functions.ParseLoadBalancer;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.functions.ParseLoadBalancers;
|
import org.jclouds.rackspace.cloudloadbalancers.functions.ParseLoadBalancers;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.functions.ParseMetadata;
|
||||||
|
import org.jclouds.rest.annotations.BinderParam;
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
|
import org.jclouds.rest.annotations.Payload;
|
||||||
|
import org.jclouds.rest.annotations.PayloadParam;
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.annotations.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.rest.annotations.Transform;
|
import org.jclouds.rest.annotations.Transform;
|
||||||
|
@ -117,4 +129,57 @@ public interface LoadBalancerAsyncApi {
|
||||||
@Consumes("*/*")
|
@Consumes("*/*")
|
||||||
ListenableFuture<Void> remove(@PathParam("id") int id);
|
ListenableFuture<Void> remove(@PathParam("id") int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see LoadBalancerApi#createMetadata(int, Iterable)
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@ResponseParser(ParseMetadata.class)
|
||||||
|
@Fallback(EmptyMapOnNotFoundOr404.class)
|
||||||
|
@Path("/loadbalancers/{id}/metadata")
|
||||||
|
ListenableFuture<Metadata> createMetadata(
|
||||||
|
@PathParam("id") int id,
|
||||||
|
@BinderParam(BindMetadataToJsonPayload.class) Map<String, String> metadata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see LoadBalancerApi#getMetadata(int)
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@ResponseParser(ParseMetadata.class)
|
||||||
|
@Fallback(EmptyMapOnNotFoundOr404.class)
|
||||||
|
@Path("/loadbalancers/{id}/metadata")
|
||||||
|
ListenableFuture<Metadata> getMetadata(@PathParam("id") int lb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see LoadBalancerApi#updateMetadatum(int, int, String)
|
||||||
|
*/
|
||||||
|
@PUT
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Consumes("*/*")
|
||||||
|
@Fallback(FalseOnNotFoundOr404.class)
|
||||||
|
@Payload("%7B\"meta\":%7B\"value\":\"{value}\"%7D%7D")
|
||||||
|
@Path("/loadbalancers/{id}/metadata/{metadatumId}")
|
||||||
|
ListenableFuture<Boolean> updateMetadatum(@PathParam("id") int id,
|
||||||
|
@PathParam("metadatumId") int metadatumId,
|
||||||
|
@PayloadParam("value") String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see LoadBalancerApi#removeMetadatum(int, int)
|
||||||
|
*/
|
||||||
|
@DELETE
|
||||||
|
@Fallback(FalseOnNotFoundOr404.class)
|
||||||
|
@Consumes("*/*")
|
||||||
|
@Path("/loadbalancers/{id}/metadata/{metadatumId}")
|
||||||
|
ListenableFuture<Boolean> removeMetadatum(@PathParam("id") int id, @PathParam("metadatumId") int metadatumId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see LoadBalancerApi#removeMetadata(int, Iterable)
|
||||||
|
*/
|
||||||
|
@DELETE
|
||||||
|
@Fallback(FalseOnNotFoundOr404.class)
|
||||||
|
@Consumes("*/*")
|
||||||
|
@Path("/loadbalancers/{id}/metadata")
|
||||||
|
ListenableFuture<Boolean> removeMetadata(@PathParam("id") int id,
|
||||||
|
@QueryParam("id") Iterable<Integer> metadataIds);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,14 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudloadbalancers.features;
|
package org.jclouds.rackspace.cloudloadbalancers.features;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.jclouds.collect.IterableWithMarker;
|
import org.jclouds.collect.IterableWithMarker;
|
||||||
import org.jclouds.collect.PagedIterable;
|
import org.jclouds.collect.PagedIterable;
|
||||||
import org.jclouds.http.HttpResponseException;
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerAttributes;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerAttributes;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Metadata;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.Node;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Node;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeAttributes;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeAttributes;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeRequest;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeRequest;
|
||||||
|
@ -111,4 +113,43 @@ public interface NodeApi {
|
||||||
* nodes to remove
|
* nodes to remove
|
||||||
*/
|
*/
|
||||||
void remove(Iterable<Integer> ids);
|
void remove(Iterable<Integer> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When a metadata item is added, it is assigned a unique identifier that can be used for mutating operations such
|
||||||
|
* as changing the value attribute or removing it. Key and value must be 256 characters or less.
|
||||||
|
* All UTF-8 characters are valid.
|
||||||
|
*/
|
||||||
|
Metadata createMetadata(int id, Map<String, String> metadata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List a load balancer's metadata.
|
||||||
|
*/
|
||||||
|
Metadata getMetadata(int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update metadatum. Key and value must be 256 characters or less. All UTF-8 characters are valid.
|
||||||
|
*
|
||||||
|
* @return true on a successful update, false if the metadatum was not found
|
||||||
|
*/
|
||||||
|
boolean updateMetadatum(int id, int metadatumId, String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove metadatum.
|
||||||
|
*
|
||||||
|
* @see NodeApi#remove(int, Iterable)
|
||||||
|
*
|
||||||
|
* @return true on a successful removal, false if the metadatum was not found
|
||||||
|
*/
|
||||||
|
boolean removeMetadatum(int id, int metadatumId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Batch delete metadata given the specified ids.
|
||||||
|
*
|
||||||
|
* The current default limit is ten ids per request. Any and all configuration data is immediately purged and is
|
||||||
|
* not recoverable. If one or more of the items in the list cannot be removed due to its current status, an
|
||||||
|
* exception is thrown along with the ids of the ones the system identified as potential failures for this request.
|
||||||
|
*
|
||||||
|
* @return true on a successful removal, false if the metadata was not found
|
||||||
|
*/
|
||||||
|
boolean removeMetadata(int id, Iterable<Integer> metadataIds);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudloadbalancers.features;
|
package org.jclouds.rackspace.cloudloadbalancers.features;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
@ -27,10 +28,13 @@ import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.PUT;
|
import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.Fallbacks.EmptyMapOnNotFoundOr404;
|
||||||
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
||||||
|
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
|
||||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||||
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
|
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
|
||||||
import org.jclouds.collect.IterableWithMarker;
|
import org.jclouds.collect.IterableWithMarker;
|
||||||
|
@ -38,12 +42,19 @@ import org.jclouds.collect.PagedIterable;
|
||||||
import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
|
import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
|
||||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.binders.BindMetadataToJsonPayload;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Metadata;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.Node;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Node;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeAttributes;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeAttributes;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeRequest;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeRequest;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.functions.ParseMetadata;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.functions.ParseNode;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.functions.ParseNodes;
|
import org.jclouds.rackspace.cloudloadbalancers.functions.ParseNodes;
|
||||||
|
import org.jclouds.rest.annotations.BinderParam;
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
|
import org.jclouds.rest.annotations.Payload;
|
||||||
|
import org.jclouds.rest.annotations.PayloadParam;
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.annotations.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
@ -98,15 +109,15 @@ public interface NodeAsyncApi {
|
||||||
@ResponseParser(ParseNodes.class)
|
@ResponseParser(ParseNodes.class)
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
|
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
|
||||||
@Path("/loadbalancers")
|
@Path("/nodes")
|
||||||
ListenableFuture<IterableWithMarker<LoadBalancer>> list(PaginationOptions options);
|
ListenableFuture<IterableWithMarker<LoadBalancer>> list(PaginationOptions options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NodeApi#get(int)
|
* @see NodeApi#get(int)
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@SelectJson("node")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@ResponseParser(ParseNode.class)
|
||||||
@Path("/nodes/{id}")
|
@Path("/nodes/{id}")
|
||||||
@Fallback(NullOnNotFoundOr404.class)
|
@Fallback(NullOnNotFoundOr404.class)
|
||||||
ListenableFuture<Node> get(@PathParam("id") int id);
|
ListenableFuture<Node> get(@PathParam("id") int id);
|
||||||
|
@ -129,5 +140,57 @@ public interface NodeAsyncApi {
|
||||||
@Consumes("*/*")
|
@Consumes("*/*")
|
||||||
ListenableFuture<Void> remove(@QueryParam("id") Iterable<Integer> ids);
|
ListenableFuture<Void> remove(@QueryParam("id") Iterable<Integer> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see NodeApi#createMetadata(int, Iterable)
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@ResponseParser(ParseMetadata.class)
|
||||||
|
@Fallback(EmptyMapOnNotFoundOr404.class)
|
||||||
|
@Path("/nodes/{id}/metadata")
|
||||||
|
ListenableFuture<Metadata> createMetadata(
|
||||||
|
@PathParam("id") int id,
|
||||||
|
@BinderParam(BindMetadataToJsonPayload.class) Map<String, String> metadata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see NodeApi#getMetadata(int)
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@ResponseParser(ParseMetadata.class)
|
||||||
|
@Fallback(EmptyMapOnNotFoundOr404.class)
|
||||||
|
@Path("/nodes/{id}/metadata")
|
||||||
|
ListenableFuture<Metadata> getMetadata(@PathParam("id") int lb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see NodeApi#updateMetadatum(int, int, String)
|
||||||
|
*/
|
||||||
|
@PUT
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Consumes("*/*")
|
||||||
|
@Fallback(FalseOnNotFoundOr404.class)
|
||||||
|
@Payload("%7B\"meta\":%7B\"value\":\"{value}\"%7D%7D")
|
||||||
|
@Path("/nodes/{id}/metadata/{metadatumId}")
|
||||||
|
ListenableFuture<Boolean> updateMetadatum(@PathParam("id") int id,
|
||||||
|
@PathParam("metadatumId") int metadatumId,
|
||||||
|
@PayloadParam("value") String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see NodeApi#removeMetadatum(int, int)
|
||||||
|
*/
|
||||||
|
@DELETE
|
||||||
|
@Fallback(FalseOnNotFoundOr404.class)
|
||||||
|
@Consumes("*/*")
|
||||||
|
@Path("/nodes/{id}/metadata/{metadatumId}")
|
||||||
|
ListenableFuture<Boolean> removeMetadatum(@PathParam("id") int id, @PathParam("metadatumId") int metadatumId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see NodeApi#removeMetadata(int, Iterable)
|
||||||
|
*/
|
||||||
|
@DELETE
|
||||||
|
@Fallback(FalseOnNotFoundOr404.class)
|
||||||
|
@Consumes("*/*")
|
||||||
|
@Path("/nodes/{id}/metadata")
|
||||||
|
ListenableFuture<Boolean> removeMetadata(@PathParam("id") int id,
|
||||||
|
@QueryParam("id") Iterable<Integer> metadataIds);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,9 @@ import javax.inject.Inject;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRuleWithId;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRuleWithId;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.VirtualIPWithId;
|
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer.Builder;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer.Builder;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Metadata;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.domain.VirtualIPWithId;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
@ -58,8 +59,7 @@ public class ConvertLB implements Function<LB, LoadBalancer> {
|
||||||
.protocol(lb.getProtocol()).port(lb.getPort()).nodeCount(lb.nodeCount).nodes(lb.getNodes())
|
.protocol(lb.getProtocol()).port(lb.getPort()).nodeCount(lb.nodeCount).nodes(lb.getNodes())
|
||||||
.timeout(lb.getTimeout()).algorithm(lb.getAlgorithm()).halfClosed(lb.isHalfClosed())
|
.timeout(lb.getTimeout()).algorithm(lb.getAlgorithm()).halfClosed(lb.isHalfClosed())
|
||||||
.sessionPersistenceType(lb.getSessionPersistenceType()).connectionLogging(lb.isConnectionLogging())
|
.sessionPersistenceType(lb.getSessionPersistenceType()).connectionLogging(lb.isConnectionLogging())
|
||||||
.connectionThrottle(lb.getConnectionThrottle()).healthMonitor(lb.getHealthMonitor())
|
.connectionThrottle(lb.getConnectionThrottle()).healthMonitor(lb.getHealthMonitor());
|
||||||
.metadata(lb.getMetadata());
|
|
||||||
|
|
||||||
if (lb.cluster.size() == 1)
|
if (lb.cluster.size() == 1)
|
||||||
builder.clusterName(Iterables.get(lb.cluster.values(), 0));
|
builder.clusterName(Iterables.get(lb.cluster.values(), 0));
|
||||||
|
@ -81,6 +81,10 @@ public class ConvertLB implements Function<LB, LoadBalancer> {
|
||||||
builder.virtualIPs(ImmutableSet.<VirtualIPWithId> of());
|
builder.virtualIPs(ImmutableSet.<VirtualIPWithId> of());
|
||||||
else
|
else
|
||||||
builder.virtualIPs(lb.virtualIps);
|
builder.virtualIPs(lb.virtualIps);
|
||||||
|
if (lb.metadata == null)
|
||||||
|
builder.metadata(new Metadata());
|
||||||
|
else
|
||||||
|
builder.metadata(ParseMetadata.transformCLBMetadataToMetadata(lb.metadata));
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.jclouds.rackspace.cloudloadbalancers.functions;
|
package org.jclouds.rackspace.cloudloadbalancers.functions;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ import org.jclouds.rackspace.cloudloadbalancers.domain.SSLTermination;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.SourceAddresses;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.SourceAddresses;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.VirtualIPWithId;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.VirtualIPWithId;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseLoadBalancer;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseLoadBalancer;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.functions.ParseMetadata.CLBMetadata;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
@ -49,6 +51,7 @@ class LB extends BaseLoadBalancer<Node, LB> {
|
||||||
SSLTermination sslTermination;
|
SSLTermination sslTermination;
|
||||||
SourceAddresses sourceAddresses;
|
SourceAddresses sourceAddresses;
|
||||||
Set<AccessRuleWithId> accessList;
|
Set<AccessRuleWithId> accessList;
|
||||||
|
List<CLBMetadata> metadata;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.rackspace.cloudloadbalancers.functions;
|
||||||
|
|
||||||
|
import static org.jclouds.http.HttpUtils.releasePayload;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
import org.jclouds.http.functions.ParseJson;
|
||||||
|
import org.jclouds.json.Json;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Metadata;
|
||||||
|
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Everett Toews
|
||||||
|
*/
|
||||||
|
public class ParseMetadata extends ParseJson<Metadata> {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ParseMetadata(Json json, TypeLiteral<Metadata> type) {
|
||||||
|
super(json, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Metadata apply(HttpResponse response) {
|
||||||
|
Map<String, List<CLBMetadata>> clbMetadata;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Type clbMetadataType = new TypeLiteral<Map<String, List<CLBMetadata>>>() {}.getType();
|
||||||
|
clbMetadata = apply(response.getPayload().getInput(), clbMetadataType);
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
StringBuilder message = new StringBuilder();
|
||||||
|
message.append("Error parsing response");
|
||||||
|
logger.error(e, message.toString());
|
||||||
|
throw new HttpResponseException(message.toString() + "\n" + response, null, response, e);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
releasePayload(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return transformCLBMetadataToMetadata(clbMetadata.get("metadata"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Metadata transformCLBMetadataToMetadata(List<CLBMetadata> clbMetadatum) {
|
||||||
|
Metadata metadata = new Metadata();
|
||||||
|
|
||||||
|
for (CLBMetadata clbMetadata: clbMetadatum) {
|
||||||
|
metadata.put(clbMetadata.key, clbMetadata.value);
|
||||||
|
metadata.putId(clbMetadata.key, clbMetadata.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is here only to deal with the metadata format in CLB.
|
||||||
|
*/
|
||||||
|
public static class CLBMetadata {
|
||||||
|
private int id;
|
||||||
|
private String key;
|
||||||
|
private String value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.rackspace.cloudloadbalancers.functions;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.http.functions.ParseJson;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Node;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Node.Status;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseNode;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.functions.ParseMetadata.CLBMetadata;
|
||||||
|
import org.jclouds.rest.InvocationContext;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Everett Toews
|
||||||
|
*/
|
||||||
|
public class ParseNode implements Function<HttpResponse, Node>, InvocationContext<ParseNode> {
|
||||||
|
|
||||||
|
private final ParseJson<Map<String, NodeWithCLBMetadata>> json;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ParseNode(ParseJson<Map<String, NodeWithCLBMetadata>> json) {
|
||||||
|
this.json = checkNotNull(json, "json");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node apply(HttpResponse response) {
|
||||||
|
Map<String, NodeWithCLBMetadata> map = json.apply(response);
|
||||||
|
|
||||||
|
if (map == null || map.size() == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
NodeWithCLBMetadata nodeWithCLBMetadata = Iterables.get(map.values(), 0);
|
||||||
|
Node node = Node.builder()
|
||||||
|
.address(nodeWithCLBMetadata.getAddress())
|
||||||
|
.port(nodeWithCLBMetadata.getPort())
|
||||||
|
.condition(nodeWithCLBMetadata.getCondition())
|
||||||
|
.type(nodeWithCLBMetadata.getType())
|
||||||
|
.weight(nodeWithCLBMetadata.getWeight())
|
||||||
|
.id(nodeWithCLBMetadata.id)
|
||||||
|
.status(nodeWithCLBMetadata.status)
|
||||||
|
.metadata(ParseMetadata.transformCLBMetadataToMetadata(nodeWithCLBMetadata.metadata))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParseNode setContext(HttpRequest request) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is here only to deal with the metadata format in CLB.
|
||||||
|
*/
|
||||||
|
private static class NodeWithCLBMetadata extends BaseNode<Node> {
|
||||||
|
private int id;
|
||||||
|
private Status status;
|
||||||
|
private List<CLBMetadata> metadata;
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@
|
||||||
package org.jclouds.rackspace.cloudloadbalancers.features;
|
package org.jclouds.rackspace.cloudloadbalancers.features;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -30,6 +31,7 @@ import org.jclouds.rackspace.cloudloadbalancers.CloudLoadBalancersApi;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerAttributes;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerAttributes;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerRequest;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerRequest;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Metadata;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeRequest;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeRequest;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.VirtualIP;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.VirtualIP;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.functions.ParseLoadBalancerTest;
|
import org.jclouds.rackspace.cloudloadbalancers.functions.ParseLoadBalancerTest;
|
||||||
|
@ -37,6 +39,7 @@ import org.jclouds.rackspace.cloudloadbalancers.functions.ParseLoadBalancersTest
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.internal.BaseCloudLoadBalancerApiExpectTest;
|
import org.jclouds.rackspace.cloudloadbalancers.internal.BaseCloudLoadBalancerApiExpectTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,7 +58,7 @@ public class LoadBalancerApiExpectTest extends BaseCloudLoadBalancerApiExpectTes
|
||||||
).getLoadBalancerApiForZone("DFW");
|
).getLoadBalancerApiForZone("DFW");
|
||||||
|
|
||||||
Set<LoadBalancer> loadBalancers = api.list().concat().toSet();
|
Set<LoadBalancer> loadBalancers = api.list().concat().toSet();
|
||||||
assertEquals(loadBalancers, testLoadBalancers());
|
assertEquals(loadBalancers, getExpectedLoadBalancers());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetLoadBalancer() throws Exception {
|
public void testGetLoadBalancer() throws Exception {
|
||||||
|
@ -68,7 +71,7 @@ public class LoadBalancerApiExpectTest extends BaseCloudLoadBalancerApiExpectTes
|
||||||
).getLoadBalancerApiForZone("DFW");
|
).getLoadBalancerApiForZone("DFW");
|
||||||
|
|
||||||
LoadBalancer loadBalancer = api.get(2000);
|
LoadBalancer loadBalancer = api.get(2000);
|
||||||
assertEquals(loadBalancer, testLoadBalancer());
|
assertEquals(loadBalancer, getExpectedLoadBalancer());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCreateLoadBalancer() throws Exception {
|
public void testCreateLoadBalancer() throws Exception {
|
||||||
|
@ -109,7 +112,7 @@ public class LoadBalancerApiExpectTest extends BaseCloudLoadBalancerApiExpectTes
|
||||||
|
|
||||||
LoadBalancer loadBalancer = api.create(lbRequest);
|
LoadBalancer loadBalancer = api.create(lbRequest);
|
||||||
|
|
||||||
assertEquals(loadBalancer, testLoadBalancer());
|
assertEquals(loadBalancer, getExpectedLoadBalancer());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUpdateLoadBalancerAttributes() {
|
public void testUpdateLoadBalancerAttributes() {
|
||||||
|
@ -146,11 +149,84 @@ public class LoadBalancerApiExpectTest extends BaseCloudLoadBalancerApiExpectTes
|
||||||
api.remove(2000);
|
api.remove(2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object testLoadBalancer() {
|
public void testListMetadata() {
|
||||||
|
URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers/2000/metadata");
|
||||||
|
LoadBalancerApi api = requestsSendResponses(
|
||||||
|
rackspaceAuthWithUsernameAndApiKey,
|
||||||
|
responseWithAccess,
|
||||||
|
authenticatedGET().endpoint(endpoint).build(),
|
||||||
|
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/metadata-list.json")).build()
|
||||||
|
).getLoadBalancerApiForZone("DFW");
|
||||||
|
|
||||||
|
Metadata metadata = api.getMetadata(2000);
|
||||||
|
assertEquals(metadata, getExpectedMetadataWithIds());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateMetadata() {
|
||||||
|
URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers/2000/metadata");
|
||||||
|
LoadBalancerApi api = requestsSendResponses(
|
||||||
|
rackspaceAuthWithUsernameAndApiKey,
|
||||||
|
responseWithAccess,
|
||||||
|
authenticatedGET()
|
||||||
|
.method("POST")
|
||||||
|
.endpoint(endpoint)
|
||||||
|
.payload(payloadFromResourceWithContentType("/metadata-create.json", MediaType.APPLICATION_JSON)).build(),
|
||||||
|
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/metadata-list.json")).build()
|
||||||
|
).getLoadBalancerApiForZone("DFW");
|
||||||
|
|
||||||
|
Metadata metadata = api.createMetadata(2000, getExpectedMetadata());
|
||||||
|
assertEquals(metadata, getExpectedMetadataWithIds());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRemoveSingleMetadata() {
|
||||||
|
URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers/2000/metadata/23");
|
||||||
|
LoadBalancerApi api = requestsSendResponses(
|
||||||
|
rackspaceAuthWithUsernameAndApiKey,
|
||||||
|
responseWithAccess,
|
||||||
|
authenticatedGET().method("DELETE").endpoint(endpoint).replaceHeader("Accept", MediaType.WILDCARD).build(),
|
||||||
|
HttpResponse.builder().statusCode(200).build()
|
||||||
|
).getLoadBalancerApiForZone("DFW");
|
||||||
|
|
||||||
|
assertTrue(api.removeMetadatum(2000, 23));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRemoveManyMetadata() {
|
||||||
|
URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers/2000/metadata?id=23&id=24");
|
||||||
|
LoadBalancerApi api = requestsSendResponses(
|
||||||
|
rackspaceAuthWithUsernameAndApiKey,
|
||||||
|
responseWithAccess,
|
||||||
|
authenticatedGET().method("DELETE").endpoint(endpoint).replaceHeader("Accept", MediaType.WILDCARD).build(),
|
||||||
|
HttpResponse.builder().statusCode(200).build()
|
||||||
|
).getLoadBalancerApiForZone("DFW");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
assertTrue(api.removeMetadata(2000, ImmutableList.<Integer> of(23, 24)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getExpectedLoadBalancer() {
|
||||||
return new ParseLoadBalancerTest().expected();
|
return new ParseLoadBalancerTest().expected();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<LoadBalancer> testLoadBalancers() {
|
private Set<LoadBalancer> getExpectedLoadBalancers() {
|
||||||
return new ParseLoadBalancersTest().data();
|
return new ParseLoadBalancersTest().data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Metadata getExpectedMetadata() {
|
||||||
|
Metadata metadata = new Metadata();
|
||||||
|
metadata.put("color", "red");
|
||||||
|
metadata.put("label", "web-load-balancer");
|
||||||
|
metadata.put("os", "ubuntu");
|
||||||
|
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Metadata getExpectedMetadataWithIds() {
|
||||||
|
Metadata metadata = getExpectedMetadata();
|
||||||
|
metadata.putId("color", 1);
|
||||||
|
metadata.putId("label", 2);
|
||||||
|
metadata.putId("os", 3);
|
||||||
|
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,20 +22,25 @@ import static org.jclouds.rackspace.cloudloadbalancers.predicates.LoadBalancerPr
|
||||||
import static org.jclouds.rackspace.cloudloadbalancers.predicates.LoadBalancerPredicates.awaitDeleted;
|
import static org.jclouds.rackspace.cloudloadbalancers.predicates.LoadBalancerPredicates.awaitDeleted;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerAttributes;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerAttributes;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerRequest;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerRequest;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Metadata;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeRequest;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeRequest;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.VirtualIP.Type;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.VirtualIP.Type;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.internal.BaseCloudLoadBalancersApiLiveTest;
|
import org.jclouds.rackspace.cloudloadbalancers.internal.BaseCloudLoadBalancersApiLiveTest;
|
||||||
import org.testng.annotations.AfterGroups;
|
import org.testng.annotations.AfterGroups;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
@ -147,6 +152,39 @@ public class LoadBalancerApiLiveTest extends BaseCloudLoadBalancersApiLiveTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testListLoadBalancers")
|
||||||
|
public void testLoadBalancerMetadata() throws Exception {
|
||||||
|
for (LoadBalancer lb: lbs) {
|
||||||
|
Map<String, String> metadataMap = ImmutableMap.<String, String> of(
|
||||||
|
"key1", "value1",
|
||||||
|
"key2", "value2",
|
||||||
|
"key3", "value3");
|
||||||
|
|
||||||
|
Metadata metadata = clbApi.getLoadBalancerApiForZone(lb.getRegion()).createMetadata(lb.getId(), metadataMap);
|
||||||
|
assertEquals(metadata, getExpectedMetadata());
|
||||||
|
assertTrue(awaitAvailable(clbApi.getLoadBalancerApiForZone(lb.getRegion())).apply(lb));
|
||||||
|
|
||||||
|
metadata = clbApi.getLoadBalancerApiForZone(lb.getRegion()).getMetadata(lb.getId());
|
||||||
|
assertEquals(metadata, getExpectedMetadata());
|
||||||
|
|
||||||
|
assertTrue(clbApi.getLoadBalancerApiForZone(lb.getRegion()).updateMetadatum(lb.getId(), metadata.getId("key1"), "key1-updated"));
|
||||||
|
assertTrue(awaitAvailable(clbApi.getLoadBalancerApiForZone(lb.getRegion())).apply(lb));
|
||||||
|
metadata = clbApi.getLoadBalancerApiForZone(lb.getRegion()).getMetadata(lb.getId());
|
||||||
|
assertEquals(metadata.get("key1"), "key1-updated");
|
||||||
|
|
||||||
|
assertTrue(clbApi.getLoadBalancerApiForZone(lb.getRegion()).removeMetadatum(lb.getId(), metadata.getId("key1")));
|
||||||
|
assertTrue(awaitAvailable(clbApi.getLoadBalancerApiForZone(lb.getRegion())).apply(lb));
|
||||||
|
metadata = clbApi.getLoadBalancerApiForZone(lb.getRegion()).getMetadata(lb.getId());
|
||||||
|
assertNull(metadata.get("key1"));
|
||||||
|
|
||||||
|
assertTrue(clbApi.getLoadBalancerApiForZone(lb.getRegion()).removeMetadata(lb.getId(),
|
||||||
|
ImmutableList.<Integer> of(metadata.getId("key2"), metadata.getId("key3"))));
|
||||||
|
assertTrue(awaitAvailable(clbApi.getLoadBalancerApiForZone(lb.getRegion())).apply(lb));
|
||||||
|
metadata = clbApi.getLoadBalancerApiForZone(lb.getRegion()).getMetadata(lb.getId());
|
||||||
|
assertEquals(metadata.size(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void checkLBInRegion(String region, LoadBalancer lb, String name) {
|
private void checkLBInRegion(String region, LoadBalancer lb, String name) {
|
||||||
assertEquals(lb.getRegion(), region);
|
assertEquals(lb.getRegion(), region);
|
||||||
assertEquals(lb.getName(), name);
|
assertEquals(lb.getName(), name);
|
||||||
|
@ -155,4 +193,12 @@ public class LoadBalancerApiLiveTest extends BaseCloudLoadBalancersApiLiveTest {
|
||||||
assertEquals(Iterables.get(lb.getVirtualIPs(), 0).getType(), Type.PUBLIC);
|
assertEquals(Iterables.get(lb.getVirtualIPs(), 0).getType(), Type.PUBLIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Metadata getExpectedMetadata() {
|
||||||
|
Metadata metadata = new Metadata();
|
||||||
|
metadata.put("key1", "value1");
|
||||||
|
metadata.put("key2", "value2");
|
||||||
|
metadata.put("key3", "value3");
|
||||||
|
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.jclouds.rackspace.cloudloadbalancers.features;
|
package org.jclouds.rackspace.cloudloadbalancers.features;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -27,13 +28,14 @@ import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.CloudLoadBalancersApi;
|
import org.jclouds.rackspace.cloudloadbalancers.CloudLoadBalancersApi;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Metadata;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.Node;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Node;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeAttributes;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeAttributes;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeRequest;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeRequest;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.features.NodeApi;
|
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.internal.BaseCloudLoadBalancerApiExpectTest;
|
import org.jclouds.rackspace.cloudloadbalancers.internal.BaseCloudLoadBalancerApiExpectTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.ImmutableSortedSet;
|
import com.google.common.collect.ImmutableSortedSet;
|
||||||
|
|
||||||
|
@ -52,7 +54,7 @@ public class NodeApiExpectTest extends BaseCloudLoadBalancerApiExpectTest<CloudL
|
||||||
).getNodeApiForZoneAndLoadBalancer("DFW", 2000);
|
).getNodeApiForZoneAndLoadBalancer("DFW", 2000);
|
||||||
|
|
||||||
Set<Node> nodes = api.list().concat().toSet();
|
Set<Node> nodes = api.list().concat().toSet();
|
||||||
assertEquals(nodes, testNodes());
|
assertEquals(nodes, getExpectedNodes());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetNodeInLoadBalancer() {
|
public void testGetNodeInLoadBalancer() {
|
||||||
|
@ -106,7 +108,7 @@ public class NodeApiExpectTest extends BaseCloudLoadBalancerApiExpectTest<CloudL
|
||||||
Set<NodeRequest> nodeRequests = ImmutableSortedSet.<NodeRequest> of(nodeRequest1, nodeRequest2, nodeRequest3);
|
Set<NodeRequest> nodeRequests = ImmutableSortedSet.<NodeRequest> of(nodeRequest1, nodeRequest2, nodeRequest3);
|
||||||
|
|
||||||
Set<Node> nodes = api.add(nodeRequests);
|
Set<Node> nodes = api.add(nodeRequests);
|
||||||
assertEquals(nodes, testNodes());
|
assertEquals(nodes, getExpectedNodes());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUpdateAttributesForNodeInLoadBalancer() {
|
public void testUpdateAttributesForNodeInLoadBalancer() {
|
||||||
|
@ -152,7 +154,80 @@ public class NodeApiExpectTest extends BaseCloudLoadBalancerApiExpectTest<CloudL
|
||||||
api.remove(nodeIds);
|
api.remove(nodeIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Node> testNodes() {
|
public void testListMetadata() {
|
||||||
|
URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers/2000/nodes/410/metadata");
|
||||||
|
NodeApi api = requestsSendResponses(
|
||||||
|
rackspaceAuthWithUsernameAndApiKey,
|
||||||
|
responseWithAccess,
|
||||||
|
authenticatedGET().endpoint(endpoint).build(),
|
||||||
|
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/metadata-list.json")).build()
|
||||||
|
).getNodeApiForZoneAndLoadBalancer("DFW", 2000);
|
||||||
|
|
||||||
|
Metadata metadata = api.getMetadata(410);
|
||||||
|
assertEquals(metadata, getExpectedMetadataWithIds());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateMetadata() {
|
||||||
|
URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers/2000/nodes/410/metadata");
|
||||||
|
NodeApi api = requestsSendResponses(
|
||||||
|
rackspaceAuthWithUsernameAndApiKey,
|
||||||
|
responseWithAccess,
|
||||||
|
authenticatedGET()
|
||||||
|
.method("POST")
|
||||||
|
.endpoint(endpoint)
|
||||||
|
.payload(payloadFromResourceWithContentType("/metadata-create.json", MediaType.APPLICATION_JSON)).build(),
|
||||||
|
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/metadata-list.json")).build()
|
||||||
|
).getNodeApiForZoneAndLoadBalancer("DFW", 2000);
|
||||||
|
|
||||||
|
Metadata metadata = api.createMetadata(410, getExpectedMetadata());
|
||||||
|
assertEquals(metadata, getExpectedMetadataWithIds());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRemoveSingleMetadata() {
|
||||||
|
URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers/2000/nodes/410/metadata/23");
|
||||||
|
NodeApi api = requestsSendResponses(
|
||||||
|
rackspaceAuthWithUsernameAndApiKey,
|
||||||
|
responseWithAccess,
|
||||||
|
authenticatedGET().method("DELETE").endpoint(endpoint).replaceHeader("Accept", MediaType.WILDCARD).build(),
|
||||||
|
HttpResponse.builder().statusCode(200).build()
|
||||||
|
).getNodeApiForZoneAndLoadBalancer("DFW", 2000);
|
||||||
|
|
||||||
|
assertTrue(api.removeMetadatum(410, 23));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRemoveManyMetadata() {
|
||||||
|
URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers/2000/nodes/410/metadata?id=23&id=24");
|
||||||
|
NodeApi api = requestsSendResponses(
|
||||||
|
rackspaceAuthWithUsernameAndApiKey,
|
||||||
|
responseWithAccess,
|
||||||
|
authenticatedGET().method("DELETE").endpoint(endpoint).replaceHeader("Accept", MediaType.WILDCARD).build(),
|
||||||
|
HttpResponse.builder().statusCode(200).build()
|
||||||
|
).getNodeApiForZoneAndLoadBalancer("DFW", 2000);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
assertTrue(api.removeMetadata(410, ImmutableList.<Integer> of(23, 24)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Metadata getExpectedMetadata() {
|
||||||
|
Metadata metadata = new Metadata();
|
||||||
|
metadata.put("color", "red");
|
||||||
|
metadata.put("label", "web-load-balancer");
|
||||||
|
metadata.put("os", "ubuntu");
|
||||||
|
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Metadata getExpectedMetadataWithIds() {
|
||||||
|
Metadata metadata = getExpectedMetadata();
|
||||||
|
metadata.putId("color", 1);
|
||||||
|
metadata.putId("label", 2);
|
||||||
|
metadata.putId("os", 3);
|
||||||
|
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<Node> getExpectedNodes() {
|
||||||
Node node1 = Node.builder()
|
Node node1 = Node.builder()
|
||||||
.id(410)
|
.id(410)
|
||||||
.address("10.1.1.1")
|
.address("10.1.1.1")
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.jclouds.rackspace.cloudloadbalancers.features;
|
||||||
import static org.jclouds.rackspace.cloudloadbalancers.predicates.LoadBalancerPredicates.awaitAvailable;
|
import static org.jclouds.rackspace.cloudloadbalancers.predicates.LoadBalancerPredicates.awaitAvailable;
|
||||||
import static org.jclouds.rackspace.cloudloadbalancers.predicates.LoadBalancerPredicates.awaitDeleted;
|
import static org.jclouds.rackspace.cloudloadbalancers.predicates.LoadBalancerPredicates.awaitDeleted;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -30,11 +31,14 @@ import java.util.Set;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerRequest;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerRequest;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Metadata;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.Node;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Node;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeAttributes;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeAttributes;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeRequest;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeRequest;
|
||||||
|
@ -135,6 +139,41 @@ public class NodeApiLiveTest extends BaseCloudLoadBalancersApiLiveTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testListNodes")
|
||||||
|
public void testNodeMetadata() throws Exception {
|
||||||
|
for (Entry<LoadBalancer, Set<Node>> entry : nodes.entrySet()) {
|
||||||
|
LoadBalancer lb = entry.getKey();
|
||||||
|
Node node = entry.getValue().iterator().next();
|
||||||
|
Map<String, String> metadataMap = ImmutableMap.<String, String> of(
|
||||||
|
"key1", "value1",
|
||||||
|
"key2", "value2",
|
||||||
|
"key3", "value3");
|
||||||
|
|
||||||
|
Metadata metadata = clbApi.getNodeApiForZoneAndLoadBalancer(lb.getRegion(), lb.getId()).createMetadata(node.getId(), metadataMap);
|
||||||
|
assertEquals(metadata, getExpectedMetadata());
|
||||||
|
assertTrue(awaitAvailable(clbApi.getLoadBalancerApiForZone(lb.getRegion())).apply(lb));
|
||||||
|
|
||||||
|
metadata = clbApi.getNodeApiForZoneAndLoadBalancer(lb.getRegion(), lb.getId()).getMetadata(node.getId());
|
||||||
|
assertEquals(metadata, getExpectedMetadata());
|
||||||
|
|
||||||
|
assertTrue(clbApi.getNodeApiForZoneAndLoadBalancer(lb.getRegion(), lb.getId()).updateMetadatum(node.getId(), metadata.getId("key1"), "key1-updated"));
|
||||||
|
assertTrue(awaitAvailable(clbApi.getLoadBalancerApiForZone(lb.getRegion())).apply(lb));
|
||||||
|
metadata = clbApi.getNodeApiForZoneAndLoadBalancer(lb.getRegion(), lb.getId()).getMetadata(node.getId());
|
||||||
|
assertEquals(metadata.get("key1"), "key1-updated");
|
||||||
|
|
||||||
|
assertTrue(clbApi.getNodeApiForZoneAndLoadBalancer(lb.getRegion(), lb.getId()).removeMetadatum(node.getId(), metadata.getId("key1")));
|
||||||
|
assertTrue(awaitAvailable(clbApi.getLoadBalancerApiForZone(lb.getRegion())).apply(lb));
|
||||||
|
metadata = clbApi.getNodeApiForZoneAndLoadBalancer(lb.getRegion(), lb.getId()).getMetadata(node.getId());
|
||||||
|
assertNull(metadata.get("key1"));
|
||||||
|
|
||||||
|
assertTrue(clbApi.getNodeApiForZoneAndLoadBalancer(lb.getRegion(), lb.getId()).removeMetadata(node.getId(),
|
||||||
|
ImmutableList.<Integer> of(metadata.getId("key2"), metadata.getId("key3"))));
|
||||||
|
assertTrue(awaitAvailable(clbApi.getLoadBalancerApiForZone(lb.getRegion())).apply(lb));
|
||||||
|
metadata = clbApi.getNodeApiForZoneAndLoadBalancer(lb.getRegion(), lb.getId()).getMetadata(node.getId());
|
||||||
|
assertEquals(metadata.size(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@AfterGroups(groups = "live")
|
@AfterGroups(groups = "live")
|
||||||
protected void tearDownContext() {
|
protected void tearDownContext() {
|
||||||
|
@ -150,4 +189,13 @@ public class NodeApiLiveTest extends BaseCloudLoadBalancersApiLiveTest {
|
||||||
}
|
}
|
||||||
super.tearDownContext();
|
super.tearDownContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Metadata getExpectedMetadata() {
|
||||||
|
Metadata metadata = new Metadata();
|
||||||
|
metadata.put("key1", "value1");
|
||||||
|
metadata.put("key2", "value2");
|
||||||
|
metadata.put("key3", "value3");
|
||||||
|
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,12 @@ public class ParseLoadBalancerTest extends BaseItemParserTest<LoadBalancer> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoadBalancer expected() {
|
public LoadBalancer expected() {
|
||||||
|
Metadata metadata = new Metadata();
|
||||||
|
metadata.put("color", "red");
|
||||||
|
metadata.putId("color", 1);
|
||||||
|
metadata.put("label", "web-load-balancer");
|
||||||
|
metadata.putId("label", 2);
|
||||||
|
|
||||||
return LoadBalancer
|
return LoadBalancer
|
||||||
.builder()
|
.builder()
|
||||||
.region("DFW")
|
.region("DFW")
|
||||||
|
@ -88,9 +94,7 @@ public class ParseLoadBalancerTest extends BaseItemParserTest<LoadBalancer> {
|
||||||
.clusterName("c1.dfw1")
|
.clusterName("c1.dfw1")
|
||||||
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2010-11-30T03:23:42Z"))
|
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2010-11-30T03:23:42Z"))
|
||||||
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2010-11-30T03:23:44Z"))
|
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2010-11-30T03:23:44Z"))
|
||||||
.metadata(ImmutableSet.<Metadata> of(
|
.metadata(metadata).build();
|
||||||
Metadata.builder().id(1).key("color").value("red").build(),
|
|
||||||
Metadata.builder().id(2).key("label").value("web-load-balancer").build())).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add factory binding as this is not default
|
// add factory binding as this is not default
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
{"metadata":[{"key":"os","value":"ubuntu"},{"key":"color","value":"red"},{"key":"label","value":"web-load-balancer"}]}
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"key": "color",
|
||||||
|
"value": "red"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2",
|
||||||
|
"key": "label",
|
||||||
|
"value": "web-load-balancer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3",
|
||||||
|
"key": "os",
|
||||||
|
"value": "ubuntu"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue