Merge pull request #160 from danikov/add-nodeclient

Issue 551: Added NodeClient
This commit is contained in:
Adrian Cole 2011-11-16 22:55:14 -08:00
commit 04f2cdbd90
17 changed files with 840 additions and 5 deletions

View File

@ -21,6 +21,7 @@ package org.jclouds.cloudloadbalancers;
import java.util.Set;
import org.jclouds.cloudloadbalancers.features.LoadBalancerAsyncClient;
import org.jclouds.cloudloadbalancers.features.NodeAsyncClient;
import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.rest.annotations.Delegate;
@ -54,5 +55,12 @@ public interface CloudLoadBalancersAsyncClient {
@Delegate
LoadBalancerAsyncClient getLoadBalancerClient(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) String region);
/**
* Provides asynchronous access to Node features.
*/
@Delegate
NodeAsyncClient getNodeClient(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) String region);
}

View File

@ -22,6 +22,7 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.cloudloadbalancers.features.LoadBalancerClient;
import org.jclouds.cloudloadbalancers.features.NodeClient;
import org.jclouds.concurrent.Timeout;
import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
@ -56,5 +57,12 @@ public interface CloudLoadBalancersClient {
@Delegate
LoadBalancerClient getLoadBalancerClient(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) String region);
/**
* Provides synchronous access to Node features.
*/
@Delegate
NodeClient getNodeClient(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) String region);
}

View File

