Issue 786:isolate stub computeservice contexts from eachother

This commit is contained in:
Adrian Cole 2011-12-18 15:19:49 -08:00
parent aa00e28d73
commit 39290d725c
4 changed files with 78 additions and 58 deletions

View File

@ -19,15 +19,17 @@
package org.jclouds.compute.stub.config;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.compute.JCloudsNativeComputeServiceAdapter;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
@ -46,8 +48,8 @@ import org.jclouds.rest.ResourceNotFoundException;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableList.Builder;
/**
*
@ -57,6 +59,7 @@ import com.google.common.collect.ImmutableSet;
public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAdapter {
private final Supplier<Location> location;
private final ConcurrentMap<String, NodeMetadata> nodes;
private final ExecutorService ioThreads;
private final Provider<Integer> idProvider;
private final String publicIpPrefix;
private final String privateIpPrefix;
@ -65,11 +68,13 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
private final Map<OsFamily, Map<String, String>> osToVersionMap;
@Inject
public StubComputeServiceAdapter(ConcurrentMap<String, NodeMetadata> nodes, Supplier<Location> location,
@Named("NODE_ID") Provider<Integer> idProvider, @Named("PUBLIC_IP_PREFIX") String publicIpPrefix,
@Named("PRIVATE_IP_PREFIX") String privateIpPrefix, @Named("PASSWORD_PREFIX") String passwordPrefix,
JustProvider locationSupplier, Map<OsFamily, Map<String, String>> osToVersionMap) {
public StubComputeServiceAdapter(ConcurrentMap<String, NodeMetadata> nodes,
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioThreads, Supplier<Location> location,
@Named("NODE_ID") Provider<Integer> idProvider, @Named("PUBLIC_IP_PREFIX") String publicIpPrefix,
@Named("PRIVATE_IP_PREFIX") String privateIpPrefix, @Named("PASSWORD_PREFIX") String passwordPrefix,
JustProvider locationSupplier, Map<OsFamily, Map<String, String>> osToVersionMap) {
this.nodes = nodes;
this.ioThreads=ioThreads;
this.location = location;
this.idProvider = idProvider;
this.publicIpPrefix = publicIpPrefix;
@ -79,6 +84,28 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
this.osToVersionMap = osToVersionMap;
}
protected void setStateOnNode(NodeState state, NodeMetadata node) {
nodes.put(node.getId(), NodeMetadataBuilder.fromNodeMetadata(node).state(state).build());
}
protected void setStateOnNodeAfterDelay(final NodeState state, final NodeMetadata node, final long millis) {
if (millis == 0l)
setStateOnNode(state, node);
else
ioThreads.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
Throwables.propagate(e);
}
setStateOnNode(state, node);
}
});
}
@Override
public NodeWithInitialCredentials createNodeWithGroupEncodedIntoName(String group, String name, Template template) {
NodeMetadataBuilder builder = new NodeMetadataBuilder();
@ -99,7 +126,7 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
builder.credentials(LoginCredentials.builder().user("root").password(passwordPrefix + id).build());
NodeMetadata node = builder.build();
nodes.put(node.getId(), node);
StubComputeServiceDependenciesModule.setState(node, NodeState.RUNNING, 100);
setStateOnNodeAfterDelay(NodeState.RUNNING, node, 100);
return new NodeWithInitialCredentials(node);
}
@ -149,9 +176,9 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
NodeMetadata node = nodes.get(id);
if (node == null)
return;
StubComputeServiceDependenciesModule.setState(node, NodeState.PENDING, 0);
StubComputeServiceDependenciesModule.setState(node, NodeState.TERMINATED, 50);
StubComputeServiceDependenciesModule.service.execute(new Runnable() {
setStateOnNodeAfterDelay(NodeState.PENDING, node, 0);
setStateOnNodeAfterDelay(NodeState.TERMINATED, node, 50);
ioThreads.execute(new Runnable() {
@Override
public void run() {
@ -172,8 +199,8 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
NodeMetadata node = nodes.get(id);
if (node == null)
throw new ResourceNotFoundException("node not found: " + id);
StubComputeServiceDependenciesModule.setState(node, NodeState.PENDING, 0);
StubComputeServiceDependenciesModule.setState(node, NodeState.RUNNING, 50);
setStateOnNode(NodeState.PENDING, node);
setStateOnNodeAfterDelay(NodeState.RUNNING, node, 50);
}
@Override
@ -185,8 +212,8 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
return;
if (node.getState() != NodeState.SUSPENDED)
throw new IllegalStateException("to resume a node, it must be in suspended state, not: " + node.getState());
StubComputeServiceDependenciesModule.setState(node, NodeState.PENDING, 0);
StubComputeServiceDependenciesModule.setState(node, NodeState.RUNNING, 50);
setStateOnNode(NodeState.PENDING, node);
setStateOnNodeAfterDelay(NodeState.RUNNING, node, 50);
}
@Override
@ -198,7 +225,7 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
return;
if (node.getState() != NodeState.RUNNING)
throw new IllegalStateException("to suspend a node, it must be in running state, not: " + node.getState());
StubComputeServiceDependenciesModule.setState(node, NodeState.PENDING, 0);
StubComputeServiceDependenciesModule.setState(node, NodeState.SUSPENDED, 50);
setStateOnNode(NodeState.PENDING, node);
setStateOnNodeAfterDelay(NodeState.SUSPENDED, node, 50);
}
}

View File

@ -20,8 +20,7 @@ package org.jclouds.compute.stub.config;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import javax.inject.Inject;
@ -30,15 +29,17 @@ import javax.inject.Singleton;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.internal.VolumeImpl;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.rest.annotations.Identity;
import com.google.common.base.Throwables;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@ -54,23 +55,38 @@ public class StubComputeServiceDependenciesModule extends AbstractModule {
}
protected static final ConcurrentMap<String, NodeMetadata> backing = new ConcurrentHashMap<String, NodeMetadata>();
// STUB STUFF STATIC SO MULTIPLE CONTEXTS CAN SEE IT
protected static final LoadingCache<String, ConcurrentMap<String, NodeMetadata>> backing = CacheBuilder.newBuilder()
.build(new CacheLoader<String, ConcurrentMap<String, NodeMetadata>>() {
@Override
public ConcurrentMap<String, NodeMetadata> load(String arg0) throws Exception {
return new ConcurrentHashMap<String, NodeMetadata>();
}
});
// implementation details below
@Provides
@Singleton
ConcurrentMap<String, NodeMetadata> provideNodes() {
return backing;
protected ConcurrentMap<String, NodeMetadata> provideNodesForIdentity(@Identity String identity)
throws ExecutionException {
return backing.get(identity);
}
// STUB STUFF STATIC SO MULTIPLE CONTEXTS CAN SEE IT
private static final AtomicInteger nodeIds = new AtomicInteger(0);
static final ExecutorService service = Executors.newCachedThreadPool();
protected static final LoadingCache<String, AtomicInteger> nodeIds = CacheBuilder.newBuilder().build(
new CacheLoader<String, AtomicInteger>() {
@Override
public AtomicInteger load(String arg0) throws Exception {
return new AtomicInteger(0);
}
});
@Provides
@Named("NODE_ID")
Integer provideNodeId() {
return nodeIds.incrementAndGet();
protected Integer provideNodeIdForIdentity(@Identity String identity) throws ExecutionException {
return nodeIds.get(identity).incrementAndGet();
}
@Singleton
@ -122,29 +138,6 @@ public class StubComputeServiceDependenciesModule extends AbstractModule {
}
protected static void nodeWithState(NodeMetadata node, NodeState state) {
backing.put(node.getId(), NodeMetadataBuilder.fromNodeMetadata(node).state(state).build());
}
public static void setState(final NodeMetadata node, final NodeState state, final long millis) {
if (millis == 0l)
nodeWithState(node, state);
else
service.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
Throwables.propagate(e);
}
nodeWithState(node, state);
}
});
}
static Hardware stub(String type, int cores, int ram, float disk) {
return new org.jclouds.compute.domain.HardwareBuilder().ids(type).name(type)
.processors(ImmutableList.of(new Processor(cores, 1.0))).ram(ram)

View File

@ -42,7 +42,7 @@ list, Alan Dipert and MeikelBrandmeyer."
(deftest os-families-test
(is (some #{"centos"} (map str (os-families)))))
(def compute-stub (compute-service "stub" "" "" :extensions [(ssh-test/ssh-test-client ssh-test/no-op-ssh-client)]))
(def compute-stub (compute-service "stub" "compute2.clj" "" :extensions [(ssh-test/ssh-test-client ssh-test/no-op-ssh-client)]))
(defn clean-stub-fixture
"This should allow basic tests to easily be run with another service."
@ -58,7 +58,7 @@ list, Alan Dipert and MeikelBrandmeyer."
(is (compute-service? compute-stub)))
(deftest as-compute-service-test
(is (compute-service? (compute-service "stub" "user" "password")))
(is (compute-service? (compute-service "stub" "compute2.clj" "")))
(is (compute-service? compute-stub))
(is (compute-service? (compute-service (compute-context compute-stub)))))
@ -119,7 +119,7 @@ list, Alan Dipert and MeikelBrandmeyer."
(run-script-on-node compute-stub "nonexistingnode" echo script-options)))))
(deftest build-template-test
(let [service (compute-service "stub" "user" "password")]
(let [service (compute-service "stub" "compute2.clj" "")]
(testing "nullary"
(is (>= (-> (build-template service {:fastest true})
bean :hardware bean :processors first bean :cores)

View File

@ -42,13 +42,13 @@ list, Alan Dipert and MeikelBrandmeyer."
(destroy-node (.getId node)))
(f))))
(use-fixtures :each (clean-stub-fixture "stub" "" ""))
(use-fixtures :each (clean-stub-fixture "stub" "compute.clj" ""))
(deftest compute-service?-test
(is (compute-service? *compute*)))
(deftest as-compute-service-test
(is (compute-service? (compute-service "stub" "user" "password")))
(is (compute-service? (compute-service "stub" "compute.clj" "")))
(is (compute-service? (as-compute-service *compute*)))
(is (compute-service? (as-compute-service (compute-context *compute*)))))
@ -90,7 +90,7 @@ list, Alan Dipert and MeikelBrandmeyer."
(is (terminated? (first (nodes-with-tag "deprecated")))))
(deftest build-template-test
(let [service (compute-service "stub" "user" "password")]
(let [service (compute-service "stub" "compute.clj" "")]
(testing "nullary"
(is (>= (-> (build-template service {:fastest true})
bean :hardware bean :processors first bean :cores)