@ -0,0 +1,39 @@
/**
* 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.cloudloadbalancers;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
/**
* Represents a Node endpoint
*
* @author Dan Lo Bianco
*
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Qualifier
public @interface Node {
}

View File

@ -32,6 +32,8 @@ import org.jclouds.cloudloadbalancers.CloudLoadBalancersAsyncClient;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersClient;
import org.jclouds.cloudloadbalancers.features.LoadBalancerAsyncClient;
import org.jclouds.cloudloadbalancers.features.LoadBalancerClient;
import org.jclouds.cloudloadbalancers.features.NodeAsyncClient;
import org.jclouds.cloudloadbalancers.features.NodeClient;
import org.jclouds.cloudloadbalancers.handlers.ParseCloudLoadBalancersErrorFromHttpResponse;
import org.jclouds.cloudloadbalancers.reference.RackspaceConstants;
import org.jclouds.http.HttpErrorHandler;
@ -74,6 +76,7 @@ public class CloudLoadBalancersRestClientModule extends
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
.put(LoadBalancerClient.class, LoadBalancerAsyncClient.class)//
.put(NodeClient.class, NodeAsyncClient.class)//
.build();
public CloudLoadBalancersRestClientModule() {

View File

@ -171,7 +171,7 @@ public class Node extends BaseNode<Node> {
@Override
public String toString() {
return String.format("[id=%s, address=%s, condition=%s, port=%s, weight=%s,status=%s]", id, address, condition,
return String.format("[id=%s, address=%s, condition=%s, port=%s, weight=%s, status=%s]", id, address, condition,
port, weight, status);
}

View File

@ -0,0 +1,94 @@
/**
* 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.cloudloadbalancers.domain;
import org.jclouds.cloudloadbalancers.domain.internal.BaseNode;
import org.jclouds.cloudloadbalancers.domain.internal.BaseNode.Condition;
/**
*
* @author Dan Lo Bianco
* @see <a href=
* "http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/Modify_Nodes-d1e2503.html"
* />
*/
public class NodeAttributes {
protected String condition;
protected Integer weight;
public NodeAttributes condition(String condition) {
this.condition = condition;
return this;
}
public NodeAttributes weight(int weight) {
this.weight = weight;
return this;
}
public static <T extends BaseNode<T>> NodeAttributes fromNode(T n) {
return Builder.condition(n.getCondition()).weight(n.getWeight());
}
public static class Builder {
public static NodeAttributes condition(Condition condition) {
return new NodeAttributes().condition(condition.name());
}
public static NodeAttributes weight(int weight) {
return new NodeAttributes().weight(weight);
}
}
@Override
public String toString() {
return String.format("[condition=%s, weight=%s]", condition, weight);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((condition == null) ? 0 : condition.hashCode());
result = prime * result + ((weight == null) ? 0 : weight.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
NodeAttributes other = (NodeAttributes) obj;
if (condition == null) {
if (other.condition != null)
return false;
} else if (!condition.equals(other.condition))
return false;
if (weight == null) {
if (other.weight != null)
return false;
} else if (!weight.equals(other.weight))
return false;
return true;
}
}

View File

@ -0,0 +1,125 @@
/**
* 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.cloudloadbalancers.features;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudloadbalancers.domain.Node;
import org.jclouds.cloudloadbalancers.domain.NodeAttributes;
import org.jclouds.cloudloadbalancers.domain.NodeRequest;
import org.jclouds.openstack.filters.AuthenticateRequest;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.SkipEncoding;
import org.jclouds.rest.annotations.WrapWith;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to CloudLoadBalancers Node features.
* <p/>
*
* @see NodeAsyncClient
* @see <a
* href="http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/Nodes-d1e2173.html"
* />
* @author Dan Lo Bianco
*/
@SkipEncoding('/')
@RequestFilters(AuthenticateRequest.class)
public interface NodeAsyncClient {
/**
* @see NodeClient#createNodesInLoadBalancer
*/
@POST
@SelectJson("nodes")
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Path("/loadbalancers/{lbid}/nodes")
ListenableFuture<Set<Node>> createNodesInLoadBalancer(@WrapWith("nodes") Set<NodeRequest> nodes,
@PathParam("lbid") int lbid);
/**
* @see NodeClient#updateAttributesForNodeInLoadBalancer
*/
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Path("/loadbalancers/{lbid}/nodes/{nid}")
ListenableFuture<Void> updateAttributesForNodeInLoadBalancer(@WrapWith("node") NodeAttributes attrs,
@PathParam("nid") int nid,
@PathParam("lbid") int lbid);
/**
* @see NodeClient#listNodes
*/
@GET
@SelectJson("nodes")
@Consumes(MediaType.APPLICATION_JSON)
@Path("/loadbalancers/{lbid}/nodes")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Node>> listNodes(@PathParam("lbid") int lbid);
/**
* @see NodeClient#getNodeInLoadBalancer
*/
@GET
@SelectJson("node")
@Consumes(MediaType.APPLICATION_JSON)
@Path("/loadbalancers/{lbid}/nodes/{nid}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Node> getNodeInLoadBalancer(@PathParam("nid") int nid,
@PathParam("lbid") int lbid);
/**
* @see NodeClient#removeNodeFromLoadBalancer
*/
@DELETE
@Path("/loadbalancers/{lbid}/nodes/{nid}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
@Consumes("*/*")
ListenableFuture<Void> removeNodeFromLoadBalancer(@PathParam("nid") int nid,
@PathParam("lbid") int lbid);
/**
* @see NodeClient#removeNodesFromLoadBalancer
*/
@DELETE
@Path("/loadbalancers/{lbid}/nodes")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
@Consumes("*/*")
ListenableFuture<Void> removeNodesFromLoadBalancer(@QueryParam("id") Set<Integer> nids,
@PathParam("lbid") int lbid);
}

View File

@ -0,0 +1,133 @@
/**
* 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.cloudloadbalancers.features;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.cloudloadbalancers.domain.LoadBalancerAttributes;
import org.jclouds.cloudloadbalancers.domain.Node;
import org.jclouds.cloudloadbalancers.domain.NodeAttributes;
import org.jclouds.cloudloadbalancers.domain.NodeRequest;
import org.jclouds.concurrent.Timeout;
import org.jclouds.http.HttpResponseException;
/**
* Provides synchronous access to CloudLoadBalancers Node features.
* <p/>
*
* @see NodeAsyncClient
* @see <a
* href="http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/Nodes-d1e2173.html"
* />
* @author Dan Lo Bianco
*/
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface NodeClient {
/**
* Create a new node with the configuration defined by the request.
*
* <p/>
* When a node is added, it is assigned a unique identifier that can be used for mutating operations
* such as changing the condition or removing it. Every load balancer is dual-homed on both the public
* Internet and ServiceNet; as a result, nodes can either be internal ServiceNet addresses or addresses
* on the public Internet.
*
* @param nodes
* configurations to create
* @param lbid
* loadbalancer on which to create the nodes
* @return created nodes
* @throws HttpResponseException
* If the corresponding request cannot be fulfilled due to insufficient or invalid
* data
*
*/
Set<Node> createNodesInLoadBalancer(Set<NodeRequest> nodes, int lbid);
/**
*
* Update the properties of a node.
*
* <p/>
* This operation asynchronously updates the attributes of the specified node. Upon
* successful validation of the request, the service will return a 202 (Accepted) response code.
* A caller can poll the load balancer with its ID to wait for the changes to be applied and the
* load balancer to return to an ACTIVE status.
*
* @param attrs
* what to change
* @param nid
* node to get
* @param lbid
* loadbalancer from which to get the node
*
* @see LoadBalancerAttributes#fromLoadBalancer
*/
void updateAttributesForNodeInLoadBalancer(NodeAttributes attrs, int nid, int lbid);
/**
*
* @return all nodes for a given loadbalancer, or empty set if none available
*
* @param lbid
* id of the loadbalancer to get the nodes for
*/
Set<Node> listNodes(int lbid);
/**
*
*
* @param nid
* node to get
* @param lbid
* loadbalancer from which to get the node
* @return details of the specified node, or null if not found
*/
Node getNodeInLoadBalancer(int nid, int lbid);
/**
* Remove a node from the account.
* <p/>
* The remove load balancer function removes the specified load balancer and its associated
* configuration from the account. Any and all configuration data is immediately purged and is
* not recoverable.
*
* @param nid
* node to remove
* @param lbid
* loadbalancer from which to remove the node
*/
void removeNodeFromLoadBalancer(int nid, int lbid);
/**
* Batch-remove nodes from the account.
* <p/>
* The current default limit is ten ids per request. Any and all configuration data is
* immediately purged and is not recoverable. By chance one of the items in the list
* cannot be removed due to its current status a 400:BadRequest is returned along with the ids
* of the ones the system identified as potential failures for this request
*
* @param nids
* nodes to remove
* @param lbid
* loadbalancer from which to remove the node
*/
void removeNodesFromLoadBalancer(Set<Integer> nids, int lbid);
}

View File

@ -30,6 +30,7 @@ import org.jclouds.cloudloadbalancers.domain.LoadBalancerRequest;
import org.jclouds.cloudloadbalancers.domain.NodeRequest;
import org.jclouds.cloudloadbalancers.domain.VirtualIP.Type;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.Iterables;
@ -43,6 +44,12 @@ import com.google.common.collect.Sets;
@Test(groups = "live", singleThreaded = true, testName = "LoadBalancerClientLiveTest")
public class LoadBalancerClientLiveTest extends BaseCloudLoadBalancersClientLiveTest {
private Set<LoadBalancer> lbs = Sets.newLinkedHashSet();
@BeforeGroups(groups = "live")
protected void setup() {
assertTrue(client.getConfiguredRegions().size() > 0, "Need to have some regions!");
Logger.getAnonymousLogger().info("running against regions "+client.getConfiguredRegions());
}
@AfterGroups(groups = "live")
protected void tearDown() {

View File

@ -0,0 +1,172 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudloadbalancers.features;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Properties;
import java.util.Set;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersAsyncClient;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersClient;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersContextBuilder;
import org.jclouds.cloudloadbalancers.domain.NodeAttributes;
import org.jclouds.cloudloadbalancers.domain.NodeAttributes.Builder;
import org.jclouds.cloudloadbalancers.domain.NodeRequest;
import org.jclouds.cloudloadbalancers.domain.internal.BaseNode.Condition;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseFirstJsonValueNamed;
import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code NodeAsyncClient}
*
* @author Dan Lo Bianco
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "NodeAsyncClientTest")
public class NodeAsyncClientTest extends BaseCloudLoadBalancersAsyncClientTest<NodeAsyncClient> {
public void testListNodes() throws SecurityException, NoSuchMethodException, IOException {
Method method = NodeAsyncClient.class.getMethod("listNodes", int.class);
HttpRequest httpRequest = processor.createRequest(method, 2);
assertRequestLineEquals(httpRequest,
"GET https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers/2/nodes HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseFirstJsonValueNamed.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testGetNodeInLoadBalancer() throws SecurityException, NoSuchMethodException, IOException {
Method method = NodeAsyncClient.class.getMethod("getNodeInLoadBalancer", int.class, int.class);
HttpRequest httpRequest = processor.createRequest(method, 3, 2);
assertRequestLineEquals(httpRequest,
"GET https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers/2/nodes/3 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseFirstJsonValueNamed.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void createNodesInLoadBalancerWithType() throws SecurityException, NoSuchMethodException, IOException {
Method method = NodeAsyncClient.class.getMethod("createNodesInLoadBalancer", Set.class, int.class);
HttpRequest httpRequest = processor.createRequest(method, Collections.<NodeRequest>singleton(NodeRequest.builder().
address("192.168.1.1").port(8080).build()), 3);
assertRequestLineEquals(httpRequest,
"POST https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers/3/nodes HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(
httpRequest,
"{\"nodes\":[{\"address\":\"192.168.1.1\",\"port\":8080,\"condition\":\"ENABLED\"}]}",
"application/json", false);
assertResponseParserClassEquals(method, httpRequest, ParseFirstJsonValueNamed.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testUpdateAttributesForNodeInLoadBalancer() throws SecurityException, NoSuchMethodException, IOException {
Method method = NodeAsyncClient.class.getMethod("updateAttributesForNodeInLoadBalancer", NodeAttributes.class,
int.class, int.class);
HttpRequest httpRequest = processor.createRequest(method, Builder.condition(Condition.DISABLED).weight(13), 8, 7);
assertRequestLineEquals(httpRequest,
"PUT https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers/7/nodes/8 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, "{\"node\":{\"condition\":\"DISABLED\",\"weight\":13}}", "application/json", false);
assertResponseParserClassEquals(method, httpRequest, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(httpRequest);
}
public void testRemoveNodeFromLoadBalancer() throws SecurityException, NoSuchMethodException, IOException {
Method method = NodeAsyncClient.class.getMethod("removeNodeFromLoadBalancer", int.class, int.class);
HttpRequest httpRequest = processor.createRequest(method, 9, 4);
assertRequestLineEquals(httpRequest,
"DELETE https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers/4/nodes/9 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: */*\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnVoidOnNotFoundOr404.class);
checkFilters(httpRequest);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<NodeAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<NodeAsyncClient>>() {
};
}
protected String provider = "cloudloadbalancers";
@Override
public RestContextSpec<CloudLoadBalancersClient, CloudLoadBalancersAsyncClient> createContextSpec() {
return new RestContextFactory(getProperties()).createContextSpec(provider, "user", "password", new Properties());
}
@Override
protected Properties getProperties() {
Properties overrides = new Properties();
overrides.setProperty(PROPERTY_REGIONS, "US");
overrides.setProperty(PROPERTY_API_VERSION, "1");
overrides.setProperty(provider + ".endpoint", "https://auth");
overrides.setProperty(provider + ".contextbuilder", CloudLoadBalancersContextBuilder.class.getName());
return overrides;
}
}

View File

@ -0,0 +1,143 @@
/**
* 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.cloudloadbalancers.features;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Logger;
import org.jclouds.cloudloadbalancers.domain.LoadBalancer;
import org.jclouds.cloudloadbalancers.domain.LoadBalancer.Status;
import org.jclouds.cloudloadbalancers.domain.LoadBalancerRequest;
import org.jclouds.cloudloadbalancers.domain.Node;
import org.jclouds.cloudloadbalancers.domain.NodeAttributes;
import org.jclouds.cloudloadbalancers.domain.NodeRequest;
import org.jclouds.cloudloadbalancers.domain.VirtualIP.Type;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code NodeClient}
*
* @author Dan Lo Bianco
*/
@Test(groups = "live", singleThreaded = true, testName = "NodeClientLiveTest")
public class NodeClientLiveTest extends BaseCloudLoadBalancersClientLiveTest {
private Map<LoadBalancer, Set<Node>> nodes = new HashMap<LoadBalancer, Set<Node>>();
@BeforeGroups(groups = "live")
protected void setup() {
assertTrue(client.getConfiguredRegions().size() > 0, "Need to have some regions!");
Logger.getAnonymousLogger().info("running against regions "+client.getConfiguredRegions());
for (String region : client.getConfiguredRegions()) {
Logger.getAnonymousLogger().info("starting lb in region " + region);
LoadBalancer lb = client.getLoadBalancerClient(region).createLoadBalancer(
LoadBalancerRequest.builder().name(prefix + "-" + region).protocol("HTTP").port(80).virtualIPType(
Type.PUBLIC).node(NodeRequest.builder().address("192.168.1.1").port(8080).build()).build());
nodes.put(lb, new HashSet<Node>());
assert loadBalancerActive.apply(lb) : lb;
}
}
@AfterGroups(groups = "live")
protected void tearDown() {
for (Entry<LoadBalancer, Set<Node>> entry : nodes.entrySet()) {
LoadBalancer lb = entry.getKey();
LoadBalancerClient lbClient = client.getLoadBalancerClient(lb.getRegion());
if(lbClient.getLoadBalancer(lb.getId()).getStatus() != Status.DELETED) {
lbClient.removeLoadBalancer(lb.getId());
}
assert loadBalancerDeleted.apply(lb) : lb;
}
super.tearDown();
}
public void testListNodes() throws Exception {
for (LoadBalancer lb : nodes.keySet()) {
Set<Node> response = client.getNodeClient(lb.getRegion()).listNodes(lb.getId());
assert null != response;
assertTrue(response.size() >= 0);
for (Node n : response) {
assert n.getId() != -1 : n;
assert n.getCondition() != null : n;
assert n.getAddress() != null : n;
assert n.getPort() != -1 : n;
assert n.getStatus() != null : n;
assert n.getWeight() != null : n; //FIXME may fail as can be null (json response doesn't have the attribute)
Node getDetails = client.getNodeClient(lb.getRegion()).getNodeInLoadBalancer(n.getId(), lb.getId());
System.out.println(n.toString());
try {
assertEquals(getDetails.getId(), n.getId());
assertEquals(getDetails.getCondition(), n.getCondition());
assertEquals(getDetails.getAddress(), n.getAddress());
assertEquals(getDetails.getPort(), n.getPort());
assertEquals(getDetails.getStatus(), n.getStatus());
assertEquals(getDetails.getWeight(), n.getWeight()); //FIXME disparity between list/get can lead these to mismatch
} catch (AssertionError e) {
throw new AssertionError(String.format("%s\n%s - %s", e.getMessage(),getDetails, n));
}
}
}
}
public void testAddNodes() throws Exception {
for (LoadBalancer lb : nodes.keySet()) {
String region = lb.getRegion();
Logger.getAnonymousLogger().info("starting node on loadbalancer "+lb.getId()+" in region "+region);
Set<Node> newNodes = client.getNodeClient(region).createNodesInLoadBalancer(Collections.<NodeRequest>singleton(
NodeRequest.builder().address("192.168.1.2").port(8080).build()), lb.getId());
for (Node n : newNodes) {
assertEquals(n.getStatus(), Node.Status.ONLINE);
nodes.get(lb).add(n);
assertEquals(client.getNodeClient(region).getNodeInLoadBalancer(n.getId(), lb.getId()).getStatus(), Node.Status.ONLINE);
}
assert loadBalancerActive.apply(lb) : lb;
}
}
@Test(dependsOnMethods = "testAddNodes")
public void testModifyNode() throws Exception {
for (Entry<LoadBalancer, Set<Node>> entry : nodes.entrySet()) {
for (Node n : entry.getValue()) {
String region = entry.getKey().getRegion();
client.getNodeClient(region).updateAttributesForNodeInLoadBalancer(NodeAttributes.Builder.weight(23),
n.getId(), entry.getKey().getId());
assertEquals(client.getNodeClient(region)
.getNodeInLoadBalancer(n.getId(), entry.getKey().getId()).getStatus(), Node.Status.ONLINE);
Node newNode = client.getNodeClient(region).getNodeInLoadBalancer(n.getId(), entry.getKey().getId());
assertEquals(newNode.getStatus(), Node.Status.ONLINE);
assertEquals(newNode.getWeight(), (Integer)23);
}
}
}
}

View File

@ -0,0 +1,9 @@
{"node": {
"id":410,
"address":"10.1.1.1",
"port":80,
"condition":"ENABLED",
"status":"ONLINE",
"weight":12
}
}

View File

@ -0,0 +1,28 @@
{
"nodes": [
{
"id":"410",
"address":"10.1.1.1",
"port":80,
"condition":"ENABLED",
"status":"ONLINE",
"weight":3
},
{
"id":"411",
"address":"10.1.1.2",
"port":80,
"condition":"ENABLED",
"status":"ONLINE",
"weight":8
},
{
"id":"412",
"address":"10.1.1.3",
"port":80,
"condition":"DISABLED",
"status":"ONLINE",
"weight":12
}
]
}

View File

@ -26,8 +26,8 @@ import org.testng.annotations.Test;
* @author Dan Lo Bianco
*/
@Test(groups = "live", singleThreaded = true)
public class CloudLoadBalancersUKClientLiveTest extends LoadBalancerClientLiveTest {
public CloudLoadBalancersUKClientLiveTest() {
public class CloudLoadBalancersUKLoadBalancerClientLiveTest extends LoadBalancerClientLiveTest {
public CloudLoadBalancersUKLoadBalancerClientLiveTest() {
provider = "cloudloadbalancers-uk";
}
}

View File

@ -0,0 +1,33 @@
/**
* 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;
import org.jclouds.cloudloadbalancers.features.NodeClientLiveTest;
import org.testng.annotations.Test;
/**
*
* @author Dan Lo Bianco
*/
@Test(groups = "live", singleThreaded = true)
public class CloudLoadBalancersUKNodeClientLiveTest extends NodeClientLiveTest {
public CloudLoadBalancersUKNodeClientLiveTest() {
provider = "cloudloadbalancers-uk";
}
}

View File

@ -26,8 +26,8 @@ import org.testng.annotations.Test;
* @author Dan Lo Bianco
*/
@Test(groups = "live", singleThreaded = true)
public class CloudLoadBalancersUSClientLiveTest extends LoadBalancerClientLiveTest {
public CloudLoadBalancersUSClientLiveTest() {
public class CloudLoadBalancersUSLoadBalancerClientLiveTest extends LoadBalancerClientLiveTest {
public CloudLoadBalancersUSLoadBalancerClientLiveTest() {
provider = "cloudloadbalancers-us";
}
}

View File

@ -0,0 +1,33 @@
/**
* 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;
import org.jclouds.cloudloadbalancers.features.NodeClientLiveTest;
import org.testng.annotations.Test;
/**
*
* @author Dan Lo Bianco
*/
@Test(groups = "live", singleThreaded = true)
public class CloudLoadBalancersUSNodeClientLiveTest extends NodeClientLiveTest {
public CloudLoadBalancersUSNodeClientLiveTest() {
provider = "cloudloadbalancers-us";
}
}