mirror of https://github.com/apache/jclouds.git
Merge branch 'master' of https://github.com/jclouds/jclouds
This commit is contained in:
commit
6dc57aa98f
13
README.txt
13
README.txt
|
@ -16,7 +16,7 @@ check out our examples site! https://github.com/jclouds/jclouds-examples
|
||||||
our compute api supports: aws-ec2, gogrid, cloudservers-us, stub (in-memory), deltacloud,
|
our compute api supports: aws-ec2, gogrid, cloudservers-us, stub (in-memory), deltacloud,
|
||||||
cloudservers-uk, vcloud (generic), ec2 (generic), byon, nova,
|
cloudservers-uk, vcloud (generic), ec2 (generic), byon, nova,
|
||||||
trmk-ecloud, trmk-vcloudexpress, eucalyptus (generic),
|
trmk-ecloud, trmk-vcloudexpress, eucalyptus (generic),
|
||||||
cloudsigma-zrh, elasticstack(generic), bluelock-vcloud-vcenterprise,
|
cloudsigma-zrh, elasticstack(generic), go2cloud-jhb1,
|
||||||
bluelock-vcloud-zone01, stratogen-vcloud-mycloud, rimuhosting,
|
bluelock-vcloud-zone01, stratogen-vcloud-mycloud, rimuhosting,
|
||||||
slicehost, eucalyptus-partnercloud-ec2, elastichosts-lon-p (Peer 1),
|
slicehost, eucalyptus-partnercloud-ec2, elastichosts-lon-p (Peer 1),
|
||||||
elastichosts-sat-p (Peer 1), elastichosts-lon-b (BlueSquare),
|
elastichosts-sat-p (Peer 1), elastichosts-lon-b (BlueSquare),
|
||||||
|
@ -39,6 +39,8 @@ our loadbalancer api supports: cloudloadbalancers-us
|
||||||
* note * the pom dependency org.jclouds/jclouds-allloadbalancer gives you access to
|
* note * the pom dependency org.jclouds/jclouds-allloadbalancer gives you access to
|
||||||
to all of these providers
|
to all of these providers
|
||||||
|
|
||||||
|
we also have aws-cloudwatch support.
|
||||||
|
|
||||||
we also have support for: ibmdev, mezeo, nirvanix, boxdotnet, openstack nova, scality ring,
|
we also have support for: ibmdev, mezeo, nirvanix, boxdotnet, openstack nova, scality ring,
|
||||||
hosteurope-storage, tiscali-storage, scaleup-storage, googlestorage,
|
hosteurope-storage, tiscali-storage, scaleup-storage, googlestorage,
|
||||||
azurequeue, simpledb, cloudstack as well as a async-http-client
|
azurequeue, simpledb, cloudstack as well as a async-http-client
|
||||||
|
@ -115,10 +117,11 @@ Downloads:
|
||||||
* snapshot repo: https://oss.sonatype.org/content/repositories/snapshots
|
* snapshot repo: https://oss.sonatype.org/content/repositories/snapshots
|
||||||
|
|
||||||
Links:
|
Links:
|
||||||
* project page: http://code.google.com/p/jclouds/
|
* project page: http://jclouds.org/
|
||||||
* javadocs: http://jclouds.rimuhosting.com/apidocs/
|
* documentation: http://www.jclouds.org/documentation/index
|
||||||
* maven site: http://jclouds.googlecode.com/svn/maven-sites/1.1.1/jclouds-multi/index.html
|
* javadocs (1.1.0): http://jclouds.rimuhosting.com/apidocs/
|
||||||
* community: http://code.google.com/p/jclouds/wiki/AppsThatUseJClouds
|
* javadocs (1.0-SNAPSHOT): http://jclouds.rimuhosting.com/apidocs-SNAPSHOT/
|
||||||
|
* community: http://www.jclouds.org/documentation/reference/apps-that-use-jclouds
|
||||||
* user group: http://groups.google.com/group/jclouds
|
* user group: http://groups.google.com/group/jclouds
|
||||||
* dev group: http://groups.google.com/group/jclouds-dev
|
* dev group: http://groups.google.com/group/jclouds-dev
|
||||||
* twitter: http://twitter.com/jclouds
|
* twitter: http://twitter.com/jclouds
|
||||||
|
|
|
@ -30,6 +30,11 @@
|
||||||
<artifactId>jclouds-all</artifactId>
|
<artifactId>jclouds-all</artifactId>
|
||||||
<name>all</name>
|
<name>all</name>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jclouds.provider</groupId>
|
||||||
|
<artifactId>aws-cloudwatch</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>jclouds-allloadbalancer</artifactId>
|
<artifactId>jclouds-allloadbalancer</artifactId>
|
||||||
|
|
|
@ -105,11 +105,6 @@
|
||||||
<artifactId>trmk-ecloud</artifactId>
|
<artifactId>trmk-ecloud</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.jclouds.provider</groupId>
|
|
||||||
<artifactId>bluelock-vcloud-vcenterprise</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jclouds.provider</groupId>
|
<groupId>org.jclouds.provider</groupId>
|
||||||
<artifactId>bluelock-vcloud-zone01</artifactId>
|
<artifactId>bluelock-vcloud-zone01</artifactId>
|
||||||
|
@ -170,5 +165,10 @@
|
||||||
<artifactId>cloudsigma-zrh</artifactId>
|
<artifactId>cloudsigma-zrh</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jclouds.provider</groupId>
|
||||||
|
<artifactId>go2cloud-jhb1</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -25,9 +25,6 @@ import static org.jclouds.tools.ant.taskdefs.compute.ComputeTaskUtils.ipOrEmptyS
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import org.apache.tools.ant.BuildException;
|
import org.apache.tools.ant.BuildException;
|
||||||
import org.apache.tools.ant.Project;
|
import org.apache.tools.ant.Project;
|
||||||
|
@ -43,10 +40,12 @@ import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.compute.predicates.NodePredicates;
|
import org.jclouds.compute.predicates.NodePredicates;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.http.HttpUtils;
|
import org.jclouds.http.HttpUtils;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.util.CredentialUtils;
|
import org.jclouds.util.CredentialUtils;
|
||||||
|
|
||||||
import com.google.common.base.CaseFormat;
|
import com.google.common.base.CaseFormat;
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
|
@ -56,7 +55,7 @@ import com.google.inject.Provider;
|
||||||
*/
|
*/
|
||||||
public class ComputeTask extends Task {
|
public class ComputeTask extends Task {
|
||||||
|
|
||||||
private final Map<URI, ComputeServiceContext> computeMap;
|
private final Cache<URI, ComputeServiceContext> computeMap;
|
||||||
private String provider;
|
private String provider;
|
||||||
private String actions;
|
private String actions;
|
||||||
private NodeElement nodeElement;
|
private NodeElement nodeElement;
|
||||||
|
@ -72,7 +71,7 @@ public class ComputeTask extends Task {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public ComputeTask(@Nullable Map<URI, ComputeServiceContext> computeMap) {
|
public ComputeTask(@Nullable Cache<URI, ComputeServiceContext> computeMap) {
|
||||||
this.computeMap = computeMap != null ? computeMap : buildComputeMap(projectProvider);
|
this.computeMap = computeMap != null ? computeMap : buildComputeMap(projectProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +87,7 @@ public class ComputeTask extends Task {
|
||||||
* makes a connection to the compute service and invokes
|
* makes a connection to the compute service and invokes
|
||||||
*/
|
*/
|
||||||
public void execute() throws BuildException {
|
public void execute() throws BuildException {
|
||||||
ComputeServiceContext context = computeMap.get(HttpUtils.createUri(provider));
|
ComputeServiceContext context = computeMap.getUnchecked(HttpUtils.createUri(provider));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (String action : Splitter.on(',').split(actions)) {
|
for (String action : Splitter.on(',').split(actions)) {
|
||||||
|
|
|
@ -22,7 +22,6 @@ import static org.jclouds.rest.RestContextFactory.getPropertiesFromResource;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -43,11 +42,12 @@ import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||||
import org.jclouds.tools.ant.logging.config.AntLoggingModule;
|
import org.jclouds.tools.ant.logging.config.AntLoggingModule;
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.MapMaker;
|
|
||||||
import com.google.common.io.Files;
|
import com.google.common.io.Files;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
@ -67,12 +67,12 @@ public class ComputeTaskUtils {
|
||||||
* allows access to the ant project to retrieve default properties needed for compute
|
* allows access to the ant project to retrieve default properties needed for compute
|
||||||
* providers.
|
* providers.
|
||||||
*/
|
*/
|
||||||
static Map<URI, ComputeServiceContext> buildComputeMap(final Provider<Project> projectProvider) {
|
static Cache<URI, ComputeServiceContext> buildComputeMap(final Provider<Project> projectProvider) {
|
||||||
return new MapMaker().makeComputingMap(new Function<URI, ComputeServiceContext>() {
|
return CacheBuilder.newBuilder().build(new CacheLoader<URI, ComputeServiceContext>() {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public ComputeServiceContext apply(URI from) {
|
public ComputeServiceContext load(URI from) {
|
||||||
Properties props = getPropertiesFromResource("/rest.properties");
|
Properties props = getPropertiesFromResource("/rest.properties");
|
||||||
props.putAll(projectProvider.get().getProperties());
|
props.putAll(projectProvider.get().getProperties());
|
||||||
// adding the properties to the factory will allow us to pass
|
// adding the properties to the factory will allow us to pass
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.atmos.domain;
|
package org.jclouds.atmos.domain;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.atmos.domain.internal.AtmosObjectImpl.AtmosObjectFactory;
|
import org.jclouds.atmos.domain.internal.AtmosObjectImpl.AtmosObjectFactory;
|
||||||
import org.jclouds.io.PayloadEnclosing;
|
import org.jclouds.io.PayloadEnclosing;
|
||||||
|
|
|
@ -20,7 +20,7 @@ package org.jclouds.atmos.domain;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.atmos.domain.internal.BoundedLinkedHashSet;
|
import org.jclouds.atmos.domain.internal.BoundedLinkedHashSet;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ package org.jclouds.atmos.domain;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metadata of a Atmos Online object
|
* Metadata of a Atmos Online object
|
||||||
|
|
|
@ -22,7 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.atmos.domain.BoundedSet;
|
import org.jclouds.atmos.domain.BoundedSet;
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ import static org.jclouds.util.Throwables2.propagateOrNull;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.blobstore.KeyAlreadyExistsException;
|
import org.jclouds.blobstore.KeyAlreadyExistsException;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
|
|
@ -22,9 +22,13 @@ import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.byon.config.BYONComputeServiceContextModule;
|
import org.jclouds.byon.config.BYONComputeServiceContextModule;
|
||||||
|
import org.jclouds.byon.config.ConfiguresNodeStore;
|
||||||
|
import org.jclouds.byon.config.YamlNodeStoreModule;
|
||||||
import org.jclouds.compute.StandaloneComputeServiceContextBuilder;
|
import org.jclouds.compute.StandaloneComputeServiceContextBuilder;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,6 +45,21 @@ public class BYONComputeServiceContextBuilder extends StandaloneComputeServiceCo
|
||||||
@Override
|
@Override
|
||||||
protected void addContextModule(List<Module> modules) {
|
protected void addContextModule(List<Module> modules) {
|
||||||
modules.add(new BYONComputeServiceContextModule());
|
modules.add(new BYONComputeServiceContextModule());
|
||||||
|
addNodeStoreModuleIfNotPresent(modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void addNodeStoreModuleIfNotPresent(List<Module> modules) {
|
||||||
|
if (!Iterables.any(modules, new Predicate<Module>() {
|
||||||
|
public boolean apply(Module input) {
|
||||||
|
return input.getClass().isAnnotationPresent(ConfiguresNodeStore.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
})) {
|
||||||
|
addNodeStoreModule(modules);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addNodeStoreModule(List<Module> modules) {
|
||||||
|
modules.add(new YamlNodeStoreModule());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,14 +20,11 @@ package org.jclouds.byon.config;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.byon.Node;
|
import org.jclouds.byon.Node;
|
||||||
import org.jclouds.byon.functions.NodesFromYamlStream;
|
|
||||||
import org.jclouds.byon.internal.BYONComputeServiceAdapter;
|
import org.jclouds.byon.internal.BYONComputeServiceAdapter;
|
||||||
import org.jclouds.byon.suppliers.NodesParsedFromSupplier;
|
|
||||||
import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
|
import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
|
||||||
import org.jclouds.compute.config.JCloudsNativeComputeServiceAdapterContextModule;
|
import org.jclouds.compute.config.JCloudsNativeComputeServiceAdapterContextModule;
|
||||||
import org.jclouds.concurrent.SingleThreaded;
|
import org.jclouds.concurrent.SingleThreaded;
|
||||||
|
@ -37,6 +34,7 @@ import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
@ -55,7 +53,7 @@ public class BYONComputeServiceContextModule extends
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
Supplier provideApi(Supplier<Map<String, Node>> in) {
|
Supplier provideApi(Supplier<Cache<String, Node>> in) {
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,15 +62,12 @@ public class BYONComputeServiceContextModule extends
|
||||||
super.configure();
|
super.configure();
|
||||||
bind(new TypeLiteral<Supplier<Location>>() {
|
bind(new TypeLiteral<Supplier<Location>>() {
|
||||||
}).to(OnlyLocationOrFirstZone.class);
|
}).to(OnlyLocationOrFirstZone.class);
|
||||||
bind(new TypeLiteral<Supplier<Map<String, Node>>>() {
|
bind(new TypeLiteral<Function<URI, InputStream>>() {
|
||||||
}).to(NodesParsedFromSupplier.class);
|
}).to(SupplyFromProviderURIOrNodesProperty.class);
|
||||||
bind(new TypeLiteral<Supplier<InputStream>>() {
|
bind(new TypeLiteral<Supplier<InputStream>>() {
|
||||||
}).annotatedWith(Provider.class).to(SupplyFromProviderURIOrNodesProperty.class);
|
}).annotatedWith(Provider.class).to(SupplyFromProviderURIOrNodesProperty.class);
|
||||||
bind(new TypeLiteral<Function<URI, InputStream>>() {
|
bind(new TypeLiteral<Function<URI, InputStream>>() {
|
||||||
}).to(SupplyFromProviderURIOrNodesProperty.class);
|
}).to(SupplyFromProviderURIOrNodesProperty.class);
|
||||||
// TODO make this somehow overridable via user request
|
|
||||||
bind(new TypeLiteral<Function<InputStream, Map<String, Node>>>() {
|
|
||||||
}).to(NodesFromYamlStream.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
* 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.byon.config;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jclouds.byon.Node;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
import com.google.common.base.Functions;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@ConfiguresNodeStore
|
||||||
|
@Beta
|
||||||
|
public class CacheNodeStoreModule extends AbstractModule {
|
||||||
|
private final Cache<String, Node> backing;
|
||||||
|
|
||||||
|
public CacheNodeStoreModule(Cache<String, Node> backing) {
|
||||||
|
this.backing = checkNotNull(backing, "backing");
|
||||||
|
}
|
||||||
|
|
||||||
|
public CacheNodeStoreModule(Map<String, Node> backing) {
|
||||||
|
this(CacheBuilder.newBuilder().<String, Node>build(CacheLoader.from(Functions.forMap(backing))));
|
||||||
|
for (String node : backing.keySet())
|
||||||
|
this.backing.getUnchecked(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bind(new TypeLiteral<Cache<String, Node>>() {
|
||||||
|
}).toInstance(backing);
|
||||||
|
bind(new TypeLiteral<Supplier<Cache<String, Node>>>() {
|
||||||
|
}).toInstance(Suppliers.<Cache<String, Node>> ofInstance(backing));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -27,7 +27,7 @@ import java.lang.annotation.Target;
|
||||||
import com.google.common.annotations.Beta;
|
import com.google.common.annotations.Beta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* designates the module configures a {@code Map<String, Node>}
|
* designates the module configures a {@code Cache<String, Node>}
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
|
|
|
@ -22,19 +22,30 @@ import java.io.InputStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.byon.Node;
|
import org.jclouds.byon.Node;
|
||||||
import org.jclouds.byon.domain.YamlNode;
|
import org.jclouds.byon.domain.YamlNode;
|
||||||
|
import org.jclouds.byon.functions.NodesFromYamlStream;
|
||||||
|
import org.jclouds.byon.suppliers.NodesParsedFromSupplier;
|
||||||
import org.jclouds.collect.TransformingMap;
|
import org.jclouds.collect.TransformingMap;
|
||||||
import org.jclouds.io.CopyInputStreamInputSupplierMap;
|
import org.jclouds.io.CopyInputStreamInputSupplierMap;
|
||||||
|
import org.jclouds.io.CopyInputStreamIntoSupplier;
|
||||||
|
|
||||||
import com.google.common.annotations.Beta;
|
import com.google.common.annotations.Beta;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Functions;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.io.InputSupplier;
|
import com.google.common.io.InputSupplier;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
import com.google.inject.name.Names;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -56,6 +67,10 @@ public class YamlNodeStoreModule extends AbstractModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
|
bind(new TypeLiteral<Supplier<Cache<String, Node>>>() {
|
||||||
|
}).to(NodesParsedFromSupplier.class);
|
||||||
|
bind(new TypeLiteral<Function<InputStream, Cache<String, Node>>>() {
|
||||||
|
}).to(NodesFromYamlStream.class);
|
||||||
bind(new TypeLiteral<Function<YamlNode, InputStream>>() {
|
bind(new TypeLiteral<Function<YamlNode, InputStream>>() {
|
||||||
}).toInstance(org.jclouds.byon.domain.YamlNode.yamlNodeToInputStream);
|
}).toInstance(org.jclouds.byon.domain.YamlNode.yamlNodeToInputStream);
|
||||||
bind(new TypeLiteral<Function<InputStream, YamlNode>>() {
|
bind(new TypeLiteral<Function<InputStream, YamlNode>>() {
|
||||||
|
@ -66,26 +81,36 @@ public class YamlNodeStoreModule extends AbstractModule {
|
||||||
}).toInstance(org.jclouds.byon.domain.YamlNode.toNode);
|
}).toInstance(org.jclouds.byon.domain.YamlNode.toNode);
|
||||||
if (backing != null) {
|
if (backing != null) {
|
||||||
bind(new TypeLiteral<Map<String, InputStream>>() {
|
bind(new TypeLiteral<Map<String, InputStream>>() {
|
||||||
}).toInstance(backing);
|
}).annotatedWith(Names.named("yaml")).toInstance(backing);
|
||||||
} else {
|
} else {
|
||||||
bind(new TypeLiteral<Map<String, InputSupplier<InputStream>>>() {
|
bind(new TypeLiteral<Map<String, InputSupplier<InputStream>>>() {
|
||||||
}).toInstance(BACKING);
|
}).annotatedWith(Names.named("yaml")).toInstance(BACKING);
|
||||||
bind(new TypeLiteral<Map<String, InputStream>>() {
|
bind(new TypeLiteral<Map<String, InputStream>>() {
|
||||||
}).to(new TypeLiteral<CopyInputStreamInputSupplierMap>() {
|
}).annotatedWith(Names.named("yaml")).to(new TypeLiteral<YAMLCopyInputStreamInputSupplierMap>() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class YAMLCopyInputStreamInputSupplierMap extends CopyInputStreamInputSupplierMap {
|
||||||
|
@Inject
|
||||||
|
public YAMLCopyInputStreamInputSupplierMap(@Named("yaml") Map<String, InputSupplier<InputStream>> toMap,
|
||||||
|
CopyInputStreamIntoSupplier putFunction) {
|
||||||
|
super(toMap, putFunction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Map<String, Node> provideNodeStore(Map<String, YamlNode> backing,
|
protected Cache<String, Node> provideNodeStore(Map<String, YamlNode> backing, Function<Node, YamlNode> yamlSerializer,
|
||||||
Function<Node, YamlNode> yamlSerializer, Function<YamlNode, Node> yamlDeserializer) {
|
Function<YamlNode, Node> yamlDeserializer) {
|
||||||
return new TransformingMap<String, YamlNode, Node>(backing, yamlDeserializer, yamlSerializer);
|
return CacheBuilder.newBuilder().build(CacheLoader.from(Functions.forMap(new TransformingMap<String, YamlNode, Node>(backing, yamlDeserializer, yamlSerializer))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Map<String, YamlNode> provideYamlStore(Map<String, InputStream> backing,
|
protected Map<String, YamlNode> provideYamlStore(@Named("yaml") Map<String, InputStream> backing,
|
||||||
Function<YamlNode, InputStream> yamlSerializer, Function<InputStream, YamlNode> yamlDeserializer) {
|
Function<YamlNode, InputStream> yamlSerializer, Function<InputStream, YamlNode> yamlDeserializer) {
|
||||||
return new TransformingMap<String, InputStream, YamlNode>(backing, yamlDeserializer, yamlSerializer);
|
return new TransformingMap<String, InputStream, YamlNode>(backing, yamlDeserializer, yamlSerializer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,7 @@ public class NodeToNodeMetadata implements Function<Node, NodeMetadata> {
|
||||||
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
||||||
builder.ids(from.getId());
|
builder.ids(from.getId());
|
||||||
builder.name(from.getName());
|
builder.name(from.getName());
|
||||||
|
builder.loginPort(from.getLoginPort());
|
||||||
builder.hostname(from.getHostname());
|
builder.hostname(from.getHostname());
|
||||||
builder.location(findLocationWithId(from.getLocationId()));
|
builder.location(findLocationWithId(from.getLocationId()));
|
||||||
builder.group(from.getGroup());
|
builder.group(from.getGroup());
|
||||||
|
|
|
@ -34,6 +34,10 @@ import org.yaml.snakeyaml.Yaml;
|
||||||
import org.yaml.snakeyaml.constructor.Constructor;
|
import org.yaml.snakeyaml.constructor.Constructor;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Functions;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
@ -65,7 +69,7 @@ import com.google.common.collect.Maps;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class NodesFromYamlStream implements Function<InputStream, Map<String, Node>> {
|
public class NodesFromYamlStream implements Function<InputStream, Cache<String, Node>> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type-safe config class for YAML
|
* Type-safe config class for YAML
|
||||||
|
@ -76,7 +80,7 @@ public class NodesFromYamlStream implements Function<InputStream, Map<String, No
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Node> apply(InputStream source) {
|
public Cache<String, Node> apply(InputStream source) {
|
||||||
|
|
||||||
Constructor constructor = new Constructor(Config.class);
|
Constructor constructor = new Constructor(Config.class);
|
||||||
|
|
||||||
|
@ -87,17 +91,23 @@ public class NodesFromYamlStream implements Function<InputStream, Map<String, No
|
||||||
TypeDescription configDesc = new TypeDescription(Config.class);
|
TypeDescription configDesc = new TypeDescription(Config.class);
|
||||||
configDesc.putListPropertyType("nodes", YamlNode.class);
|
configDesc.putListPropertyType("nodes", YamlNode.class);
|
||||||
constructor.addTypeDescription(configDesc);
|
constructor.addTypeDescription(configDesc);
|
||||||
// note that snakeyaml also throws nosuchmethod error when you use the non-deprecated
|
// note that snakeyaml also throws nosuchmethod error when you use the
|
||||||
|
// non-deprecated
|
||||||
// constructor
|
// constructor
|
||||||
Yaml yaml = new Yaml(new Loader(constructor));
|
Yaml yaml = new Yaml(new Loader(constructor));
|
||||||
Config config = (Config) yaml.load(source);
|
Config config = (Config) yaml.load(source);
|
||||||
checkState(config != null, "missing config: class");
|
checkState(config != null, "missing config: class");
|
||||||
checkState(config.nodes != null, "missing nodes: collection");
|
checkState(config.nodes != null, "missing nodes: collection");
|
||||||
|
|
||||||
return Maps.uniqueIndex(Iterables.transform(config.nodes, YamlNode.toNode), new Function<Node, String>() {
|
Map<String, Node> backingMap = Maps.uniqueIndex(Iterables.transform(config.nodes, YamlNode.toNode),
|
||||||
|
new Function<Node, String>() {
|
||||||
public String apply(Node node) {
|
public String apply(Node node) {
|
||||||
return node.getId();
|
return node.getId();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Cache<String, Node> cache = CacheBuilder.newBuilder().build(CacheLoader.from(Functions.forMap(backingMap)));
|
||||||
|
for (String node : backingMap.keySet())
|
||||||
|
cache.getUnchecked(node);
|
||||||
|
return cache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,9 +42,11 @@ import org.jclouds.location.suppliers.JustProvider;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.collect.ImmutableSet.Builder;
|
import com.google.common.collect.ImmutableSet.Builder;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -52,12 +54,12 @@ import com.google.common.collect.ImmutableSet.Builder;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAdapter {
|
public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAdapter {
|
||||||
private final Supplier<Map<String, Node>> nodes;
|
private final Supplier<Cache<String, Node>> nodes;
|
||||||
private final NodeToNodeMetadata converter;
|
private final NodeToNodeMetadata converter;
|
||||||
private final JustProvider locationSupplier;
|
private final JustProvider locationSupplier;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public BYONComputeServiceAdapter(Supplier<Map<String, Node>> nodes, NodeToNodeMetadata converter,
|
public BYONComputeServiceAdapter(Supplier<Cache<String, Node>> nodes, NodeToNodeMetadata converter,
|
||||||
JustProvider locationSupplier) {
|
JustProvider locationSupplier) {
|
||||||
this.nodes = checkNotNull(nodes, "nodes");
|
this.nodes = checkNotNull(nodes, "nodes");
|
||||||
this.converter = checkNotNull(converter, "converter");
|
this.converter = checkNotNull(converter, "converter");
|
||||||
|
@ -82,14 +84,14 @@ public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<NodeMetadata> listNodes() {
|
public Iterable<NodeMetadata> listNodes() {
|
||||||
return Iterables.transform(nodes.get().values(), converter);
|
return Iterables.transform(nodes.get().asMap().values(), converter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Location> listLocations() {
|
public Iterable<Location> listLocations() {
|
||||||
Builder<Location> locations = ImmutableSet.builder();
|
Builder<Location> locations = ImmutableSet.builder();
|
||||||
Location provider = Iterables.getOnlyElement(locationSupplier.get());
|
Location provider = Iterables.getOnlyElement(locationSupplier.get());
|
||||||
Set<String> zones = ImmutableSet.copyOf(Iterables.filter(Iterables.transform(nodes.get().values(),
|
Set<String> zones = ImmutableSet.copyOf(Iterables.filter(Iterables.transform(nodes.get().asMap().values(),
|
||||||
new Function<Node, String>() {
|
new Function<Node, String>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -109,7 +111,13 @@ public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadata getNode(String id) {
|
public NodeMetadata getNode(String id) {
|
||||||
Node node = nodes.get().get(id);
|
|
||||||
|
Node node = null;
|
||||||
|
try {
|
||||||
|
node = nodes.get().getUnchecked(id);
|
||||||
|
} catch (UncheckedExecutionException e) {
|
||||||
|
|
||||||
|
}
|
||||||
return node != null ? converter.apply(node) : null;
|
return node != null ? converter.apply(node) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
@ -34,28 +33,29 @@ import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class NodesParsedFromSupplier implements Supplier<Map<String, Node>> {
|
public class NodesParsedFromSupplier implements Supplier<Cache<String, Node>> {
|
||||||
@Resource
|
@Resource
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
private final Supplier<InputStream> supplier;
|
private final Supplier<InputStream> supplier;
|
||||||
private final Function<InputStream, Map<String, Node>> parser;
|
private final Function<InputStream, Cache<String, Node>> parser;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
NodesParsedFromSupplier(@Provider Supplier<InputStream> supplier, Function<InputStream, Map<String, Node>> parser) {
|
NodesParsedFromSupplier(@Provider Supplier<InputStream> supplier, Function<InputStream, Cache<String, Node>> parser) {
|
||||||
this.supplier = checkNotNull(supplier, "supplier");
|
this.supplier = checkNotNull(supplier, "supplier");
|
||||||
this.parser = checkNotNull(parser, "parser");
|
this.parser = checkNotNull(parser, "parser");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Node> get() {
|
public Cache<String, Node> get() {
|
||||||
Map<String, Node> nodes = parser.apply(supplier.get());
|
Cache<String, Node> nodes = parser.apply(supplier.get());
|
||||||
checkState(nodes != null && nodes.size() > 0, "no nodes parsed from supplier: %s", supplier);
|
checkState(nodes != null && nodes.size() > 0, "no nodes parsed from supplier: %s", supplier);
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,17 +24,17 @@ import static org.jclouds.byon.functions.NodeToNodeMetadataTest.zoneCalled;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.byon.config.CacheNodeStoreModule;
|
||||||
import org.jclouds.byon.functions.NodesFromYamlTest;
|
import org.jclouds.byon.functions.NodesFromYamlTest;
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
@ -43,41 +43,48 @@ import com.google.inject.Module;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live")
|
@Test(singleThreaded = true, testName = "BYONComputeServiceTest")
|
||||||
public class BYONComputeServiceTest {
|
public class BYONComputeServiceTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNodesParseNodeMap() throws Exception {
|
||||||
|
assertNodesParse(
|
||||||
|
"foo",
|
||||||
|
ImmutableSet.<Module> of(new CacheNodeStoreModule(ImmutableMap.<String, Node> of(
|
||||||
|
NodesFromYamlTest.TEST1.getId(), NodesFromYamlTest.TEST1))));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNodesParseWithFileUrl() throws Exception {
|
public void testNodesParseWithFileUrl() throws Exception {
|
||||||
assertNodesParse("file://" + getClass().getResource("/test1.yaml").getPath());
|
assertNodesParse("file://" + getClass().getResource("/test1.yaml").getPath(), ImmutableSet.<Module> of());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNodesParseWithClasspathUrl() throws Exception {
|
public void testNodesParseWithClasspathUrl() throws Exception {
|
||||||
assertNodesParse("classpath:///test1.yaml");
|
assertNodesParse("classpath:///test1.yaml", ImmutableSet.<Module> of());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertNodesParse(String endpoint) {
|
private void assertNodesParse(String endpoint, Iterable<Module> modules) {
|
||||||
ComputeServiceContext context = null;
|
ComputeServiceContext context = null;
|
||||||
try {
|
try {
|
||||||
Location providerLocation = expectedProviderLocationFromResource(endpoint);
|
Location providerLocation = expectedProviderLocationFromResource(endpoint);
|
||||||
|
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
props.setProperty("byon.endpoint", endpoint);
|
props.setProperty("byon.endpoint", endpoint);
|
||||||
context = new ComputeServiceContextFactory().createContext("byon", "foo", "bar", ImmutableSet
|
context = new ComputeServiceContextFactory().createContext("byon", "foo", "bar", modules, props);
|
||||||
.<Module> of(new SshjSshClientModule()), props);
|
|
||||||
|
|
||||||
assertEquals(context.getProviderSpecificContext().getEndpoint(), URI.create(endpoint));
|
assertEquals(context.getProviderSpecificContext().getEndpoint(), URI.create(endpoint));
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Supplier<Map<String, Node>> supplier = (Supplier<Map<String, Node>>) context.getProviderSpecificContext()
|
Supplier<Cache<String, Node>> supplier = (Supplier<Cache<String, Node>>) context.getProviderSpecificContext()
|
||||||
.getApi();
|
.getApi();
|
||||||
|
|
||||||
assertEquals(supplier.get().size(), context.getComputeService().listNodes().size());
|
assertEquals(supplier.get().size(), context.getComputeService().listNodes().size());
|
||||||
assertEquals(supplier.get(), ImmutableMap.<String, Node> of(NodesFromYamlTest.TEST1.getId(),
|
assertEquals(supplier.get().asMap(),
|
||||||
NodesFromYamlTest.TEST1));
|
ImmutableMap.<String, Node> of(NodesFromYamlTest.TEST1.getId(), NodesFromYamlTest.TEST1));
|
||||||
|
|
||||||
assertEquals(context.getComputeService().listNodes(), ImmutableSet
|
assertEquals(context.getComputeService().listNodes(),
|
||||||
.of(expectedNodeMetadataFromResource(endpoint)));
|
ImmutableSet.of(expectedNodeMetadataFromResource(endpoint)));
|
||||||
assertEquals(context.getComputeService().listAssignableLocations(), ImmutableSet.of(providerLocation));
|
assertEquals(context.getComputeService().listAssignableLocations(), ImmutableSet.of(providerLocation));
|
||||||
} finally {
|
} finally {
|
||||||
if (context != null)
|
if (context != null)
|
||||||
|
@ -91,25 +98,26 @@ public class BYONComputeServiceTest {
|
||||||
String endpoint = "file://" + getClass().getResource("/test_location.yaml").getPath();
|
String endpoint = "file://" + getClass().getResource("/test_location.yaml").getPath();
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
props.setProperty("byon.endpoint", endpoint);
|
props.setProperty("byon.endpoint", endpoint);
|
||||||
context = new ComputeServiceContextFactory().createContext("byon", "foo", "bar", ImmutableSet
|
context = new ComputeServiceContextFactory().createContext("byon", "foo", "bar",
|
||||||
.<Module> of(new SshjSshClientModule()), props);
|
ImmutableSet.<Module> of(), props);
|
||||||
|
|
||||||
assertEquals(context.getProviderSpecificContext().getEndpoint(), URI.create(endpoint));
|
assertEquals(context.getProviderSpecificContext().getEndpoint(), URI.create(endpoint));
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Supplier<Map<String, Node>> supplier = (Supplier<Map<String, Node>>) context.getProviderSpecificContext()
|
Supplier<Cache<String, Node>> supplier = (Supplier<Cache<String, Node>>) context.getProviderSpecificContext()
|
||||||
.getApi();
|
.getApi();
|
||||||
|
|
||||||
assertEquals(supplier.get().size(), context.getComputeService().listNodes().size());
|
assertEquals(supplier.get().size(), context.getComputeService().listNodes().size());
|
||||||
assertEquals(supplier.get(), ImmutableMap.<String, Node> of(NodesFromYamlTest.TEST2.getId(),
|
assertEquals(supplier.get().asMap(), ImmutableMap.<String, Node> of(NodesFromYamlTest.TEST2.getId(),
|
||||||
NodesFromYamlTest.TEST2, NodesFromYamlTest.TEST3.getId(), NodesFromYamlTest.TEST3));
|
NodesFromYamlTest.TEST2, NodesFromYamlTest.TEST3.getId(), NodesFromYamlTest.TEST3));
|
||||||
Location providerLocation = expectedProviderLocationFromResource(endpoint);
|
Location providerLocation = expectedProviderLocationFromResource(endpoint);
|
||||||
|
|
||||||
Location virginia = zoneCalled("virginia", providerLocation);
|
Location virginia = zoneCalled("virginia", providerLocation);
|
||||||
Location maryland = zoneCalled("maryland", providerLocation);
|
Location maryland = zoneCalled("maryland", providerLocation);
|
||||||
|
|
||||||
assertEquals(context.getComputeService().listNodes(), ImmutableSet.of(expectedNodeMetadataFromResource(1,
|
assertEquals(context.getComputeService().listNodes(), ImmutableSet.of(
|
||||||
endpoint, virginia), expectedNodeMetadataFromResource(2, endpoint, maryland)));
|
expectedNodeMetadataFromResource(1, endpoint, virginia),
|
||||||
|
expectedNodeMetadataFromResource(2, endpoint, maryland, 2022)));
|
||||||
|
|
||||||
assertEquals(context.getComputeService().listAssignableLocations(), ImmutableSet.of(virginia, maryland));
|
assertEquals(context.getComputeService().listAssignableLocations(), ImmutableSet.of(virginia, maryland));
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
/**
|
||||||
|
* 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.byon.config;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jclouds.byon.Node;
|
||||||
|
import org.jclouds.location.Provider;
|
||||||
|
import org.testng.annotations.DataProvider;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Functions;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Key;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", singleThreaded = true, testName = "CacheNodeStoreModuleTest")
|
||||||
|
public class CacheNodeStoreModuleTest {
|
||||||
|
|
||||||
|
@DataProvider(name = "names")
|
||||||
|
public Object[][] createData() {
|
||||||
|
return new Object[][] { { "instance1", "bear" }, { "instance2", "apple" }, { "instance2", "francis" },
|
||||||
|
{ "instance4", "robot" } };
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testProvidedMapWithValue() throws IOException {
|
||||||
|
Map<String, Node> map = Maps.newConcurrentMap();
|
||||||
|
|
||||||
|
map.put("test", Node.builder().id("instance1").name("instancename").build());
|
||||||
|
checkConsistent(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename");
|
||||||
|
checkConsistent(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename");
|
||||||
|
remove(map, getStore(createInjectorWithProvidedMap(map)), "test");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testProvidedConsistentAcrossRepeatedWrites() throws IOException {
|
||||||
|
Map<String, Node> map = Maps.newConcurrentMap();
|
||||||
|
|
||||||
|
Injector injector = createInjectorWithProvidedMap(map);
|
||||||
|
assertEquals(injector.getInstance(Key.get(new TypeLiteral<Cache<String, Node>>() {
|
||||||
|
})).asMap(), map);
|
||||||
|
Cache<String, Node> store = getStore(injector);
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
check(map, store, "test" + i, "instance1" + i, "instancename" + i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testProvidedConsistentAcrossMultipleInjectors() throws IOException {
|
||||||
|
Map<String, Node> map = Maps.newConcurrentMap();
|
||||||
|
|
||||||
|
put(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename");
|
||||||
|
checkConsistent(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename");
|
||||||
|
checkConsistent(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename");
|
||||||
|
remove(map, getStore(createInjectorWithProvidedMap(map)), "test");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testProvidedCacheConsistentAcrossMultipleInjectors() throws IOException {
|
||||||
|
Map<String, Node> map = Maps.newConcurrentMap();
|
||||||
|
|
||||||
|
Cache<String, Node> cache = CacheBuilder.newBuilder().build(CacheLoader.from(Functions.forMap(map)));
|
||||||
|
|
||||||
|
put(map, getStore(createInjectorWithProvidedCache(cache)), "test", "instance1", "instancename");
|
||||||
|
checkConsistent(map, getStore(createInjectorWithProvidedCache(cache)), "test", "instance1", "instancename");
|
||||||
|
checkConsistent(map, getStore(createInjectorWithProvidedCache(cache)), "test", "instance1", "instancename");
|
||||||
|
remove(map, getStore(createInjectorWithProvidedCache(cache)), "test");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Cache<String, Node> getStore(Injector injector) {
|
||||||
|
return injector.getInstance(Key.get(new TypeLiteral<Cache<String, Node>>() {
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Injector createInjectorWithProvidedMap(Map<String, Node> map) {
|
||||||
|
return Guice.createInjector(new CacheNodeStoreModule(map), new AbstractModule() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure() {
|
||||||
|
bind(new TypeLiteral<Supplier<InputStream>>() {
|
||||||
|
}).annotatedWith(Provider.class).toInstance(Suppliers.<InputStream> ofInstance(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Injector createInjectorWithProvidedCache(Cache<String, Node> cache) {
|
||||||
|
return Guice.createInjector(new CacheNodeStoreModule(cache), new AbstractModule() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure() {
|
||||||
|
bind(new TypeLiteral<Supplier<InputStream>>() {
|
||||||
|
}).annotatedWith(Provider.class).toInstance(Suppliers.<InputStream> ofInstance(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void check(Map<String, Node> map, Cache<String, Node> store, String key, String id, String name)
|
||||||
|
throws IOException {
|
||||||
|
put(map, store, key, id, name);
|
||||||
|
checkConsistent(map, store, key, id, name);
|
||||||
|
remove(map, store, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void remove(Map<String, Node> map, Cache<String, Node> store, String key) {
|
||||||
|
store.invalidate(key);
|
||||||
|
assertEquals(store.size(), 0);
|
||||||
|
map.remove(key);
|
||||||
|
assertEquals(map.size(), 0);
|
||||||
|
try {
|
||||||
|
assertEquals(store.getUnchecked(key), null);
|
||||||
|
assert false : "should not work as null is invalid";
|
||||||
|
} catch (UncheckedExecutionException e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
assertEquals(map.get(key), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkConsistent(Map<String, Node> map, Cache<String, Node> store, String key, String id, String name)
|
||||||
|
throws IOException {
|
||||||
|
assertEquals(map.size(), 1);
|
||||||
|
if (store.size() == 0)
|
||||||
|
store.getUnchecked(key);
|
||||||
|
assertEquals(store.size(), 1);
|
||||||
|
// checkRepeatedRead
|
||||||
|
assertEquals(store.getUnchecked(key), Node.builder().id(id).name(name).build());
|
||||||
|
assertEquals(store.getUnchecked(key), Node.builder().id(id).name(name).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void put(Map<String, Node> map, Cache<String, Node> store, String key, String id, String name) {
|
||||||
|
assertEquals(store.size(), 0);
|
||||||
|
assertEquals(map.size(), 0);
|
||||||
|
map.put(key, Node.builder().id(id).name(name).build());
|
||||||
|
store.getUnchecked(key);
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,16 +28,23 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.jclouds.byon.Node;
|
import org.jclouds.byon.Node;
|
||||||
import org.jclouds.io.CopyInputStreamInputSupplierMap;
|
import org.jclouds.io.CopyInputStreamInputSupplierMap;
|
||||||
|
import org.jclouds.location.Provider;
|
||||||
import org.jclouds.util.Strings2;
|
import org.jclouds.util.Strings2;
|
||||||
import org.testng.annotations.DataProvider;
|
import org.testng.annotations.DataProvider;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.io.InputSupplier;
|
import com.google.common.io.InputSupplier;
|
||||||
|
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Key;
|
import com.google.inject.Key;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
import com.google.inject.name.Names;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -45,7 +52,7 @@ import com.google.inject.TypeLiteral;
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", singleThreaded = true)
|
@Test(groups = "unit", singleThreaded = true)
|
||||||
public class YamlNodeStoreModuleTest {
|
public class YamlNodeStoreModuleTest {
|
||||||
Yaml json = createInjector().getInstance(Yaml.class);
|
Yaml yaml = createInjector().getInstance(Yaml.class);
|
||||||
|
|
||||||
@DataProvider(name = "names")
|
@DataProvider(name = "names")
|
||||||
public Object[][] createData() {
|
public Object[][] createData() {
|
||||||
|
@ -77,8 +84,8 @@ public class YamlNodeStoreModuleTest {
|
||||||
|
|
||||||
Injector injector = createInjectorWithProvidedMap(map);
|
Injector injector = createInjectorWithProvidedMap(map);
|
||||||
assertEquals(injector.getInstance(Key.get(new TypeLiteral<Map<String, InputStream>>() {
|
assertEquals(injector.getInstance(Key.get(new TypeLiteral<Map<String, InputStream>>() {
|
||||||
})), map);
|
}, Names.named("yaml"))), map);
|
||||||
Map<String, Node> store = getStore(injector);
|
Cache<String, Node> store = getStore(injector);
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
check(map, store, "test" + i, "instance1" + i, "instancename" + i);
|
check(map, store, "test" + i, "instance1" + i, "instancename" + i);
|
||||||
|
@ -100,52 +107,77 @@ public class YamlNodeStoreModuleTest {
|
||||||
Map<String, InputStream> map = getMap(createInjector());
|
Map<String, InputStream> map = getMap(createInjector());
|
||||||
|
|
||||||
put(map, getStore(createInjector()), "test", "instance1", "instancename");
|
put(map, getStore(createInjector()), "test", "instance1", "instancename");
|
||||||
|
|
||||||
checkConsistent(map, getStore(createInjector()), "test", "instance1", "instancename");
|
checkConsistent(map, getStore(createInjector()), "test", "instance1", "instancename");
|
||||||
checkConsistent(map, getStore(createInjector()), "test", "instance1", "instancename");
|
checkConsistent(map, getStore(createInjector()), "test", "instance1", "instancename");
|
||||||
remove(map, getStore(createInjector()), "test");
|
remove(map, getStore(createInjector()), "test");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<String, Node> getStore(Injector injector) {
|
protected Cache<String, Node> getStore(Injector injector) {
|
||||||
return injector.getInstance(Key.get(new TypeLiteral<Map<String, Node>>() {
|
return injector.getInstance(Key.get(new TypeLiteral<Cache<String, Node>>() {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<String, InputStream> getMap(Injector injector) {
|
protected Map<String, InputStream> getMap(Injector injector) {
|
||||||
return injector.getInstance(Key.get(new TypeLiteral<Map<String, InputStream>>() {
|
return injector.getInstance(Key.get(new TypeLiteral<Map<String, InputStream>>() {
|
||||||
}));
|
}, Names.named("yaml")));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Injector createInjectorWithProvidedMap(Map<String, InputStream> map) {
|
protected Injector createInjectorWithProvidedMap(Map<String, InputStream> map) {
|
||||||
return Guice.createInjector(new YamlNodeStoreModule(map));
|
return Guice.createInjector(new YamlNodeStoreModule(map), new AbstractModule() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bind(new TypeLiteral<Supplier<InputStream>>() {
|
||||||
|
}).annotatedWith(Provider.class).toInstance(Suppliers.<InputStream> ofInstance(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Injector createInjector() {
|
protected Injector createInjector() {
|
||||||
return Guice.createInjector(new YamlNodeStoreModule());
|
return Guice.createInjector(new YamlNodeStoreModule(), new AbstractModule() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bind(new TypeLiteral<Supplier<InputStream>>() {
|
||||||
|
}).annotatedWith(Provider.class).toInstance(Suppliers.<InputStream> ofInstance(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void check(Map<String, InputStream> map, Map<String, Node> store, String key, String id, String name)
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void check(Map<String, InputStream> map, Cache<String, Node> store, String key, String id, String name)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
put(map, store, key, id, name);
|
put(map, store, key, id, name);
|
||||||
checkConsistent(map, store, key, id, name);
|
checkConsistent(map, store, key, id, name);
|
||||||
remove(map, store, key);
|
remove(map, store, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void remove(Map<String, InputStream> map, Map<String, Node> store, String key) {
|
protected void remove(Map<String, InputStream> map, Cache<String, Node> store, String key) {
|
||||||
store.remove(key);
|
store.invalidate(key);
|
||||||
assertEquals(store.size(), 0);
|
assertEquals(store.size(), 0);
|
||||||
|
map.remove(key);
|
||||||
assertEquals(map.size(), 0);
|
assertEquals(map.size(), 0);
|
||||||
assertEquals(store.get(key), null);
|
try {
|
||||||
|
assertEquals(store.getUnchecked(key), null);
|
||||||
|
assert false : "should not work as null is invalid";
|
||||||
|
} catch (UncheckedExecutionException e) {
|
||||||
|
|
||||||
|
}
|
||||||
assertEquals(map.get(key), null);
|
assertEquals(map.get(key), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void checkConsistent(Map<String, InputStream> map, Map<String, Node> store, String key, String id,
|
protected void checkConsistent(Map<String, InputStream> map, Cache<String, Node> store, String key, String id,
|
||||||
String name) throws IOException {
|
String name) throws IOException {
|
||||||
assertEquals(store.size(), 1);
|
|
||||||
assertEquals(map.size(), 1);
|
assertEquals(map.size(), 1);
|
||||||
|
if (store.size() == 0)
|
||||||
|
store.getUnchecked(key);
|
||||||
|
assertEquals(store.size(), 1);
|
||||||
// checkRepeatedRead
|
// checkRepeatedRead
|
||||||
assertEquals(store.get(key), Node.builder().id(id).name(name).build());
|
assertEquals(store.getUnchecked(key), Node.builder().id(id).name(name).build());
|
||||||
assertEquals(store.get(key), Node.builder().id(id).name(name).build());
|
assertEquals(store.getUnchecked(key), Node.builder().id(id).name(name).build());
|
||||||
// checkRepeatedRead
|
// checkRepeatedRead
|
||||||
checkToYaml(map, key, id, name);
|
checkToYaml(map, key, id, name);
|
||||||
checkToYaml(map, key, id, name);
|
checkToYaml(map, key, id, name);
|
||||||
|
@ -155,9 +187,10 @@ public class YamlNodeStoreModuleTest {
|
||||||
assertEquals(Strings2.toStringAndClose(map.get(key)), String.format("id: %s\nname: %s\n", id, name));
|
assertEquals(Strings2.toStringAndClose(map.get(key)), String.format("id: %s\nname: %s\n", id, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void put(Map<String, InputStream> map, Map<String, Node> store, String key, String id, String name) {
|
protected void put(Map<String, InputStream> map, Cache<String, Node> store, String key, String id, String name) {
|
||||||
assertEquals(store.size(), 0);
|
assertEquals(store.size(), 0);
|
||||||
assertEquals(map.size(), 0);
|
assertEquals(map.size(), 0);
|
||||||
store.put(key, Node.builder().id(id).name(name).build());
|
map.put(key, new ByteArrayInputStream(String.format("id: %s\nname: %s\n", id, name).getBytes()));
|
||||||
|
store.getUnchecked(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -45,6 +45,7 @@ import com.google.common.collect.Maps;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@Test(singleThreaded = true, testName = "NodeToNodeMetadataTest")
|
||||||
public class NodeToNodeMetadataTest {
|
public class NodeToNodeMetadataTest {
|
||||||
public static Location expectedProviderLocationFromResource(String resource) {
|
public static Location expectedProviderLocationFromResource(String resource) {
|
||||||
return new LocationBuilder().scope(LocationScope.PROVIDER).id("byon").description(resource).build();
|
return new LocationBuilder().scope(LocationScope.PROVIDER).id("byon").description(resource).build();
|
||||||
|
@ -60,8 +61,8 @@ public class NodeToNodeMetadataTest {
|
||||||
|
|
||||||
Map<String, Credentials> credentialStore = Maps.newLinkedHashMap();
|
Map<String, Credentials> credentialStore = Maps.newLinkedHashMap();
|
||||||
|
|
||||||
NodeToNodeMetadata parser = new NodeToNodeMetadata(Suppliers.ofInstance(provider), Suppliers
|
NodeToNodeMetadata parser = new NodeToNodeMetadata(Suppliers.ofInstance(provider),
|
||||||
.<Set<? extends Location>> ofInstance(ImmutableSet.of(provider, zoneCalled("virginia", provider))),
|
Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet.of(provider, zoneCalled("virginia", provider))),
|
||||||
new SupplyFromProviderURIOrNodesProperty(URI.create("test")), credentialStore);
|
new SupplyFromProviderURIOrNodesProperty(URI.create("test")), credentialStore);
|
||||||
|
|
||||||
public static NodeMetadata expectedNodeMetadataFromResource(String resource) {
|
public static NodeMetadata expectedNodeMetadataFromResource(String resource) {
|
||||||
|
@ -73,10 +74,15 @@ public class NodeToNodeMetadataTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NodeMetadata expectedNodeMetadataFromResource(int id, String resource, Location location) {
|
public static NodeMetadata expectedNodeMetadataFromResource(int id, String resource, Location location) {
|
||||||
|
return expectedNodeMetadataFromResource(id, resource, location, 22);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NodeMetadata expectedNodeMetadataFromResource(int id, String resource, Location location, int loginPort) {
|
||||||
return new NodeMetadataBuilder()
|
return new NodeMetadataBuilder()
|
||||||
.ids("cluster-" + id)
|
.ids("cluster-" + id)
|
||||||
.group("hadoop")
|
.group("hadoop")
|
||||||
.name("cluster-" + id)
|
.name("cluster-" + id)
|
||||||
|
.loginPort(loginPort)
|
||||||
.hostname("cluster-" + id + ".mydomain.com")
|
.hostname("cluster-" + id + ".mydomain.com")
|
||||||
.location(location)
|
.location(location)
|
||||||
.state(NodeState.RUNNING)
|
.state(NodeState.RUNNING)
|
||||||
|
@ -94,8 +100,13 @@ public class NodeToNodeMetadataTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNodesParseLocation() throws Exception {
|
public void testNodesParseLocation() throws Exception {
|
||||||
assertEquals(parser.apply(NodesFromYamlTest.TEST2), expectedNodeMetadataFromResource(resource, zoneCalled(
|
assertEquals(parser.apply(NodesFromYamlTest.TEST2),
|
||||||
"virginia", provider)));
|
expectedNodeMetadataFromResource(resource, zoneCalled("virginia", provider)));
|
||||||
assertEquals(credentialStore, ImmutableMap.of("node#cluster-1", new Credentials("myUser", NodesFromYamlTest.key)));
|
assertEquals(credentialStore, ImmutableMap.of("node#cluster-1", new Credentials("myUser", NodesFromYamlTest.key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNodesParseLoginPort() throws Exception {
|
||||||
|
assertEquals(parser.apply(NodesFromYamlTest.TEST3), expectedNodeMetadataFromResource(2, resource, provider, 2022));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class NodesFromYamlTest {
|
||||||
InputStream is = getClass().getResourceAsStream("/test1.yaml");
|
InputStream is = getClass().getResourceAsStream("/test1.yaml");
|
||||||
NodesFromYamlStream parser = new NodesFromYamlStream();
|
NodesFromYamlStream parser = new NodesFromYamlStream();
|
||||||
|
|
||||||
assertEquals(parser.apply(is), ImmutableMap.of(TEST1.getId(), TEST1));
|
assertEquals(parser.apply(is).asMap(), ImmutableMap.of(TEST1.getId(), TEST1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -67,7 +67,7 @@ public class NodesFromYamlTest {
|
||||||
InputStream is = getClass().getResourceAsStream("/test_location.yaml");
|
InputStream is = getClass().getResourceAsStream("/test_location.yaml");
|
||||||
NodesFromYamlStream parser = new NodesFromYamlStream();
|
NodesFromYamlStream parser = new NodesFromYamlStream();
|
||||||
|
|
||||||
assertEquals(parser.apply(is), ImmutableMap.of(TEST2.getId(), TEST2, TEST3.getId(), TEST3));
|
assertEquals(parser.apply(is).asMap(), ImmutableMap.of(TEST2.getId(), TEST2, TEST3.getId(), TEST3));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -76,7 +76,7 @@ public class NodesFromYamlTest {
|
||||||
InputStream is = getClass().getResourceAsStream("/test_with_url.yaml");
|
InputStream is = getClass().getResourceAsStream("/test_with_url.yaml");
|
||||||
NodesFromYamlStream parser = new NodesFromYamlStream();
|
NodesFromYamlStream parser = new NodesFromYamlStream();
|
||||||
|
|
||||||
assertEquals(parser.apply(is), ImmutableMap.of(TEST1.getId(), TEST1));
|
assertEquals(parser.apply(is).asMap(), ImmutableMap.of(TEST1.getId(), TEST1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
|
|
|
@ -23,7 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
|
|
@ -21,7 +21,6 @@ package org.jclouds.cloudwatch;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.ws.rs.FormParam;
|
import javax.ws.rs.FormParam;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
@ -30,6 +29,7 @@ import org.jclouds.aws.filters.FormSigner;
|
||||||
import org.jclouds.cloudwatch.domain.Datapoint;
|
import org.jclouds.cloudwatch.domain.Datapoint;
|
||||||
import org.jclouds.cloudwatch.functions.ISO8601Format;
|
import org.jclouds.cloudwatch.functions.ISO8601Format;
|
||||||
import org.jclouds.cloudwatch.xml.GetMetricStatisticsResponseHandler;
|
import org.jclouds.cloudwatch.xml.GetMetricStatisticsResponseHandler;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
|
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
|
||||||
import org.jclouds.rest.annotations.EndpointParam;
|
import org.jclouds.rest.annotations.EndpointParam;
|
||||||
import org.jclouds.rest.annotations.FormParams;
|
import org.jclouds.rest.annotations.FormParams;
|
|
@ -22,10 +22,9 @@ import java.util.Date;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import org.jclouds.cloudwatch.domain.Datapoint;
|
import org.jclouds.cloudwatch.domain.Datapoint;
|
||||||
import org.jclouds.concurrent.Timeout;
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to Amazon CloudWatch via the Query API
|
* Provides access to Amazon CloudWatch via the Query API
|
|
@ -0,0 +1,53 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.cloudwatch;
|
||||||
|
|
||||||
|
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||||
|
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
|
||||||
|
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.PropertiesBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds properties used in Cloud Watch Clients
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class CloudWatchPropertiesBuilder extends PropertiesBuilder {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Properties defaultProperties() {
|
||||||
|
Properties properties = super.defaultProperties();
|
||||||
|
properties.setProperty(PROPERTY_AUTH_TAG, "AWS");
|
||||||
|
properties.setProperty(PROPERTY_HEADER_TAG, "amz");
|
||||||
|
properties.setProperty(PROPERTY_API_VERSION, CloudWatchAsyncClient.VERSION);
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CloudWatchPropertiesBuilder() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CloudWatchPropertiesBuilder(Properties properties) {
|
||||||
|
super(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ package org.jclouds.cloudwatch.domain;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/index.html?DT_Datapoint.html"
|
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/index.html?DT_Datapoint.html"
|
|
@ -109,7 +109,9 @@ public class CloudWatchAsyncClientTest extends RestClientTest<CloudWatchAsyncCli
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RestContextSpec<?, ?> createContextSpec() {
|
public RestContextSpec<?, ?> createContextSpec() {
|
||||||
return new RestContextFactory().createContextSpec("cloudwatch", "identity", "credential", new Properties());
|
Properties props = new Properties();
|
||||||
|
props.setProperty("cloudwatch.endpoint", "https://monitoring.us-east-1.amazonaws.com");
|
||||||
|
return new RestContextFactory().createContextSpec("cloudwatch", "identity", "credential", props);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -25,7 +25,6 @@ import java.util.Date;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.aws.domain.Region;
|
|
||||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.rest.RestContextFactory;
|
import org.jclouds.rest.RestContextFactory;
|
||||||
|
@ -83,13 +82,15 @@ public class CloudWatchClientLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetMetricStatisticsInRegion() {
|
protected void testGetMetricStatisticsInRegion() {
|
||||||
|
getMetricStatisticsInRegion(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void getMetricStatisticsInRegion(String region) {
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
cal.add(Calendar.MINUTE, -1);
|
cal.add(Calendar.MINUTE, -1);
|
||||||
for (String region : Region.DEFAULT_REGIONS) {
|
|
||||||
assert client.getMetricStatisticsInRegion(region, "CPUUtilization", cal.getTime(), new Date(), 60, "Average") != null;
|
assert client.getMetricStatisticsInRegion(region, "CPUUtilization", cal.getTime(), new Date(), 60, "Average") != null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@AfterTest
|
@AfterTest
|
||||||
public void shutdown() {
|
public void shutdown() {
|
|
@ -22,7 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An image is a platonic form of a machine. Images are not directly executable, but are a template
|
* An image is a platonic form of a machine. Images are not directly executable, but are a template
|
||||||
|
|
|
@ -24,7 +24,7 @@ import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Within a cloud provider a realm represents a boundary containing resources. The exact definition
|
* Within a cloud provider a realm represents a boundary containing resources. The exact definition
|
||||||
|
|
|
@ -23,7 +23,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.deltacloud.domain.EnumHardwareProperty;
|
import org.jclouds.deltacloud.domain.EnumHardwareProperty;
|
||||||
import org.jclouds.deltacloud.domain.FixedHardwareProperty;
|
import org.jclouds.deltacloud.domain.FixedHardwareProperty;
|
||||||
|
|
|
@ -22,6 +22,7 @@ import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
|
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
|
||||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
|
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
|
||||||
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
|
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
|
||||||
|
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_TIMEOUT_SECURITYGROUP_PRESENT;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
@ -40,6 +41,7 @@ public class EC2PropertiesBuilder extends PropertiesBuilder {
|
||||||
properties.setProperty(PROPERTY_HEADER_TAG, "amz");
|
properties.setProperty(PROPERTY_HEADER_TAG, "amz");
|
||||||
properties.setProperty(PROPERTY_API_VERSION, EC2AsyncClient.VERSION);
|
properties.setProperty(PROPERTY_API_VERSION, EC2AsyncClient.VERSION);
|
||||||
properties.setProperty(PROPERTY_EC2_AMI_OWNERS, "*");
|
properties.setProperty(PROPERTY_EC2_AMI_OWNERS, "*");
|
||||||
|
properties.setProperty(PROPERTY_EC2_TIMEOUT_SECURITYGROUP_PRESENT, "500");
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,7 @@ import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
import com.google.common.collect.ImmutableMultimap.Builder;
|
import com.google.common.collect.ImmutableMultimap.Builder;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
@ -78,8 +79,8 @@ import com.google.common.collect.ImmutableSet;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class EC2ComputeService extends BaseComputeService {
|
public class EC2ComputeService extends BaseComputeService {
|
||||||
private final EC2Client ec2Client;
|
private final EC2Client ec2Client;
|
||||||
private final Map<RegionAndName, KeyPair> credentialsMap;
|
private final Cache<RegionAndName, KeyPair> credentialsMap;
|
||||||
private final Map<RegionAndName, String> securityGroupMap;
|
private final Cache<RegionAndName, String> securityGroupMap;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected EC2ComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore,
|
protected EC2ComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore,
|
||||||
|
@ -96,7 +97,7 @@ public class EC2ComputeService extends BaseComputeService {
|
||||||
RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess,
|
RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess,
|
||||||
PersistNodeCredentials persistNodeCredentials, Timeouts timeouts,
|
PersistNodeCredentials persistNodeCredentials, Timeouts timeouts,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
|
||||||
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap) {
|
Cache<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Cache<RegionAndName, String> securityGroupMap) {
|
||||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
||||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy,
|
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy,
|
||||||
templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended,
|
templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended,
|
||||||
|
@ -116,7 +117,7 @@ public class EC2ComputeService extends BaseComputeService {
|
||||||
try {
|
try {
|
||||||
ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(region, groupName);
|
ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(region, groupName);
|
||||||
// TODO: test this clear happens
|
// TODO: test this clear happens
|
||||||
securityGroupMap.remove(new RegionNameAndIngressRules(region, groupName, null, false));
|
securityGroupMap.invalidate(new RegionNameAndIngressRules(region, groupName, null, false));
|
||||||
logger.debug("<< deleted securityGroup(%s)", groupName);
|
logger.debug("<< deleted securityGroup(%s)", groupName);
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
logger.debug("<< inUse securityGroup(%s)", groupName);
|
logger.debug("<< inUse securityGroup(%s)", groupName);
|
||||||
|
@ -142,7 +143,7 @@ public class EC2ComputeService extends BaseComputeService {
|
||||||
logger.debug(">> deleting keyPair(%s)", keyPair.getKeyName());
|
logger.debug(">> deleting keyPair(%s)", keyPair.getKeyName());
|
||||||
ec2Client.getKeyPairServices().deleteKeyPairInRegion(region, keyPair.getKeyName());
|
ec2Client.getKeyPairServices().deleteKeyPairInRegion(region, keyPair.getKeyName());
|
||||||
// TODO: test this clear happens
|
// TODO: test this clear happens
|
||||||
credentialsMap.remove(new RegionAndName(region, keyPair.getKeyName()));
|
credentialsMap.invalidate(new RegionAndName(region, keyPair.getKeyName()));
|
||||||
logger.debug("<< deleted keyPair(%s)", keyPair.getKeyName());
|
logger.debug("<< deleted keyPair(%s)", keyPair.getKeyName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,6 @@ import static com.google.common.collect.Iterables.toArray;
|
||||||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
||||||
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
|
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
@ -37,6 +35,7 @@ import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExc
|
||||||
|
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,12 +58,12 @@ public class EC2ComputeServiceContextModule extends BaseComputeServiceContextMod
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Supplier<Map<RegionAndName, ? extends Image>> provideRegionAndNameToImageSupplierCache(
|
protected Supplier<Cache<RegionAndName, ? extends Image>> provideRegionAndNameToImageSupplierCache(
|
||||||
@Named(PROPERTY_SESSION_INTERVAL) long seconds, final RegionAndNameToImageSupplier supplier) {
|
@Named(PROPERTY_SESSION_INTERVAL) long seconds, final RegionAndNameToImageSupplier supplier) {
|
||||||
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<RegionAndName, ? extends Image>>(
|
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Cache<RegionAndName, ? extends Image>>(
|
||||||
authException, seconds, new Supplier<Map<RegionAndName, ? extends Image>>() {
|
authException, seconds, new Supplier<Cache<RegionAndName, ? extends Image>>() {
|
||||||
@Override
|
@Override
|
||||||
public Map<RegionAndName, ? extends Image> get() {
|
public Cache<RegionAndName, ? extends Image> get() {
|
||||||
return supplier.get();
|
return supplier.get();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,10 +18,11 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.ec2.compute.config;
|
package org.jclouds.ec2.compute.config;
|
||||||
|
|
||||||
import static com.google.common.collect.Maps.newLinkedHashMap;
|
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_TIMEOUT_SECURITYGROUP_PRESENT;
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
@ -39,7 +40,6 @@ import org.jclouds.ec2.EC2AsyncClient;
|
||||||
import org.jclouds.ec2.EC2Client;
|
import org.jclouds.ec2.EC2Client;
|
||||||
import org.jclouds.ec2.compute.EC2ComputeService;
|
import org.jclouds.ec2.compute.EC2ComputeService;
|
||||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
|
||||||
import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
|
import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
|
||||||
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
|
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
|
||||||
import org.jclouds.ec2.compute.functions.CredentialsForInstance;
|
import org.jclouds.ec2.compute.functions.CredentialsForInstance;
|
||||||
|
@ -47,16 +47,22 @@ import org.jclouds.ec2.compute.functions.RegionAndIdToImage;
|
||||||
import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata;
|
import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata;
|
||||||
import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl;
|
import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl;
|
||||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||||
|
import org.jclouds.ec2.compute.predicates.SecurityGroupPresent;
|
||||||
import org.jclouds.ec2.domain.InstanceState;
|
import org.jclouds.ec2.domain.InstanceState;
|
||||||
import org.jclouds.ec2.domain.KeyPair;
|
import org.jclouds.ec2.domain.KeyPair;
|
||||||
import org.jclouds.ec2.domain.RunningInstance;
|
import org.jclouds.ec2.domain.RunningInstance;
|
||||||
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.rest.internal.RestContextImpl;
|
import org.jclouds.rest.internal.RestContextImpl;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.MapMaker;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import com.google.inject.Scopes;
|
import com.google.inject.Scopes;
|
||||||
|
@ -69,9 +75,9 @@ import com.google.inject.TypeLiteral;
|
||||||
public class EC2ComputeServiceDependenciesModule extends AbstractModule {
|
public class EC2ComputeServiceDependenciesModule extends AbstractModule {
|
||||||
|
|
||||||
public static final Map<InstanceState, NodeState> instanceToNodeState = ImmutableMap
|
public static final Map<InstanceState, NodeState> instanceToNodeState = ImmutableMap
|
||||||
.<InstanceState, NodeState> builder().put(InstanceState.PENDING, NodeState.PENDING).put(
|
.<InstanceState, NodeState> builder().put(InstanceState.PENDING, NodeState.PENDING)
|
||||||
InstanceState.RUNNING, NodeState.RUNNING).put(InstanceState.SHUTTING_DOWN, NodeState.PENDING).put(
|
.put(InstanceState.RUNNING, NodeState.RUNNING).put(InstanceState.SHUTTING_DOWN, NodeState.PENDING)
|
||||||
InstanceState.TERMINATED, NodeState.TERMINATED).put(InstanceState.STOPPING, NodeState.PENDING)
|
.put(InstanceState.TERMINATED, NodeState.TERMINATED).put(InstanceState.STOPPING, NodeState.PENDING)
|
||||||
.put(InstanceState.STOPPED, NodeState.SUSPENDED).put(InstanceState.UNRECOGNIZED, NodeState.UNRECOGNIZED)
|
.put(InstanceState.STOPPED, NodeState.SUSPENDED).put(InstanceState.UNRECOGNIZED, NodeState.UNRECOGNIZED)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -88,13 +94,13 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule {
|
||||||
bind(ComputeService.class).to(EC2ComputeService.class);
|
bind(ComputeService.class).to(EC2ComputeService.class);
|
||||||
bind(new TypeLiteral<Function<RunningInstance, NodeMetadata>>() {
|
bind(new TypeLiteral<Function<RunningInstance, NodeMetadata>>() {
|
||||||
}).to(RunningInstanceToNodeMetadata.class);
|
}).to(RunningInstanceToNodeMetadata.class);
|
||||||
bind(new TypeLiteral<Function<RunningInstance, Credentials>>() {
|
bind(new TypeLiteral<CacheLoader<RunningInstance, Credentials>>() {
|
||||||
}).to(CredentialsForInstance.class);
|
}).to(CredentialsForInstance.class);
|
||||||
bind(new TypeLiteral<Function<RegionNameAndIngressRules, String>>() {
|
bind(new TypeLiteral<CacheLoader<RegionAndName, String>>() {
|
||||||
}).to(CreateSecurityGroupIfNeeded.class);
|
}).to(CreateSecurityGroupIfNeeded.class);
|
||||||
bind(new TypeLiteral<Function<RegionAndName, KeyPair>>() {
|
bind(new TypeLiteral<CacheLoader<RegionAndName, KeyPair>>() {
|
||||||
}).to(CreateUniqueKeyPair.class);
|
}).to(CreateUniqueKeyPair.class);
|
||||||
bind(new TypeLiteral<Function<RegionAndName, Image>>() {
|
bind(new TypeLiteral<CacheLoader<RegionAndName, Image>>() {
|
||||||
}).to(RegionAndIdToImage.class);
|
}).to(RegionAndIdToImage.class);
|
||||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||||
}).to(new TypeLiteral<ComputeServiceContextImpl<EC2Client, EC2AsyncClient>>() {
|
}).to(new TypeLiteral<ComputeServiceContextImpl<EC2Client, EC2AsyncClient>>() {
|
||||||
|
@ -120,25 +126,43 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected final Map<RegionAndName, KeyPair> credentialsMap(Function<RegionAndName, KeyPair> in) {
|
protected Cache<RunningInstance, Credentials> credentialsMap(CacheLoader<RunningInstance, Credentials> in) {
|
||||||
// doesn't seem to clear when someone issues remove(key)
|
return CacheBuilder.newBuilder().build(in);
|
||||||
// return new MapMaker().makeComputingMap(in);
|
}
|
||||||
return newLinkedHashMap();
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected Cache<RegionAndName, KeyPair> keypairMap(CacheLoader<RegionAndName, KeyPair> in) {
|
||||||
|
return CacheBuilder.newBuilder().build(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
// keys that we know about.
|
||||||
|
protected Map<RegionAndName, KeyPair> knownKeys(){
|
||||||
|
return Maps.newConcurrentMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@Named("SECURITY")
|
@Named("SECURITY")
|
||||||
protected final Map<RegionAndName, String> securityGroupMap(Function<RegionNameAndIngressRules, String> in) {
|
protected Cache<RegionAndName, String> securityGroupMap(CacheLoader<RegionAndName, String> in) {
|
||||||
// doesn't seem to clear when someone issues remove(key)
|
return CacheBuilder.newBuilder().build(in);
|
||||||
// return new MapMaker().makeComputingMap(in);
|
|
||||||
return newLinkedHashMap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Map<RegionAndName, Image> provideImageMap(Function<RegionAndName, Image> regionAndIdToImage) {
|
@Named("SECURITY")
|
||||||
return new MapMaker().makeComputingMap(regionAndIdToImage);
|
protected Predicate<RegionAndName> securityGroupEventualConsistencyDelay(SecurityGroupPresent in,
|
||||||
|
@Named(PROPERTY_EC2_TIMEOUT_SECURITYGROUP_PRESENT) long msDelay) {
|
||||||
|
return new RetryablePredicate<RegionAndName>(in, msDelay, 100l, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
// keys that we know about.
|
||||||
|
protected Map<RegionAndName, Image> knownImages(){
|
||||||
|
return Maps.newConcurrentMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,14 +25,17 @@ import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.ec2.EC2Client;
|
import org.jclouds.ec2.EC2Client;
|
||||||
|
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||||
import org.jclouds.ec2.domain.IpProtocol;
|
import org.jclouds.ec2.domain.IpProtocol;
|
||||||
import org.jclouds.ec2.domain.UserIdGroupPair;
|
import org.jclouds.ec2.domain.UserIdGroupPair;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.ec2.services.SecurityGroupClient;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,20 +43,30 @@ import com.google.common.collect.Iterables;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class CreateSecurityGroupIfNeeded implements Function<RegionNameAndIngressRules, String> {
|
public class CreateSecurityGroupIfNeeded extends CacheLoader<RegionAndName, String> {
|
||||||
@Resource
|
@Resource
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
protected final EC2Client ec2Client;
|
protected final SecurityGroupClient securityClient;
|
||||||
|
protected final Predicate<RegionAndName> securityGroupEventualConsistencyDelay;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CreateSecurityGroupIfNeeded(EC2Client ec2Client) {
|
public CreateSecurityGroupIfNeeded(EC2Client ec2Client,
|
||||||
this.ec2Client = ec2Client;
|
@Named("SECURITY") Predicate<RegionAndName> securityGroupEventualConsistencyDelay) {
|
||||||
|
this(checkNotNull(ec2Client, "ec2Client").getSecurityGroupServices(), securityGroupEventualConsistencyDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateSecurityGroupIfNeeded(SecurityGroupClient securityClient,
|
||||||
|
@Named("SECURITY") Predicate<RegionAndName> securityGroupEventualConsistencyDelay) {
|
||||||
|
this.securityClient = checkNotNull(securityClient, "securityClient");
|
||||||
|
this.securityGroupEventualConsistencyDelay = checkNotNull(securityGroupEventualConsistencyDelay,
|
||||||
|
"securityGroupEventualConsistencyDelay");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(RegionNameAndIngressRules from) {
|
public String load(RegionAndName from) {
|
||||||
createSecurityGroupInRegion(from.getRegion(), from.getName(), from.getPorts());
|
RegionNameAndIngressRules realFrom = RegionNameAndIngressRules.class.cast(from);
|
||||||
|
createSecurityGroupInRegion(from.getRegion(), from.getName(), realFrom.getPorts());
|
||||||
return from.getName();
|
return from.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +75,11 @@ public class CreateSecurityGroupIfNeeded implements Function<RegionNameAndIngres
|
||||||
checkNotNull(name, "name");
|
checkNotNull(name, "name");
|
||||||
logger.debug(">> creating securityGroup region(%s) name(%s)", region, name);
|
logger.debug(">> creating securityGroup region(%s) name(%s)", region, name);
|
||||||
try {
|
try {
|
||||||
ec2Client.getSecurityGroupServices().createSecurityGroupInRegion(region, name, name);
|
securityClient.createSecurityGroupInRegion(region, name, name);
|
||||||
|
boolean created = securityGroupEventualConsistencyDelay.apply(new RegionAndName(region, name));
|
||||||
|
if (!created)
|
||||||
|
throw new RuntimeException(String.format("security group %s/%s is not available after creating", region,
|
||||||
|
name));
|
||||||
logger.debug("<< created securityGroup(%s)", name);
|
logger.debug("<< created securityGroup(%s)", name);
|
||||||
for (int port : ports) {
|
for (int port : ports) {
|
||||||
createIngressRuleForTCPPort(region, name, port);
|
createIngressRuleForTCPPort(region, name, port);
|
||||||
|
@ -77,17 +94,14 @@ public class CreateSecurityGroupIfNeeded implements Function<RegionNameAndIngres
|
||||||
|
|
||||||
private void createIngressRuleForTCPPort(String region, String name, int port) {
|
private void createIngressRuleForTCPPort(String region, String name, int port) {
|
||||||
logger.debug(">> authorizing securityGroup region(%s) name(%s) port(%s)", region, name, port);
|
logger.debug(">> authorizing securityGroup region(%s) name(%s) port(%s)", region, name, port);
|
||||||
ec2Client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(region, name, IpProtocol.TCP, port,
|
securityClient.authorizeSecurityGroupIngressInRegion(region, name, IpProtocol.TCP, port, port, "0.0.0.0/0");
|
||||||
port, "0.0.0.0/0");
|
|
||||||
logger.debug("<< authorized securityGroup(%s)", name);
|
logger.debug("<< authorized securityGroup(%s)", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void authorizeGroupToItself(String region, String name) {
|
private void authorizeGroupToItself(String region, String name) {
|
||||||
logger.debug(">> authorizing securityGroup region(%s) name(%s) permission to itself", region, name);
|
logger.debug(">> authorizing securityGroup region(%s) name(%s) permission to itself", region, name);
|
||||||
String myOwnerId = Iterables.get(ec2Client.getSecurityGroupServices().describeSecurityGroupsInRegion(region), 0)
|
String myOwnerId = Iterables.get(securityClient.describeSecurityGroupsInRegion(region, name), 0).getOwnerId();
|
||||||
.getOwnerId();
|
securityClient.authorizeSecurityGroupIngressInRegion(region, name, new UserIdGroupPair(myOwnerId, name));
|
||||||
ec2Client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(region, name,
|
|
||||||
new UserIdGroupPair(myOwnerId, name));
|
|
||||||
logger.debug("<< authorized securityGroup(%s)", name);
|
logger.debug("<< authorized securityGroup(%s)", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ package org.jclouds.ec2.compute.functions;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
@ -32,30 +34,39 @@ import org.jclouds.ec2.domain.KeyPair;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class CreateUniqueKeyPair implements Function<RegionAndName, KeyPair> {
|
public class CreateUniqueKeyPair extends CacheLoader<RegionAndName, KeyPair> {
|
||||||
@Resource
|
@Resource
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
protected final EC2Client ec2Client;
|
protected final EC2Client ec2Client;
|
||||||
protected final Supplier<String> randomSuffix;
|
protected final Supplier<String> randomSuffix;
|
||||||
|
protected final Map<RegionAndName, KeyPair> knownKeys;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CreateUniqueKeyPair(EC2Client ec2Client, Supplier<String> randomSuffix) {
|
public CreateUniqueKeyPair(Map<RegionAndName, KeyPair> knownKeys, EC2Client ec2Client, Supplier<String> randomSuffix) {
|
||||||
|
this.knownKeys = knownKeys;
|
||||||
this.ec2Client = ec2Client;
|
this.ec2Client = ec2Client;
|
||||||
this.randomSuffix = randomSuffix;
|
this.randomSuffix = randomSuffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyPair apply(RegionAndName from) {
|
public KeyPair load(RegionAndName from) {
|
||||||
return createNewKeyPairInRegion(from.getRegion(), from.getName());
|
if (knownKeys.containsKey(from)){
|
||||||
|
return knownKeys.get(from);
|
||||||
|
} else {
|
||||||
|
KeyPair keyPair = createNewKeyPairInRegion(from.getRegion(), from.getName());
|
||||||
|
knownKeys.put(new RegionAndName(from.getRegion(), keyPair.getKeyName()), keyPair);
|
||||||
|
knownKeys.put(from, keyPair);
|
||||||
|
return keyPair;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
|
|
@ -20,43 +20,44 @@ package org.jclouds.ec2.compute.functions;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
|
||||||
import org.jclouds.ec2.domain.KeyPair;
|
|
||||||
import org.jclouds.ec2.domain.RunningInstance;
|
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
|
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||||
|
import org.jclouds.ec2.domain.KeyPair;
|
||||||
|
import org.jclouds.ec2.domain.RunningInstance;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class CredentialsForInstance implements Function<RunningInstance, Credentials> {
|
public class CredentialsForInstance extends CacheLoader<RunningInstance, Credentials> {
|
||||||
private final Map<RegionAndName, KeyPair> credentialsMap;
|
private final Cache<RegionAndName, KeyPair> credentialsMap;
|
||||||
private final PopulateDefaultLoginCredentialsForImageStrategy credentialProvider;
|
private final PopulateDefaultLoginCredentialsForImageStrategy credentialProvider;
|
||||||
private final Map<RegionAndName, Image> imageForInstance;
|
private final Supplier<Cache<RegionAndName, ? extends Image>> imageMap;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
CredentialsForInstance(Map<RegionAndName, KeyPair> credentialsMap,
|
CredentialsForInstance(Cache<RegionAndName, KeyPair> credentialsMap,
|
||||||
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider, Map<RegionAndName, Image> imageForInstance) {
|
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider, Supplier<Cache<RegionAndName, ? extends Image>> imageMap) {
|
||||||
this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap");
|
this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap");
|
||||||
this.credentialProvider = checkNotNull(credentialProvider, "credentialProvider");
|
this.credentialProvider = checkNotNull(credentialProvider, "credentialProvider");
|
||||||
this.imageForInstance = imageForInstance;
|
this.imageMap = imageMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Credentials apply(RunningInstance instance) {
|
public Credentials load(RunningInstance instance) throws ExecutionException {
|
||||||
Credentials credentials = null;// default if no keypair exists
|
Credentials credentials = null;// default if no keypair exists
|
||||||
|
|
||||||
if (instance.getKeyName() != null) {
|
if (instance.getKeyName() != null) {
|
||||||
credentials = new Credentials(getLoginAccountFor(instance), getPrivateKeyOrNull(instance));
|
credentials = new Credentials(getLoginAccountFor(instance), getPrivateKeyOrNull(instance));
|
||||||
}
|
}
|
||||||
|
@ -64,15 +65,15 @@ public class CredentialsForInstance implements Function<RunningInstance, Credent
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
String getPrivateKeyOrNull(RunningInstance instance) {
|
String getPrivateKeyOrNull(RunningInstance instance) throws ExecutionException {
|
||||||
KeyPair keyPair = credentialsMap.get(new RegionAndName(instance.getRegion(), instance.getKeyName()));
|
KeyPair keyPair = credentialsMap.get(new RegionAndName(instance.getRegion(), instance.getKeyName()));
|
||||||
return keyPair != null ? keyPair.getKeyMaterial() : null;
|
return keyPair != null ? keyPair.getKeyMaterial() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
String getLoginAccountFor(RunningInstance from) {
|
String getLoginAccountFor(RunningInstance from) throws ExecutionException {
|
||||||
return checkNotNull(
|
return checkNotNull(
|
||||||
credentialProvider.execute(imageForInstance.get(new RegionAndName(from.getRegion(), from.getImageId()))),
|
credentialProvider.execute(imageMap.get().get(new RegionAndName(from.getRegion(), from.getImageId()))),
|
||||||
"login from image: " + from.getImageId()).identity;
|
"login from image: " + from.getImageId()).identity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,19 +20,19 @@ package org.jclouds.ec2.compute.functions;
|
||||||
|
|
||||||
import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.imageIds;
|
import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.imageIds;
|
||||||
|
|
||||||
import java.util.NoSuchElementException;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.ec2.EC2Client;
|
import org.jclouds.ec2.EC2Client;
|
||||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||||
import org.jclouds.compute.domain.Image;
|
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,33 +40,31 @@ import com.google.common.collect.Iterables;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public final class RegionAndIdToImage implements Function<RegionAndName, Image> {
|
public class RegionAndIdToImage extends CacheLoader<RegionAndName, Image> {
|
||||||
@Resource
|
@Resource
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
private final Map<RegionAndName, Image> knownImages;
|
||||||
private final EC2ImageParser parser;
|
private final EC2ImageParser parser;
|
||||||
private final EC2Client sync;
|
private final EC2Client sync;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RegionAndIdToImage(EC2ImageParser parser, EC2Client sync) {
|
public RegionAndIdToImage(Map<RegionAndName, Image> knownImages, EC2ImageParser parser, EC2Client sync) {
|
||||||
|
this.knownImages = knownImages;
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
this.sync = sync;
|
this.sync = sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Image apply(RegionAndName key) {
|
@Override
|
||||||
|
public Image load(RegionAndName key) throws ExecutionException{
|
||||||
|
if (knownImages.containsKey(key))
|
||||||
|
return knownImages.get(key);
|
||||||
try {
|
try {
|
||||||
org.jclouds.ec2.domain.Image image = Iterables.getOnlyElement(sync.getAMIServices()
|
org.jclouds.ec2.domain.Image image = Iterables.getOnlyElement(sync.getAMIServices()
|
||||||
.describeImagesInRegion(key.getRegion(), imageIds(key.getName())));
|
.describeImagesInRegion(key.getRegion(), imageIds(key.getName())));
|
||||||
return parser.apply(image);
|
return parser.apply(image);
|
||||||
} catch (NoSuchElementException e) {
|
|
||||||
logger.debug(message(key, e));
|
|
||||||
return null;
|
|
||||||
} catch (ResourceNotFoundException e) {
|
|
||||||
logger.debug(message(key, e));
|
|
||||||
return null;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.warn(e, message(key, e));
|
throw new ExecutionException(message(key, e), e);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,6 @@ import javax.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
|
||||||
import org.jclouds.ec2.domain.BlockDevice;
|
|
||||||
import org.jclouds.ec2.domain.InstanceState;
|
|
||||||
import org.jclouds.ec2.domain.RootDeviceType;
|
|
||||||
import org.jclouds.ec2.domain.RunningInstance;
|
|
||||||
import org.jclouds.collect.Memoized;
|
import org.jclouds.collect.Memoized;
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
import org.jclouds.compute.domain.HardwareBuilder;
|
import org.jclouds.compute.domain.HardwareBuilder;
|
||||||
|
@ -46,6 +41,11 @@ import org.jclouds.compute.domain.Volume;
|
||||||
import org.jclouds.compute.domain.internal.VolumeImpl;
|
import org.jclouds.compute.domain.internal.VolumeImpl;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
|
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||||
|
import org.jclouds.ec2.domain.BlockDevice;
|
||||||
|
import org.jclouds.ec2.domain.InstanceState;
|
||||||
|
import org.jclouds.ec2.domain.RootDeviceType;
|
||||||
|
import org.jclouds.ec2.domain.RunningInstance;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.util.NullSafeCollections;
|
import org.jclouds.util.NullSafeCollections;
|
||||||
|
|
||||||
|
@ -53,8 +53,10 @@ import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
@ -67,17 +69,17 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
|
||||||
|
|
||||||
protected final Supplier<Set<? extends Location>> locations;
|
protected final Supplier<Set<? extends Location>> locations;
|
||||||
protected final Supplier<Set<? extends Hardware>> hardware;
|
protected final Supplier<Set<? extends Hardware>> hardware;
|
||||||
protected final Map<RegionAndName, Image> instanceToImage;
|
protected final Supplier<Cache<RegionAndName, ? extends Image>> imageMap;
|
||||||
protected final Map<String, Credentials> credentialStore;
|
protected final Map<String, Credentials> credentialStore;
|
||||||
protected final Map<InstanceState, NodeState> instanceToNodeState;
|
protected final Map<InstanceState, NodeState> instanceToNodeState;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected RunningInstanceToNodeMetadata(Map<InstanceState, NodeState> instanceToNodeState,
|
protected RunningInstanceToNodeMetadata(Map<InstanceState, NodeState> instanceToNodeState,
|
||||||
Map<String, Credentials> credentialStore, Map<RegionAndName, Image> instanceToImage,
|
Map<String, Credentials> credentialStore, Supplier<Cache<RegionAndName, ? extends Image>> imageMap,
|
||||||
@Memoized Supplier<Set<? extends Location>> locations, @Memoized Supplier<Set<? extends Hardware>> hardware) {
|
@Memoized Supplier<Set<? extends Location>> locations, @Memoized Supplier<Set<? extends Hardware>> hardware) {
|
||||||
this.locations = checkNotNull(locations, "locations");
|
this.locations = checkNotNull(locations, "locations");
|
||||||
this.hardware = checkNotNull(hardware, "hardware");
|
this.hardware = checkNotNull(hardware, "hardware");
|
||||||
this.instanceToImage = checkNotNull(instanceToImage, "instanceToImage");
|
this.imageMap = checkNotNull(imageMap, "imageMap");
|
||||||
this.instanceToNodeState = checkNotNull(instanceToNodeState, "instanceToNodeState");
|
this.instanceToNodeState = checkNotNull(instanceToNodeState, "instanceToNodeState");
|
||||||
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
||||||
}
|
}
|
||||||
|
@ -106,17 +108,13 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
|
||||||
// extract the operating system from the image
|
// extract the operating system from the image
|
||||||
RegionAndName regionAndName = new RegionAndName(instance.getRegion(), instance.getImageId());
|
RegionAndName regionAndName = new RegionAndName(instance.getRegion(), instance.getImageId());
|
||||||
try {
|
try {
|
||||||
Image image = instanceToImage.get(regionAndName);
|
Image image = imageMap.get().getUnchecked(regionAndName);
|
||||||
if (image != null)
|
if (image != null)
|
||||||
builder.operatingSystem(image.getOperatingSystem());
|
builder.operatingSystem(image.getOperatingSystem());
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
// The instanceToImage Map may throw NullPointerException (actually subclass
|
logger.debug("image not found for %s: %s", regionAndName, e);
|
||||||
// NullOutputException) if the
|
} catch (UncheckedExecutionException e) {
|
||||||
// computing Function returns a null value.
|
logger.debug("error getting image for %s: %s", regionAndName, e);
|
||||||
//
|
|
||||||
// See the following for more information:
|
|
||||||
// MapMaker.makeComputingMap()
|
|
||||||
// RegionAndIdToImage.apply()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
|
|
@ -20,9 +20,9 @@ package org.jclouds.ec2.compute.internal;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
@ -38,7 +38,8 @@ import org.jclouds.domain.Location;
|
||||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ComputationException;
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -46,13 +47,13 @@ import com.google.common.collect.ComputationException;
|
||||||
*/
|
*/
|
||||||
public class EC2TemplateBuilderImpl extends TemplateBuilderImpl {
|
public class EC2TemplateBuilderImpl extends TemplateBuilderImpl {
|
||||||
|
|
||||||
private final Map<RegionAndName, Image> imageMap;
|
private final Supplier<Cache<RegionAndName, ? extends Image>> imageMap;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected EC2TemplateBuilderImpl(@Memoized Supplier<Set<? extends Location>> locations,
|
protected EC2TemplateBuilderImpl(@Memoized Supplier<Set<? extends Location>> locations,
|
||||||
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
|
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
|
||||||
Supplier<Location> defaultLocation, @Named("DEFAULT") Provider<TemplateOptions> optionsProvider,
|
Supplier<Location> defaultLocation, @Named("DEFAULT") Provider<TemplateOptions> optionsProvider,
|
||||||
@Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider, Map<RegionAndName, Image> imageMap) {
|
@Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider, Supplier<Cache<RegionAndName, ? extends Image>> imageMap) {
|
||||||
super(locations, images, sizes, defaultLocation, optionsProvider, defaultTemplateProvider);
|
super(locations, images, sizes, defaultLocation, optionsProvider, defaultTemplateProvider);
|
||||||
this.imageMap = imageMap;
|
this.imageMap = imageMap;
|
||||||
}
|
}
|
||||||
|
@ -67,11 +68,13 @@ public class EC2TemplateBuilderImpl extends TemplateBuilderImpl {
|
||||||
"amazon image ids must include the region ( ex. us-east-1/ami-7ea24a17 ) you specified: " + imageId);
|
"amazon image ids must include the region ( ex. us-east-1/ami-7ea24a17 ) you specified: " + imageId);
|
||||||
RegionAndName key = new RegionAndName(regionName[0], regionName[1]);
|
RegionAndName key = new RegionAndName(regionName[0], regionName[1]);
|
||||||
try {
|
try {
|
||||||
return imageMap.get(key);
|
return imageMap.get().get(key);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
throw new NoSuchElementException(String.format("could not get imageId(%s/%s)", key.getRegion(), key.getName()));
|
||||||
|
} catch (UncheckedExecutionException e) {
|
||||||
|
throw new NoSuchElementException(String.format("could not get imageId(%s/%s)", key.getRegion(), key.getName()));
|
||||||
} catch (NullPointerException nex) {
|
} catch (NullPointerException nex) {
|
||||||
throw new NoSuchElementException(String.format("imageId(%s/%s) not found", key.getRegion(), key.getName()));
|
throw new NoSuchElementException(String.format("imageId(%s/%s) not found", key.getRegion(), key.getName()));
|
||||||
} catch (ComputationException nex) {
|
|
||||||
throw new NoSuchElementException(String.format("imageId(%s/%s) not found", key.getRegion(), key.getName()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -25,7 +25,7 @@ import static com.google.common.base.Preconditions.checkState;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.compute.options.TemplateOptions;
|
import org.jclouds.compute.options.TemplateOptions;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/**
|
||||||
|
* 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.ec2.compute.predicates;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.ec2.EC2Client;
|
||||||
|
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||||
|
import org.jclouds.ec2.domain.SecurityGroup;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class SecurityGroupPresent implements Predicate<RegionAndName> {
|
||||||
|
|
||||||
|
private final EC2Client client;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SecurityGroupPresent(EC2Client client) {
|
||||||
|
this.client = checkNotNull(client, "client");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean apply(RegionAndName securityGroup) {
|
||||||
|
logger.trace("looking for security group %s/%s", securityGroup.getRegion(), securityGroup.getName());
|
||||||
|
try {
|
||||||
|
return refresh(securityGroup) != null;
|
||||||
|
} catch (ResourceNotFoundException e) {
|
||||||
|
return false;
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SecurityGroup refresh(RegionAndName securityGroup) {
|
||||||
|
return Iterables.getOnlyElement(client.getSecurityGroupServices().describeSecurityGroupsInRegion(
|
||||||
|
securityGroup.getRegion(), securityGroup.getName()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,12 +18,12 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.ec2.compute.strategy;
|
package org.jclouds.ec2.compute.strategy;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Provider;
|
import javax.inject.Provider;
|
||||||
|
@ -37,11 +37,13 @@ import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||||
import org.jclouds.ec2.domain.BlockDeviceMapping;
|
import org.jclouds.ec2.domain.BlockDeviceMapping;
|
||||||
import org.jclouds.ec2.domain.KeyPair;
|
import org.jclouds.ec2.domain.KeyPair;
|
||||||
import org.jclouds.ec2.options.RunInstancesOptions;
|
import org.jclouds.ec2.options.RunInstancesOptions;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.ImmutableSet.Builder;
|
import com.google.common.collect.ImmutableSet.Builder;
|
||||||
|
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -49,27 +51,22 @@ import com.google.common.collect.ImmutableSet.Builder;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions {
|
public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions {
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public final Map<RegionAndName, KeyPair> credentialsMap;
|
public final Map<RegionAndName, KeyPair> knownKeys;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public final Map<RegionAndName, String> securityGroupMap;
|
public final Cache<RegionAndName, KeyPair> credentialsMap;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public final Function<RegionAndName, KeyPair> createUniqueKeyPair;
|
public final Cache<RegionAndName, String> securityGroupMap;
|
||||||
@VisibleForTesting
|
|
||||||
public final Function<RegionNameAndIngressRules, String> createSecurityGroupIfNeeded;
|
|
||||||
protected final Provider<RunInstancesOptions> optionsProvider;
|
protected final Provider<RunInstancesOptions> optionsProvider;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions(Map<RegionAndName, KeyPair> credentialsMap,
|
public CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions(Map<RegionAndName, KeyPair> knownKeys, Cache<RegionAndName, KeyPair> credentialsMap,
|
||||||
@Named("SECURITY") Map<RegionAndName, String> securityGroupMap, Function<RegionAndName, KeyPair> createUniqueKeyPair,
|
@Named("SECURITY") Cache<RegionAndName, String> securityGroupMap,
|
||||||
Function<RegionNameAndIngressRules, String> createSecurityGroupIfNeeded,
|
|
||||||
Provider<RunInstancesOptions> optionsProvider) {
|
Provider<RunInstancesOptions> optionsProvider) {
|
||||||
this.credentialsMap = credentialsMap;
|
this.knownKeys = checkNotNull(knownKeys, "knownKeys");
|
||||||
this.securityGroupMap = securityGroupMap;
|
this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap");
|
||||||
this.createUniqueKeyPair = createUniqueKeyPair;
|
this.securityGroupMap = checkNotNull(securityGroupMap, "securityGroupMap");
|
||||||
this.createSecurityGroupIfNeeded = createSecurityGroupIfNeeded;
|
this.optionsProvider = checkNotNull(optionsProvider, "optionsProvider");
|
||||||
this.optionsProvider = optionsProvider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RunInstancesOptions execute(String region, String group, Template template) {
|
public RunInstancesOptions execute(String region, String group, Template template) {
|
||||||
|
@ -109,36 +106,46 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions {
|
||||||
public String createNewKeyPairUnlessUserSpecifiedOtherwise(String region, String group, TemplateOptions options) {
|
public String createNewKeyPairUnlessUserSpecifiedOtherwise(String region, String group, TemplateOptions options) {
|
||||||
String keyPairName = null;
|
String keyPairName = null;
|
||||||
boolean shouldAutomaticallyCreateKeyPair = true;
|
boolean shouldAutomaticallyCreateKeyPair = true;
|
||||||
|
|
||||||
if (options instanceof EC2TemplateOptions) {
|
if (options instanceof EC2TemplateOptions) {
|
||||||
keyPairName = EC2TemplateOptions.class.cast(options).getKeyPair();
|
keyPairName = EC2TemplateOptions.class.cast(options).getKeyPair();
|
||||||
if (keyPairName == null)
|
if (keyPairName == null)
|
||||||
shouldAutomaticallyCreateKeyPair = EC2TemplateOptions.class.cast(options)
|
shouldAutomaticallyCreateKeyPair = EC2TemplateOptions.class.cast(options)
|
||||||
.shouldAutomaticallyCreateKeyPair();
|
.shouldAutomaticallyCreateKeyPair();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyPairName == null && shouldAutomaticallyCreateKeyPair) {
|
if (keyPairName == null && shouldAutomaticallyCreateKeyPair) {
|
||||||
keyPairName = createOrImportKeyPair(region, group, options);
|
keyPairName = createOrImportKeyPair(region, group, options);
|
||||||
|
} else if (keyPairName != null) {
|
||||||
|
if (options.getOverridingCredentials() != null && options.getOverridingCredentials().credential != null) {
|
||||||
|
KeyPair keyPair = KeyPair.builder().region(region).keyName(keyPairName).keyFingerprint("//TODO")
|
||||||
|
.keyMaterial(options.getOverridingCredentials().credential).build();
|
||||||
|
|
||||||
|
RegionAndName key = new RegionAndName(region, keyPairName);
|
||||||
|
knownKeys.put(key, keyPair);
|
||||||
|
credentialsMap.invalidate(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.getRunScript() != null) {
|
||||||
|
RegionAndName regionAndName = new RegionAndName(region, keyPairName);
|
||||||
|
String message = String.format("no private key configured for: %s; please use options.overrideLoginCredentialWith(rsa_private_text)",
|
||||||
|
regionAndName);
|
||||||
|
// test to see if this is in cache.
|
||||||
|
try {
|
||||||
|
credentialsMap.getUnchecked(regionAndName);
|
||||||
|
} catch (NullPointerException nex) {
|
||||||
|
throw new IllegalArgumentException(message, nex);
|
||||||
|
} catch (UncheckedExecutionException nex) {
|
||||||
|
throw new IllegalArgumentException(message, nex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return keyPairName;
|
return keyPairName;
|
||||||
}
|
}
|
||||||
|
|
||||||
// base EC2 driver currently does not support key import
|
// base EC2 driver currently does not support key import
|
||||||
protected String createOrImportKeyPair(String region, String group, TemplateOptions options) {
|
protected String createOrImportKeyPair(String region, String group, TemplateOptions options) {
|
||||||
return createUniqueKeyPairAndPutIntoMap(region, group);
|
return credentialsMap.getUnchecked(new RegionAndName(region, group)).getKeyName();
|
||||||
}
|
|
||||||
|
|
||||||
protected String createUniqueKeyPairAndPutIntoMap(String region, String group) {
|
|
||||||
String keyPairName;
|
|
||||||
RegionAndName regionAndName = new RegionAndName(region, group);
|
|
||||||
KeyPair keyPair = createUniqueKeyPair.apply(regionAndName);
|
|
||||||
keyPairName = keyPair.getKeyName();
|
|
||||||
// get or create incidental resources
|
|
||||||
// TODO race condition. we were using MapMaker, but it doesn't seem to
|
|
||||||
// refresh properly
|
|
||||||
// when
|
|
||||||
// another thread
|
|
||||||
// deletes a key
|
|
||||||
credentialsMap.put(new RegionAndName(regionAndName.getRegion(), keyPairName), keyPair);
|
|
||||||
return keyPairName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@ -159,11 +166,8 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions {
|
||||||
regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup,
|
regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup,
|
||||||
options.getInboundPorts(), true);
|
options.getInboundPorts(), true);
|
||||||
}
|
}
|
||||||
|
// this will create if not yet exists.
|
||||||
if (!securityGroupMap.containsKey(regionNameAndIngessRulesForMarkerGroup)) {
|
securityGroupMap.getUnchecked(regionNameAndIngessRulesForMarkerGroup);
|
||||||
securityGroupMap.put(regionNameAndIngessRulesForMarkerGroup,
|
|
||||||
createSecurityGroupIfNeeded.apply(regionNameAndIngessRulesForMarkerGroup));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return groups.build();
|
return groups.build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ import org.jclouds.logging.Logger;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
@ -77,7 +78,7 @@ public class EC2CreateNodesInGroupThenAddToSet implements CreateNodesInGroupThen
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final ComputeUtils utils;
|
final ComputeUtils utils;
|
||||||
final InstancePresent instancePresent;
|
final InstancePresent instancePresent;
|
||||||
final Function<RunningInstance, Credentials> instanceToCredentials;
|
final Cache<RunningInstance, Credentials> instanceToCredentials;
|
||||||
final Map<String, Credentials> credentialStore;
|
final Map<String, Credentials> credentialStore;
|
||||||
final Provider<TemplateBuilder> templateBuilderProvider;
|
final Provider<TemplateBuilder> templateBuilderProvider;
|
||||||
|
|
||||||
|
@ -87,7 +88,7 @@ public class EC2CreateNodesInGroupThenAddToSet implements CreateNodesInGroupThen
|
||||||
Provider<TemplateBuilder> templateBuilderProvider,
|
Provider<TemplateBuilder> templateBuilderProvider,
|
||||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize,
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize,
|
||||||
InstancePresent instancePresent, Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata,
|
InstancePresent instancePresent, Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata,
|
||||||
Function<RunningInstance, Credentials> instanceToCredentials, Map<String, Credentials> credentialStore,
|
Cache<RunningInstance, Credentials> instanceToCredentials, Map<String, Credentials> credentialStore,
|
||||||
ComputeUtils utils) {
|
ComputeUtils utils) {
|
||||||
this.client = checkNotNull(client, "client");
|
this.client = checkNotNull(client, "client");
|
||||||
this.templateBuilderProvider = checkNotNull(templateBuilderProvider, "templateBuilderProvider");
|
this.templateBuilderProvider = checkNotNull(templateBuilderProvider, "templateBuilderProvider");
|
||||||
|
|
|
@ -18,16 +18,16 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.ec2.compute.suppliers;
|
package org.jclouds.ec2.compute.suppliers;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,16 +36,16 @@ import com.google.common.collect.Sets;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class EC2ImageSupplier implements Supplier<Set<? extends Image>> {
|
public class EC2ImageSupplier implements Supplier<Set<? extends Image>> {
|
||||||
private final Supplier<Map<RegionAndName, ? extends Image>> map;
|
private final Supplier<Cache<RegionAndName, ? extends Image>> map;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
EC2ImageSupplier(Supplier<Map<RegionAndName, ? extends Image>> map) {
|
EC2ImageSupplier(Supplier<Cache<RegionAndName, ? extends Image>> map) {
|
||||||
this.map = map;
|
this.map = map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends Image> get() {
|
public Set<? extends Image> get() {
|
||||||
return Sets.newLinkedHashSet(map.get().values());
|
return Sets.newLinkedHashSet(map.get().asMap().values());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,8 @@ import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.ownedBy;
|
||||||
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
|
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
@ -45,16 +45,19 @@ import org.jclouds.logging.Logger;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.collect.ImmutableMap.Builder;
|
import com.google.common.collect.ImmutableMap.Builder;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class RegionAndNameToImageSupplier implements Supplier<Map<RegionAndName, ? extends Image>> {
|
public class RegionAndNameToImageSupplier implements Supplier<Cache<RegionAndName, ? extends Image>> {
|
||||||
@Resource
|
@Resource
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
@ -63,20 +66,23 @@ public class RegionAndNameToImageSupplier implements Supplier<Map<RegionAndName,
|
||||||
private final DescribeImagesParallel describer;
|
private final DescribeImagesParallel describer;
|
||||||
private final String[] amiOwners;
|
private final String[] amiOwners;
|
||||||
private final EC2ImageParser parser;
|
private final EC2ImageParser parser;
|
||||||
private final Map<RegionAndName, Image> images;
|
private final Map<RegionAndName, Image> knownImages;
|
||||||
|
private final CacheLoader<RegionAndName, Image> regionAndIdToImage;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected RegionAndNameToImageSupplier(@Region Set<String> regions, DescribeImagesParallel describer,
|
protected RegionAndNameToImageSupplier(@Region Set<String> regions, DescribeImagesParallel describer,
|
||||||
@Named(PROPERTY_EC2_AMI_OWNERS) String[] amiOwners, EC2ImageParser parser, Map<RegionAndName, Image> images) {
|
@Named(PROPERTY_EC2_AMI_OWNERS) String[] amiOwners, EC2ImageParser parser,
|
||||||
|
Map<RegionAndName, Image> knownImages, CacheLoader<RegionAndName, Image> regionAndIdToImage) {
|
||||||
this.regions = regions;
|
this.regions = regions;
|
||||||
this.describer = describer;
|
this.describer = describer;
|
||||||
this.amiOwners = amiOwners;
|
this.amiOwners = amiOwners;
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
this.images = images;
|
this.knownImages = knownImages;
|
||||||
|
this.regionAndIdToImage = regionAndIdToImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<RegionAndName, ? extends Image> get() {
|
public Cache<RegionAndName, ? extends Image> get() {
|
||||||
if (amiOwners.length == 0) {
|
if (amiOwners.length == 0) {
|
||||||
logger.debug(">> no owners specified, skipping image parsing");
|
logger.debug(">> no owners specified, skipping image parsing");
|
||||||
} else {
|
} else {
|
||||||
|
@ -87,8 +93,8 @@ public class RegionAndNameToImageSupplier implements Supplier<Map<RegionAndName,
|
||||||
|
|
||||||
Iterable<? extends Image> parsedImages = ImmutableSet.copyOf(filter(transform(describer.apply(queries), parser), Predicates
|
Iterable<? extends Image> parsedImages = ImmutableSet.copyOf(filter(transform(describer.apply(queries), parser), Predicates
|
||||||
.notNull()));
|
.notNull()));
|
||||||
|
knownImages.clear();
|
||||||
images.putAll(uniqueIndex(parsedImages, new Function<Image, RegionAndName>() {
|
knownImages.putAll(uniqueIndex(parsedImages, new Function<Image, RegionAndName>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RegionAndName apply(Image from) {
|
public RegionAndName apply(Image from) {
|
||||||
|
@ -96,10 +102,14 @@ public class RegionAndNameToImageSupplier implements Supplier<Map<RegionAndName,
|
||||||
}
|
}
|
||||||
|
|
||||||
}));
|
}));
|
||||||
|
logger.debug("<< images(%d)", knownImages.size());
|
||||||
logger.debug("<< images(%d)", images.size());
|
|
||||||
}
|
}
|
||||||
return images;
|
Cache<RegionAndName, Image> cache = CacheBuilder.newBuilder().build(regionAndIdToImage);
|
||||||
|
// seed the cache
|
||||||
|
for (RegionAndName image : knownImages.keySet()) {
|
||||||
|
cache.getUnchecked(image);
|
||||||
|
}
|
||||||
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterable<Entry<String, DescribeImagesOptions>> getDescribeQueriesForOwnersInRegions(Set<String> regions,
|
public Iterable<Entry<String, DescribeImagesOptions>> getDescribeQueriesForOwnersInRegions(Set<String> regions,
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
@ -48,9 +49,11 @@ import org.jclouds.ec2.services.SecurityGroupAsyncClient;
|
||||||
import org.jclouds.ec2.services.SecurityGroupClient;
|
import org.jclouds.ec2.services.SecurityGroupClient;
|
||||||
import org.jclouds.ec2.services.WindowsAsyncClient;
|
import org.jclouds.ec2.services.WindowsAsyncClient;
|
||||||
import org.jclouds.ec2.services.WindowsClient;
|
import org.jclouds.ec2.services.WindowsClient;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.http.RequiresHttp;
|
import org.jclouds.http.RequiresHttp;
|
||||||
import org.jclouds.location.Region;
|
import org.jclouds.location.Region;
|
||||||
import org.jclouds.location.Zone;
|
import org.jclouds.location.Zone;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.rest.ConfiguresRestClient;
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
|
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
|
@ -67,7 +70,7 @@ import com.google.inject.name.Names;
|
||||||
/**
|
/**
|
||||||
* Configures the EC2 connection.
|
* Configures the EC2 connection.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole (EDIT: Nick Terry nterry@familysearch.org)
|
||||||
*/
|
*/
|
||||||
@RequiresHttp
|
@RequiresHttp
|
||||||
@ConfiguresRestClient
|
@ConfiguresRestClient
|
||||||
|
@ -134,6 +137,9 @@ public class EC2RestClientModule<S extends EC2Client, A extends EC2AsyncClient>
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class RegionIdToZoneId implements javax.inject.Provider<Map<String, String>> {
|
public static class RegionIdToZoneId implements javax.inject.Provider<Map<String, String>> {
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
private final AvailabilityZoneAndRegionClient client;
|
private final AvailabilityZoneAndRegionClient client;
|
||||||
private final Map<String, URI> regions;
|
private final Map<String, URI> regions;
|
||||||
|
|
||||||
|
@ -147,13 +153,27 @@ public class EC2RestClientModule<S extends EC2Client, A extends EC2AsyncClient>
|
||||||
@Zone
|
@Zone
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> get() {
|
public Map<String, String> get() {
|
||||||
Builder<String, String> map = ImmutableMap.<String, String> builder();
|
Builder<String, String> map = ImmutableMap.builder();
|
||||||
|
HttpResponseException exception = null;
|
||||||
for (Entry<String, URI> region : regions.entrySet()) {
|
for (Entry<String, URI> region : regions.entrySet()) {
|
||||||
|
try {
|
||||||
for (AvailabilityZoneInfo zoneInfo : client.describeAvailabilityZonesInRegion(region.getKey())) {
|
for (AvailabilityZoneInfo zoneInfo : client.describeAvailabilityZonesInRegion(region.getKey())) {
|
||||||
map.put(zoneInfo.getZone(), region.getKey());
|
map.put(zoneInfo.getZone(), region.getKey());
|
||||||
}
|
}
|
||||||
|
} catch (HttpResponseException e) {
|
||||||
|
if (e.getMessage().contains("Unable to tunnel through proxy")) {
|
||||||
|
exception = e;
|
||||||
|
logger.error(e, "Could not describe availability zones in Region: %s", region.getKey());
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
return map.build();
|
}
|
||||||
|
}
|
||||||
|
ImmutableMap<String, String> result = map.build();
|
||||||
|
if (result.isEmpty() && exception != null) {
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ package org.jclouds.ec2.domain;
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.util.Preconditions2;
|
import org.jclouds.util.Preconditions2;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ package org.jclouds.ec2.domain;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -22,7 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -23,7 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
|
@ -20,7 +20,7 @@ package org.jclouds.ec2.domain;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -20,7 +20,7 @@ package org.jclouds.ec2.domain;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -23,7 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
|
@ -24,7 +24,7 @@ import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.ec2.domain;
|
package org.jclouds.ec2.domain;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -37,6 +37,12 @@ public class UserIdGroupPair implements Comparable<UserIdGroupPair> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[userId=" + userId + ", groupName=" + groupName + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -23,7 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.base.CaseFormat;
|
import com.google.common.base.CaseFormat;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
|
@ -21,7 +21,7 @@ package org.jclouds.ec2.options;
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.ec2.domain.Image.Architecture;
|
import org.jclouds.ec2.domain.Image.Architecture;
|
||||||
|
|
||||||
|
|
|
@ -32,4 +32,9 @@ public interface EC2Constants {
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_EC2_AMI_OWNERS = "jclouds.ec2.ami-owners";
|
public static final String PROPERTY_EC2_AMI_OWNERS = "jclouds.ec2.ami-owners";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Eventual consistency delay for retrieving a security group after it is created (in ms)
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_EC2_TIMEOUT_SECURITYGROUP_PRESENT = "jclouds.ec2.timeout.securitygroup-present";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ import static org.jclouds.aws.reference.FormParameters.VERSION;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import javax.ws.rs.FormParam;
|
import javax.ws.rs.FormParam;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
|
|
@ -22,7 +22,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.concurrent.Timeout;
|
import org.jclouds.concurrent.Timeout;
|
||||||
import org.jclouds.ec2.domain.Image;
|
import org.jclouds.ec2.domain.Image;
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.ec2.domain.AvailabilityZoneInfo;
|
import org.jclouds.ec2.domain.AvailabilityZoneInfo;
|
||||||
import org.jclouds.ec2.options.DescribeAvailabilityZonesOptions;
|
import org.jclouds.ec2.options.DescribeAvailabilityZonesOptions;
|
||||||
|
|
|
@ -23,7 +23,7 @@ import static org.jclouds.aws.reference.FormParameters.VERSION;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import javax.ws.rs.FormParam;
|
import javax.ws.rs.FormParam;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
|
|
@ -21,7 +21,7 @@ package org.jclouds.ec2.services;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.ec2.domain.Attachment;
|
import org.jclouds.ec2.domain.Attachment;
|
||||||
import org.jclouds.ec2.domain.Permission;
|
import org.jclouds.ec2.domain.Permission;
|
||||||
|
|
|
@ -23,7 +23,7 @@ import static org.jclouds.aws.reference.FormParameters.VERSION;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import javax.ws.rs.FormParam;
|
import javax.ws.rs.FormParam;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
|
|
@ -21,7 +21,7 @@ package org.jclouds.ec2.services;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.aws.AWSResponseException;
|
import org.jclouds.aws.AWSResponseException;
|
||||||
import org.jclouds.concurrent.Timeout;
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
|
|
@ -24,7 +24,7 @@ import static org.jclouds.aws.reference.FormParameters.VERSION;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import javax.ws.rs.FormParam;
|
import javax.ws.rs.FormParam;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
|
|
@ -22,7 +22,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.concurrent.Timeout;
|
import org.jclouds.concurrent.Timeout;
|
||||||
import org.jclouds.ec2.domain.BlockDevice;
|
import org.jclouds.ec2.domain.BlockDevice;
|
||||||
|
|
|
@ -23,7 +23,7 @@ import static org.jclouds.aws.reference.FormParameters.VERSION;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import javax.ws.rs.FormParam;
|
import javax.ws.rs.FormParam;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
|
|
@ -21,7 +21,7 @@ package org.jclouds.ec2.services;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.ec2.domain.KeyPair;
|
import org.jclouds.ec2.domain.KeyPair;
|
||||||
import org.jclouds.concurrent.Timeout;
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
|
|
@ -23,7 +23,7 @@ import static org.jclouds.aws.reference.FormParameters.VERSION;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import javax.ws.rs.FormParam;
|
import javax.ws.rs.FormParam;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
@ -93,7 +93,7 @@ public interface SecurityGroupAsyncClient {
|
||||||
@BinderParam(BindGroupNamesToIndexedFormParams.class) String... securityGroupNames);
|
@BinderParam(BindGroupNamesToIndexedFormParams.class) String... securityGroupNames);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SecurityGroupClient#authorizeSecurityGroupIngressInRegion(@Nullable Region,
|
* @see SecurityGroupClient#authorizeSecurityGroupIngressInRegion(@ org.jclouds.javax.annotation.Nullable Region,
|
||||||
* String,UserIdGroupPair)
|
* String,UserIdGroupPair)
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
|
@ -105,7 +105,7 @@ public interface SecurityGroupAsyncClient {
|
||||||
@BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup);
|
@BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SecurityGroupClient#authorizeSecurityGroupIngressInRegion(@Nullable Region,
|
* @see SecurityGroupClient#authorizeSecurityGroupIngressInRegion(@ org.jclouds.javax.annotation.Nullable Region,
|
||||||
* String,IpProtocol,int,int,String)
|
* String,IpProtocol,int,int,String)
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
|
@ -129,7 +129,7 @@ public interface SecurityGroupAsyncClient {
|
||||||
@BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup);
|
@BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SecurityGroupClient#revokeSecurityGroupIngressInRegion(@Nullable Region,
|
* @see SecurityGroupClient#revokeSecurityGroupIngressInRegion(@ org.jclouds.javax.annotation.Nullable Region,
|
||||||
* String,IpProtocol,int,int,String)
|
* String,IpProtocol,int,int,String)
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
|
|
|
@ -21,7 +21,7 @@ package org.jclouds.ec2.services;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.ec2.domain.IpProtocol;
|
import org.jclouds.ec2.domain.IpProtocol;
|
||||||
import org.jclouds.ec2.domain.SecurityGroup;
|
import org.jclouds.ec2.domain.SecurityGroup;
|
||||||
|
|
|
@ -23,7 +23,7 @@ import static org.jclouds.aws.reference.FormParameters.VERSION;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import javax.ws.rs.FormParam;
|
import javax.ws.rs.FormParam;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
|
|
@ -21,7 +21,7 @@ package org.jclouds.ec2.services;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.ec2.domain.BundleTask;
|
import org.jclouds.ec2.domain.BundleTask;
|
||||||
import org.jclouds.ec2.options.BundleInstanceS3StorageOptions;
|
import org.jclouds.ec2.options.BundleInstanceS3StorageOptions;
|
||||||
|
|
|
@ -47,6 +47,7 @@ import org.jclouds.ec2.services.ElasticBlockStoreClient;
|
||||||
import org.jclouds.ec2.services.InstanceClient;
|
import org.jclouds.ec2.services.InstanceClient;
|
||||||
import org.jclouds.ec2.services.KeyPairClient;
|
import org.jclouds.ec2.services.KeyPairClient;
|
||||||
import org.jclouds.ec2.services.SecurityGroupClient;
|
import org.jclouds.ec2.services.SecurityGroupClient;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statements;
|
||||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -97,7 +98,6 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
TemplateOptions options = client.templateOptions();
|
TemplateOptions options = client.templateOptions();
|
||||||
|
|
||||||
options.as(EC2TemplateOptions.class).securityGroups(group);
|
options.as(EC2TemplateOptions.class).securityGroups(group);
|
||||||
options.as(EC2TemplateOptions.class).keyPair(group);
|
|
||||||
|
|
||||||
String startedId = null;
|
String startedId = null;
|
||||||
try {
|
try {
|
||||||
|
@ -110,6 +110,14 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
|
|
||||||
// create a keypair to pass in as well
|
// create a keypair to pass in as well
|
||||||
KeyPair result = keyPairClient.createKeyPairInRegion(null, group);
|
KeyPair result = keyPairClient.createKeyPairInRegion(null, group);
|
||||||
|
options.as(EC2TemplateOptions.class).keyPair(result.getKeyName());
|
||||||
|
|
||||||
|
// pass in the private key, so that we can run a script with it
|
||||||
|
assert result.getKeyMaterial() != null : result;
|
||||||
|
options.overrideLoginCredentialWith(result.getKeyMaterial());
|
||||||
|
|
||||||
|
// an arbitrary command to run
|
||||||
|
options.runScript(Statements.exec("find /usr"));
|
||||||
|
|
||||||
Set<? extends NodeMetadata> nodes = client.createNodesInGroup(group, 1, options);
|
Set<? extends NodeMetadata> nodes = client.createNodesInGroup(group, 1, options);
|
||||||
NodeMetadata first = Iterables.get(nodes, 0);
|
NodeMetadata first = Iterables.get(nodes, 0);
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
/**
|
||||||
|
* 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.ec2.compute.functions;
|
||||||
|
|
||||||
|
import static org.easymock.EasyMock.expect;
|
||||||
|
import static org.easymock.EasyMock.expectLastCall;
|
||||||
|
import static org.easymock.classextension.EasyMock.createMock;
|
||||||
|
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||||
|
import static org.easymock.classextension.EasyMock.replay;
|
||||||
|
import static org.easymock.classextension.EasyMock.verify;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||||
|
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||||
|
import org.jclouds.ec2.domain.IpProtocol;
|
||||||
|
import org.jclouds.ec2.domain.SecurityGroup;
|
||||||
|
import org.jclouds.ec2.domain.UserIdGroupPair;
|
||||||
|
import org.jclouds.ec2.services.SecurityGroupClient;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", singleThreaded = true, testName = "CreateSecurityGroupIfNeeded")
|
||||||
|
public class CreateSecurityGroupIfNeededTest {
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test
|
||||||
|
public void testWhenPort22AndToItselfAuthorizesIngressTwice() throws ExecutionException {
|
||||||
|
|
||||||
|
SecurityGroupClient client = createMock(SecurityGroupClient.class);
|
||||||
|
Predicate<RegionAndName> tester = Predicates.alwaysTrue();
|
||||||
|
|
||||||
|
SecurityGroup group = createNiceMock(SecurityGroup.class);
|
||||||
|
Set<SecurityGroup> groups = ImmutableSet.<SecurityGroup> of(group);
|
||||||
|
|
||||||
|
client.createSecurityGroupInRegion("region", "group", "group");
|
||||||
|
client.authorizeSecurityGroupIngressInRegion("region", "group", IpProtocol.TCP, 22, 22, "0.0.0.0/0");
|
||||||
|
expect(client.describeSecurityGroupsInRegion("region", "group")).andReturn(Set.class.cast(groups));
|
||||||
|
expect(group.getOwnerId()).andReturn("ownerId");
|
||||||
|
client.authorizeSecurityGroupIngressInRegion("region", "group", new UserIdGroupPair("ownerId", "group"));
|
||||||
|
|
||||||
|
replay(client);
|
||||||
|
replay(group);
|
||||||
|
|
||||||
|
CreateSecurityGroupIfNeeded function = new CreateSecurityGroupIfNeeded(client, tester);
|
||||||
|
|
||||||
|
assertEquals("group", function.load(new RegionNameAndIngressRules("region", "group", new int[] { 22 }, true)));
|
||||||
|
|
||||||
|
verify(client);
|
||||||
|
verify(group);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIllegalStateExceptionCreatingGroupJustReturns() throws ExecutionException {
|
||||||
|
|
||||||
|
SecurityGroupClient client = createMock(SecurityGroupClient.class);
|
||||||
|
Predicate<RegionAndName> tester = Predicates.alwaysTrue();
|
||||||
|
|
||||||
|
client.createSecurityGroupInRegion("region", "group", "group");
|
||||||
|
expectLastCall().andThrow(new IllegalStateException());
|
||||||
|
|
||||||
|
replay(client);
|
||||||
|
|
||||||
|
CreateSecurityGroupIfNeeded function = new CreateSecurityGroupIfNeeded(client, tester);
|
||||||
|
|
||||||
|
assertEquals("group", function.load(new RegionNameAndIngressRules("region", "group", new int[] { 22 }, true)));
|
||||||
|
|
||||||
|
verify(client);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = RuntimeException.class)
|
||||||
|
public void testWhenEventualConsistencyExpiresIllegalStateException() throws ExecutionException {
|
||||||
|
|
||||||
|
SecurityGroupClient client = createMock(SecurityGroupClient.class);
|
||||||
|
Predicate<RegionAndName> tester = Predicates.alwaysFalse();
|
||||||
|
|
||||||
|
client.createSecurityGroupInRegion("region", "group", "group");
|
||||||
|
|
||||||
|
replay(client);
|
||||||
|
|
||||||
|
CreateSecurityGroupIfNeeded function = new CreateSecurityGroupIfNeeded(client, tester);
|
||||||
|
function.load(new RegionNameAndIngressRules("region", "group", new int[] { 22 }, true));
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,8 +25,10 @@ import static org.easymock.classextension.EasyMock.verify;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jclouds.ec2.EC2Client;
|
import org.jclouds.ec2.EC2Client;
|
||||||
|
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||||
import org.jclouds.ec2.domain.KeyPair;
|
import org.jclouds.ec2.domain.KeyPair;
|
||||||
import org.jclouds.ec2.services.KeyPairClient;
|
import org.jclouds.ec2.services.KeyPairClient;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -44,23 +46,26 @@ public class CreateUniqueKeyPairTest {
|
||||||
EC2Client client = createMock(EC2Client.class);
|
EC2Client client = createMock(EC2Client.class);
|
||||||
KeyPairClient keyClient = createMock(KeyPairClient.class);
|
KeyPairClient keyClient = createMock(KeyPairClient.class);
|
||||||
Supplier<String> uniqueIdSupplier = createMock(Supplier.class);
|
Supplier<String> uniqueIdSupplier = createMock(Supplier.class);
|
||||||
|
Map<RegionAndName, KeyPair> knownKeys = createMock(Map.class);
|
||||||
|
|
||||||
KeyPair pair = createMock(KeyPair.class);
|
KeyPair pair = createMock(KeyPair.class);
|
||||||
|
|
||||||
expect(client.getKeyPairServices()).andReturn(keyClient).atLeastOnce();
|
expect(client.getKeyPairServices()).andReturn(keyClient).atLeastOnce();
|
||||||
|
|
||||||
expect(uniqueIdSupplier.get()).andReturn("1");
|
expect(uniqueIdSupplier.get()).andReturn("1");
|
||||||
expect(keyClient.createKeyPairInRegion("region", "jclouds#tag#region#1")).andReturn(pair);
|
expect(keyClient.createKeyPairInRegion("region", "jclouds#group#region#1")).andReturn(pair);
|
||||||
|
|
||||||
replay(client);
|
replay(client);
|
||||||
|
replay(knownKeys);
|
||||||
replay(keyClient);
|
replay(keyClient);
|
||||||
replay(uniqueIdSupplier);
|
replay(uniqueIdSupplier);
|
||||||
|
|
||||||
CreateUniqueKeyPair parser = new CreateUniqueKeyPair(client, uniqueIdSupplier);
|
CreateUniqueKeyPair parser = new CreateUniqueKeyPair(knownKeys, client, uniqueIdSupplier);
|
||||||
|
|
||||||
assertEquals(parser.createNewKeyPairInRegion("region", "tag"), pair);
|
assertEquals(parser.createNewKeyPairInRegion("region", "group"), pair);
|
||||||
|
|
||||||
verify(client);
|
verify(client);
|
||||||
|
verify(knownKeys);
|
||||||
verify(keyClient);
|
verify(keyClient);
|
||||||
verify(uniqueIdSupplier);
|
verify(uniqueIdSupplier);
|
||||||
}
|
}
|
||||||
|
@ -71,25 +76,97 @@ public class CreateUniqueKeyPairTest {
|
||||||
EC2Client client = createMock(EC2Client.class);
|
EC2Client client = createMock(EC2Client.class);
|
||||||
KeyPairClient keyClient = createMock(KeyPairClient.class);
|
KeyPairClient keyClient = createMock(KeyPairClient.class);
|
||||||
Supplier<String> uniqueIdSupplier = createMock(Supplier.class);
|
Supplier<String> uniqueIdSupplier = createMock(Supplier.class);
|
||||||
|
Map<RegionAndName, KeyPair> knownKeys = createMock(Map.class);
|
||||||
|
|
||||||
KeyPair pair = createMock(KeyPair.class);
|
KeyPair pair = createMock(KeyPair.class);
|
||||||
|
|
||||||
expect(client.getKeyPairServices()).andReturn(keyClient).atLeastOnce();
|
expect(client.getKeyPairServices()).andReturn(keyClient).atLeastOnce();
|
||||||
|
|
||||||
expect(uniqueIdSupplier.get()).andReturn("1");
|
expect(uniqueIdSupplier.get()).andReturn("1");
|
||||||
expect(keyClient.createKeyPairInRegion("region", "jclouds#tag#region#1")).andThrow(new IllegalStateException());
|
expect(keyClient.createKeyPairInRegion("region", "jclouds#group#region#1")).andThrow(new IllegalStateException());
|
||||||
expect(uniqueIdSupplier.get()).andReturn("2");
|
expect(uniqueIdSupplier.get()).andReturn("2");
|
||||||
expect(keyClient.createKeyPairInRegion("region", "jclouds#tag#region#2")).andReturn(pair);
|
expect(keyClient.createKeyPairInRegion("region", "jclouds#group#region#2")).andReturn(pair);
|
||||||
|
|
||||||
replay(client);
|
replay(client);
|
||||||
|
replay(knownKeys);
|
||||||
replay(keyClient);
|
replay(keyClient);
|
||||||
replay(uniqueIdSupplier);
|
replay(uniqueIdSupplier);
|
||||||
|
|
||||||
CreateUniqueKeyPair parser = new CreateUniqueKeyPair(client, uniqueIdSupplier);
|
CreateUniqueKeyPair parser = new CreateUniqueKeyPair(knownKeys, client, uniqueIdSupplier);
|
||||||
|
|
||||||
assertEquals(parser.createNewKeyPairInRegion("region", "tag"), pair);
|
assertEquals(parser.createNewKeyPairInRegion("region", "group"), pair);
|
||||||
|
|
||||||
verify(client);
|
verify(client);
|
||||||
|
verify(knownKeys);
|
||||||
|
verify(keyClient);
|
||||||
|
verify(uniqueIdSupplier);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "unchecked" })
|
||||||
|
@Test
|
||||||
|
public void testApplyWhenKnownKeyExists() throws UnknownHostException {
|
||||||
|
EC2Client client = createMock(EC2Client.class);
|
||||||
|
KeyPairClient keyClient = createMock(KeyPairClient.class);
|
||||||
|
Supplier<String> uniqueIdSupplier = createMock(Supplier.class);
|
||||||
|
Map<RegionAndName, KeyPair> knownKeys = createMock(Map.class);
|
||||||
|
|
||||||
|
KeyPair pair = createMock(KeyPair.class);
|
||||||
|
|
||||||
|
expect(knownKeys.containsKey(new RegionAndName("region", "group"))).andReturn(true);
|
||||||
|
expect(knownKeys.get(new RegionAndName("region", "group"))).andReturn(pair);
|
||||||
|
|
||||||
|
replay(client);
|
||||||
|
replay(knownKeys);
|
||||||
|
replay(keyClient);
|
||||||
|
replay(uniqueIdSupplier);
|
||||||
|
|
||||||
|
CreateUniqueKeyPair parser = new CreateUniqueKeyPair(knownKeys, client, uniqueIdSupplier);
|
||||||
|
|
||||||
|
assertEquals(parser.load(new RegionAndName("region", "group")), pair);
|
||||||
|
|
||||||
|
verify(client);
|
||||||
|
verify(knownKeys);
|
||||||
|
verify(keyClient);
|
||||||
|
verify(uniqueIdSupplier);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "unchecked" })
|
||||||
|
@Test
|
||||||
|
public void testApplyWhenKnownKeyDoesntExist() throws UnknownHostException {
|
||||||
|
EC2Client client = createMock(EC2Client.class);
|
||||||
|
KeyPairClient keyClient = createMock(KeyPairClient.class);
|
||||||
|
Supplier<String> uniqueIdSupplier = createMock(Supplier.class);
|
||||||
|
Map<RegionAndName, KeyPair> knownKeys = createMock(Map.class);
|
||||||
|
|
||||||
|
KeyPair pair = createMock(KeyPair.class);
|
||||||
|
|
||||||
|
expect(client.getKeyPairServices()).andReturn(keyClient).atLeastOnce();
|
||||||
|
|
||||||
|
expect(knownKeys.containsKey(new RegionAndName("region", "group"))).andReturn(false);
|
||||||
|
expect(uniqueIdSupplier.get()).andReturn("1");
|
||||||
|
expect(keyClient.createKeyPairInRegion("region", "jclouds#group#region#1")).andThrow(new IllegalStateException());
|
||||||
|
expect(uniqueIdSupplier.get()).andReturn("2");
|
||||||
|
expect(keyClient.createKeyPairInRegion("region", "jclouds#group#region#2")).andReturn(pair);
|
||||||
|
expect(pair.getKeyName()).andReturn("jclouds#group#region#2").times(2);
|
||||||
|
// seeding the cache explicitly. both by keyName and also by group
|
||||||
|
expect(knownKeys.put(new RegionAndName("region", "jclouds#group#region#2"), pair)).andReturn(null);
|
||||||
|
expect(knownKeys.put(new RegionAndName("region", "group"), pair)).andReturn(null);
|
||||||
|
|
||||||
|
replay(pair);
|
||||||
|
replay(client);
|
||||||
|
replay(knownKeys);
|
||||||
|
replay(keyClient);
|
||||||
|
replay(uniqueIdSupplier);
|
||||||
|
|
||||||
|
CreateUniqueKeyPair parser = new CreateUniqueKeyPair(knownKeys, client, uniqueIdSupplier);
|
||||||
|
|
||||||
|
assertEquals(parser.load(new RegionAndName("region", "group")), pair);
|
||||||
|
|
||||||
|
verify(pair);
|
||||||
|
verify(client);
|
||||||
|
verify(knownKeys);
|
||||||
verify(keyClient);
|
verify(keyClient);
|
||||||
verify(uniqueIdSupplier);
|
verify(uniqueIdSupplier);
|
||||||
|
|
||||||
|
|
|
@ -26,13 +26,15 @@ import static org.easymock.classextension.EasyMock.verify;
|
||||||
import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.imageIds;
|
import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.imageIds;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.ec2.EC2Client;
|
import org.jclouds.ec2.EC2Client;
|
||||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||||
import org.jclouds.ec2.services.AMIClient;
|
import org.jclouds.ec2.services.AMIClient;
|
||||||
import org.jclouds.compute.domain.Image;
|
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -46,46 +48,85 @@ public class RegionAndIdToImageTest {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Test
|
@Test
|
||||||
public void testApply() {
|
public void testApply() throws ExecutionException {
|
||||||
|
|
||||||
EC2ImageParser parser = createMock(EC2ImageParser.class);
|
EC2ImageParser parser = createMock(EC2ImageParser.class);
|
||||||
EC2Client caller = createMock(EC2Client.class);
|
EC2Client caller = createMock(EC2Client.class);
|
||||||
AMIClient client = createMock(AMIClient.class);
|
AMIClient client = createMock(AMIClient.class);
|
||||||
|
Map<RegionAndName, Image> knownImages = createMock(Map.class);
|
||||||
|
|
||||||
org.jclouds.ec2.domain.Image ec2Image = createMock(org.jclouds.ec2.domain.Image.class);
|
org.jclouds.ec2.domain.Image ec2Image = createMock(org.jclouds.ec2.domain.Image.class);
|
||||||
Image image = createNiceMock(Image.class);
|
Image image = createNiceMock(Image.class);
|
||||||
Set<? extends org.jclouds.ec2.domain.Image> images = ImmutableSet.<org.jclouds.ec2.domain.Image> of(ec2Image);
|
Set<? extends org.jclouds.ec2.domain.Image> images = ImmutableSet.<org.jclouds.ec2.domain.Image> of(ec2Image);
|
||||||
|
|
||||||
|
expect(knownImages.containsKey(new RegionAndName("region", "ami"))).andReturn(false);
|
||||||
expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
|
expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
|
||||||
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn(Set.class.cast(images));
|
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn(Set.class.cast(images));
|
||||||
expect(parser.apply(ec2Image)).andReturn(image);
|
expect(parser.apply(ec2Image)).andReturn(image);
|
||||||
|
|
||||||
|
replay(knownImages);
|
||||||
replay(caller);
|
replay(caller);
|
||||||
replay(image);
|
replay(image);
|
||||||
replay(parser);
|
replay(parser);
|
||||||
replay(client);
|
replay(client);
|
||||||
|
|
||||||
RegionAndIdToImage function = new RegionAndIdToImage(parser, caller);
|
RegionAndIdToImage function = new RegionAndIdToImage(knownImages, parser, caller);
|
||||||
|
|
||||||
assertEquals(function.apply(new RegionAndName("region", "ami")), image);
|
assertEquals(function.load(new RegionAndName("region", "ami")), image);
|
||||||
|
|
||||||
verify(caller);
|
verify(caller);
|
||||||
verify(image);
|
verify(image);
|
||||||
verify(parser);
|
verify(image);
|
||||||
|
verify(knownImages);
|
||||||
verify(client);
|
verify(client);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Test
|
@Test
|
||||||
public void testApplyNotFound() {
|
public void testApplyWhenFoundDoesntCallClient() throws ExecutionException {
|
||||||
|
|
||||||
EC2ImageParser parser = createMock(EC2ImageParser.class);
|
EC2ImageParser parser = createMock(EC2ImageParser.class);
|
||||||
EC2Client caller = createMock(EC2Client.class);
|
EC2Client caller = createMock(EC2Client.class);
|
||||||
AMIClient client = createMock(AMIClient.class);
|
AMIClient client = createMock(AMIClient.class);
|
||||||
|
Map<RegionAndName, Image> knownImages = createMock(Map.class);
|
||||||
|
|
||||||
|
Image image = createNiceMock(Image.class);
|
||||||
|
|
||||||
|
expect(knownImages.containsKey(new RegionAndName("region", "ami"))).andReturn(true);
|
||||||
|
expect(knownImages.get(new RegionAndName("region", "ami"))).andReturn(image);
|
||||||
|
|
||||||
|
replay(knownImages);
|
||||||
|
replay(caller);
|
||||||
|
replay(image);
|
||||||
|
replay(parser);
|
||||||
|
replay(client);
|
||||||
|
|
||||||
|
RegionAndIdToImage function = new RegionAndIdToImage(knownImages, parser, caller);
|
||||||
|
|
||||||
|
assertEquals(function.load(new RegionAndName("region", "ami")), image);
|
||||||
|
|
||||||
|
verify(caller);
|
||||||
|
verify(image);
|
||||||
|
verify(image);
|
||||||
|
verify(knownImages);
|
||||||
|
verify(client);
|
||||||
|
|
||||||
|
}
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test(expectedExceptions = ExecutionException.class)
|
||||||
|
public void testApplyNotFoundMakesExecutionException() throws ExecutionException {
|
||||||
|
|
||||||
|
EC2ImageParser parser = createMock(EC2ImageParser.class);
|
||||||
|
EC2Client caller = createMock(EC2Client.class);
|
||||||
|
AMIClient client = createMock(AMIClient.class);
|
||||||
|
Map<RegionAndName, Image> knownImages = createMock(Map.class);
|
||||||
|
|
||||||
org.jclouds.ec2.domain.Image ec2Image = createMock(org.jclouds.ec2.domain.Image.class);
|
org.jclouds.ec2.domain.Image ec2Image = createMock(org.jclouds.ec2.domain.Image.class);
|
||||||
Image image = createNiceMock(Image.class);
|
Image image = createNiceMock(Image.class);
|
||||||
Set<? extends org.jclouds.ec2.domain.Image> images = ImmutableSet.<org.jclouds.ec2.domain.Image> of(ec2Image);
|
Set<? extends org.jclouds.ec2.domain.Image> images = ImmutableSet.<org.jclouds.ec2.domain.Image> of(ec2Image);
|
||||||
|
|
||||||
|
expect(knownImages.containsKey(new RegionAndName("region", "ami"))).andReturn(false);
|
||||||
expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
|
expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
|
||||||
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn(Set.class.cast(images));
|
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn(Set.class.cast(images));
|
||||||
expect(parser.apply(ec2Image)).andThrow(new ResourceNotFoundException());
|
expect(parser.apply(ec2Image)).andThrow(new ResourceNotFoundException());
|
||||||
|
@ -93,45 +134,52 @@ public class RegionAndIdToImageTest {
|
||||||
replay(caller);
|
replay(caller);
|
||||||
replay(image);
|
replay(image);
|
||||||
replay(parser);
|
replay(parser);
|
||||||
|
replay(knownImages);
|
||||||
replay(client);
|
replay(client);
|
||||||
|
|
||||||
RegionAndIdToImage function = new RegionAndIdToImage(parser, caller);
|
RegionAndIdToImage function = new RegionAndIdToImage(knownImages, parser, caller);
|
||||||
|
|
||||||
assertEquals(function.apply(new RegionAndName("region", "ami")), null);
|
assertEquals(function.load(new RegionAndName("region", "ami")), null);
|
||||||
|
|
||||||
verify(caller);
|
verify(caller);
|
||||||
verify(image);
|
verify(image);
|
||||||
verify(parser);
|
verify(parser);
|
||||||
|
verify(knownImages);
|
||||||
verify(client);
|
verify(client);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Test
|
@Test(expectedExceptions = ExecutionException.class)
|
||||||
public void testApplyNoSuchElementException() {
|
public void testApplyNoSuchElementExceptionMakesExecutionException() throws ExecutionException {
|
||||||
|
|
||||||
EC2ImageParser parser = createMock(EC2ImageParser.class);
|
EC2ImageParser parser = createMock(EC2ImageParser.class);
|
||||||
EC2Client caller = createMock(EC2Client.class);
|
EC2Client caller = createMock(EC2Client.class);
|
||||||
AMIClient client = createMock(AMIClient.class);
|
AMIClient client = createMock(AMIClient.class);
|
||||||
|
Map<RegionAndName, Image> knownImages = createMock(Map.class);
|
||||||
|
|
||||||
org.jclouds.ec2.domain.Image ec2Image = createMock(org.jclouds.ec2.domain.Image.class);
|
org.jclouds.ec2.domain.Image ec2Image = createMock(org.jclouds.ec2.domain.Image.class);
|
||||||
Image image = createNiceMock(Image.class);
|
Image image = createNiceMock(Image.class);
|
||||||
Set<? extends org.jclouds.ec2.domain.Image> images = ImmutableSet.<org.jclouds.ec2.domain.Image> of(ec2Image);
|
Set<? extends org.jclouds.ec2.domain.Image> images = ImmutableSet.<org.jclouds.ec2.domain.Image> of(ec2Image);
|
||||||
|
|
||||||
|
expect(knownImages.containsKey(new RegionAndName("region", "ami"))).andReturn(false);
|
||||||
expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
|
expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
|
||||||
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn(Set.class.cast(images));
|
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn(Set.class.cast(images));
|
||||||
expect(parser.apply(ec2Image)).andThrow(new NoSuchElementException());
|
expect(parser.apply(ec2Image)).andThrow(new NoSuchElementException());
|
||||||
|
|
||||||
replay(caller);
|
replay(caller);
|
||||||
replay(image);
|
replay(image);
|
||||||
|
replay(knownImages);
|
||||||
replay(parser);
|
replay(parser);
|
||||||
replay(client);
|
replay(client);
|
||||||
|
|
||||||
RegionAndIdToImage function = new RegionAndIdToImage(parser, caller);
|
RegionAndIdToImage function = new RegionAndIdToImage(knownImages, parser, caller);
|
||||||
|
|
||||||
assertEquals(function.apply(new RegionAndName("region", "ami")), null);
|
assertEquals(function.load(new RegionAndName("region", "ami")), null);
|
||||||
|
|
||||||
verify(caller);
|
verify(caller);
|
||||||
verify(image);
|
verify(image);
|
||||||
|
verify(knownImages);
|
||||||
verify(parser);
|
verify(parser);
|
||||||
verify(client);
|
verify(client);
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,6 @@ import java.net.UnknownHostException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
@ -43,14 +41,18 @@ import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||||
import org.jclouds.ec2.domain.InstanceState;
|
import org.jclouds.ec2.domain.InstanceState;
|
||||||
import org.jclouds.ec2.domain.RunningInstance;
|
import org.jclouds.ec2.domain.RunningInstance;
|
||||||
import org.jclouds.ec2.xml.DescribeInstancesResponseHandlerTest;
|
import org.jclouds.ec2.xml.DescribeInstancesResponseHandlerTest;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.MapMaker;
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -167,14 +169,14 @@ public class RunningInstanceToNodeMetadataTest {
|
||||||
// Handle the case when the installed AMI no longer can be found in AWS.
|
// Handle the case when the installed AMI no longer can be found in AWS.
|
||||||
|
|
||||||
// Create a null-returning function to simulate that the AMI can't be found.
|
// Create a null-returning function to simulate that the AMI can't be found.
|
||||||
Function<RegionAndName, Image> nullReturningFunction = new Function<RegionAndName, Image>() {
|
CacheLoader<RegionAndName, Image> nullReturningFunction = new CacheLoader<RegionAndName, Image>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Image apply(@Nullable RegionAndName from) {
|
public Image load(@Nullable RegionAndName from) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Map<RegionAndName, Image> instanceToImage = new MapMaker().makeComputingMap(nullReturningFunction);
|
Cache<RegionAndName, Image> instanceToImage = CacheBuilder.newBuilder().build(nullReturningFunction);
|
||||||
|
|
||||||
RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet.of(m1_small32().build()), ImmutableSet
|
RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet.of(m1_small32().build()), ImmutableSet
|
||||||
.of(provider), ImmutableMap.<String, Credentials> of(),
|
.of(provider), ImmutableMap.<String, Credentials> of(),
|
||||||
|
@ -197,25 +199,31 @@ public class RunningInstanceToNodeMetadataTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RunningInstanceToNodeMetadata createNodeParser(final ImmutableSet<Hardware> hardware,
|
protected RunningInstanceToNodeMetadata createNodeParser(final ImmutableSet<Hardware> hardware,
|
||||||
final ImmutableSet<Location> locations, Set<org.jclouds.compute.domain.Image> images,
|
final ImmutableSet<Location> locations, final Set<org.jclouds.compute.domain.Image> images,
|
||||||
Map<String, Credentials> credentialStore) {
|
Map<String, Credentials> credentialStore) {
|
||||||
Map<InstanceState, NodeState> instanceToNodeState = EC2ComputeServiceDependenciesModule.instanceToNodeState;
|
Map<InstanceState, NodeState> instanceToNodeState = EC2ComputeServiceDependenciesModule.instanceToNodeState;
|
||||||
|
|
||||||
Map<RegionAndName, Image> instanceToImage = Maps.uniqueIndex(images, new Function<Image, RegionAndName>() {
|
CacheLoader<RegionAndName, Image> getRealImage = new CacheLoader<RegionAndName, Image>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Image load(@Nullable RegionAndName from) {
|
||||||
|
return Maps.uniqueIndex(images, new Function<Image, RegionAndName>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RegionAndName apply(Image from) {
|
public RegionAndName apply(Image from) {
|
||||||
return new RegionAndName(from.getLocation().getId(), from.getProviderId());
|
return new RegionAndName(from.getLocation().getId(), from.getProviderId());
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
}).get(from);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Cache<RegionAndName, Image> instanceToImage = CacheBuilder.newBuilder().build(getRealImage);
|
||||||
return createNodeParser(hardware, locations, credentialStore, instanceToNodeState, instanceToImage);
|
return createNodeParser(hardware, locations, credentialStore, instanceToNodeState, instanceToImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RunningInstanceToNodeMetadata createNodeParser(final ImmutableSet<Hardware> hardware,
|
private RunningInstanceToNodeMetadata createNodeParser(final ImmutableSet<Hardware> hardware,
|
||||||
final ImmutableSet<Location> locations, Map<String, Credentials> credentialStore,
|
final ImmutableSet<Location> locations, Map<String, Credentials> credentialStore,
|
||||||
Map<InstanceState, NodeState> instanceToNodeState, Map<RegionAndName, Image> instanceToImage) {
|
Map<InstanceState, NodeState> instanceToNodeState, Cache<RegionAndName, Image> instanceToImage) {
|
||||||
Supplier<Set<? extends Location>> locationSupplier = new Supplier<Set<? extends Location>>() {
|
Supplier<Set<? extends Location>> locationSupplier = new Supplier<Set<? extends Location>>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -233,7 +241,8 @@ public class RunningInstanceToNodeMetadataTest {
|
||||||
|
|
||||||
};
|
};
|
||||||
RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(instanceToNodeState, credentialStore,
|
RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(instanceToNodeState, credentialStore,
|
||||||
instanceToImage, locationSupplier, hardwareSupplier);
|
Suppliers.<Cache<RegionAndName, ? extends Image>> ofInstance(instanceToImage), locationSupplier,
|
||||||
|
hardwareSupplier);
|
||||||
return parser;
|
return parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
|
|
||||||
import javax.inject.Provider;
|
import javax.inject.Provider;
|
||||||
|
|
||||||
|
@ -46,11 +45,12 @@ import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.base.Suppliers;
|
import com.google.common.base.Suppliers;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.MapMaker;
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,17 +72,16 @@ public class EC2TemplateBuilderImplTest extends TemplateBuilderImplTest {
|
||||||
Provider<TemplateOptions> optionsProvider, Provider<TemplateBuilder> templateBuilderProvider) {
|
Provider<TemplateOptions> optionsProvider, Provider<TemplateBuilder> templateBuilderProvider) {
|
||||||
final RegionAndName knownRegionAndName = new RegionAndName("region", "ami");
|
final RegionAndName knownRegionAndName = new RegionAndName("region", "ami");
|
||||||
|
|
||||||
ConcurrentMap<RegionAndName, Image> imageMap = new MapMaker()
|
Cache<RegionAndName, ? extends Image> imageMap = CacheBuilder.newBuilder().build(new CacheLoader<RegionAndName, Image>() {
|
||||||
.makeComputingMap(new Function<RegionAndName, Image>() {
|
|
||||||
@Override
|
@Override
|
||||||
public Image apply(RegionAndName from) {
|
public Image load(RegionAndName from) {
|
||||||
return from.equals(knownRegionAndName) ? knownImage : null;
|
return from.equals(knownRegionAndName) ? knownImage : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return new EC2TemplateBuilderImpl(locations, images, sizes, Suppliers.ofInstance(defaultLocation),
|
return new EC2TemplateBuilderImpl(locations, images, sizes, Suppliers.ofInstance(defaultLocation),
|
||||||
optionsProvider, templateBuilderProvider, imageMap);
|
optionsProvider, templateBuilderProvider, Suppliers.<Cache<RegionAndName, ? extends Image>>ofInstance(imageMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
|
@ -27,6 +27,7 @@ import static org.testng.Assert.assertEquals;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
import javax.inject.Provider;
|
import javax.inject.Provider;
|
||||||
|
|
||||||
|
@ -34,26 +35,26 @@ import org.jclouds.aws.domain.Region;
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.compute.options.TemplateOptions;
|
import org.jclouds.compute.options.TemplateOptions;
|
||||||
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.ec2.compute.domain.EC2HardwareBuilder;
|
import org.jclouds.ec2.compute.domain.EC2HardwareBuilder;
|
||||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||||
import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
|
|
||||||
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
|
|
||||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||||
import org.jclouds.ec2.domain.BlockDeviceMapping;
|
import org.jclouds.ec2.domain.BlockDeviceMapping;
|
||||||
import org.jclouds.ec2.domain.KeyPair;
|
import org.jclouds.ec2.domain.KeyPair;
|
||||||
import org.jclouds.ec2.options.RunInstancesOptions;
|
import org.jclouds.ec2.options.RunInstancesOptions;
|
||||||
import org.jclouds.encryption.internal.Base64;
|
import org.jclouds.encryption.internal.Base64;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statements;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit")
|
@Test(groups = "unit", singleThreaded = true, testName = "CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest")
|
||||||
public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
|
|
||||||
private static final Provider<RunInstancesOptions> OPTIONS_PROVIDER = new javax.inject.Provider<RunInstancesOptions>() {
|
private static final Provider<RunInstancesOptions> OPTIONS_PROVIDER = new javax.inject.Provider<RunInstancesOptions>() {
|
||||||
|
@ -76,15 +77,15 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
|
|
||||||
// create mocks
|
// create mocks
|
||||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock(
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock(
|
||||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] {
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class,
|
||||||
|
new Method[] {
|
||||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||||
.getDeclaredMethod("getOptionsProvider"),
|
.getDeclaredMethod("getOptionsProvider"),
|
||||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||||
"createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class,
|
"createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||||
TemplateOptions.class),
|
TemplateOptions.class),
|
||||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||||
.getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class,
|
"getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) });
|
||||||
TemplateOptions.class) });
|
|
||||||
|
|
||||||
EC2TemplateOptions options = createMock(EC2TemplateOptions.class);
|
EC2TemplateOptions options = createMock(EC2TemplateOptions.class);
|
||||||
Template template = createMock(Template.class);
|
Template template = createMock(Template.class);
|
||||||
|
@ -107,9 +108,10 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
// run
|
// run
|
||||||
RunInstancesOptions customize = strategy.execute(region, tag, template);
|
RunInstancesOptions customize = strategy.execute(region, tag, template);
|
||||||
assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap.<String, String> of("InstanceType",
|
assertEquals(
|
||||||
size.getProviderId(), "SecurityGroup.1", generatedGroup, "KeyName", systemGeneratedKeyPairName)
|
customize.buildFormParameters().entries(),
|
||||||
.entries());
|
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1",
|
||||||
|
generatedGroup, "KeyName", systemGeneratedKeyPairName).entries());
|
||||||
assertEquals(customize.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(customize.buildStringPayload(), null);
|
assertEquals(customize.buildStringPayload(), null);
|
||||||
|
@ -131,15 +133,15 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
|
|
||||||
// create mocks
|
// create mocks
|
||||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock(
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock(
|
||||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] {
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class,
|
||||||
|
new Method[] {
|
||||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||||
.getDeclaredMethod("getOptionsProvider"),
|
.getDeclaredMethod("getOptionsProvider"),
|
||||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||||
"createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class,
|
"createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||||
TemplateOptions.class),
|
TemplateOptions.class),
|
||||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||||
.getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class,
|
"getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) });
|
||||||
TemplateOptions.class) });
|
|
||||||
|
|
||||||
EC2TemplateOptions options = createMock(EC2TemplateOptions.class);
|
EC2TemplateOptions options = createMock(EC2TemplateOptions.class);
|
||||||
Template template = createMock(Template.class);
|
Template template = createMock(Template.class);
|
||||||
|
@ -162,9 +164,10 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
// run
|
// run
|
||||||
RunInstancesOptions customize = strategy.execute(region, tag, template);
|
RunInstancesOptions customize = strategy.execute(region, tag, template);
|
||||||
assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap.<String, String> of("InstanceType",
|
assertEquals(
|
||||||
size.getProviderId(), "SecurityGroup.1", "group", "KeyName", systemGeneratedKeyPairName, "UserData",
|
customize.buildFormParameters().entries(),
|
||||||
Base64.encodeBytes("hello".getBytes())).entries());
|
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1", "group",
|
||||||
|
"KeyName", systemGeneratedKeyPairName, "UserData", Base64.encodeBytes("hello".getBytes())).entries());
|
||||||
assertEquals(customize.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(customize.buildStringPayload(), null);
|
assertEquals(customize.buildStringPayload(), null);
|
||||||
|
@ -188,6 +191,8 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
|
|
||||||
// setup expectations
|
// setup expectations
|
||||||
expect(options.getKeyPair()).andReturn(userSuppliedKeyPair);
|
expect(options.getKeyPair()).andReturn(userSuppliedKeyPair);
|
||||||
|
expect(options.getOverridingCredentials()).andReturn(null);
|
||||||
|
expect(options.getRunScript()).andReturn(null);
|
||||||
|
|
||||||
// replay mocks
|
// replay mocks
|
||||||
replay(options);
|
replay(options);
|
||||||
|
@ -203,7 +208,110 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
verifyStrategy(strategy);
|
verifyStrategy(strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_createsNewKeyPairAndReturnsItsNameByDefault() {
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
|
public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldToWithRunScriptButNoCredentials() {
|
||||||
|
// setup constants
|
||||||
|
String region = Region.AP_SOUTHEAST_1;
|
||||||
|
String tag = "tag";
|
||||||
|
String userSuppliedKeyPair = "myKeyPair";
|
||||||
|
|
||||||
|
// create mocks
|
||||||
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy();
|
||||||
|
EC2TemplateOptions options = createMock(EC2TemplateOptions.class);
|
||||||
|
KeyPair keyPair = createMock(KeyPair.class);
|
||||||
|
|
||||||
|
// setup expectations
|
||||||
|
expect(options.getKeyPair()).andReturn(userSuppliedKeyPair);
|
||||||
|
expect(options.getOverridingCredentials()).andReturn(null);
|
||||||
|
expect(options.getRunScript()).andReturn(Statements.exec("echo foo"));
|
||||||
|
|
||||||
|
expect(strategy.credentialsMap.getUnchecked(new RegionAndName(region, userSuppliedKeyPair))).andThrow(new NullPointerException());
|
||||||
|
|
||||||
|
// replay mocks
|
||||||
|
replay(options);
|
||||||
|
replay(keyPair);
|
||||||
|
replayStrategy(strategy);
|
||||||
|
|
||||||
|
// run
|
||||||
|
assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), userSuppliedKeyPair);
|
||||||
|
|
||||||
|
// verify mocks
|
||||||
|
verify(options);
|
||||||
|
verify(keyPair);
|
||||||
|
verifyStrategy(strategy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldToWithRunScriptAndCredentialsAlreadyInMap() {
|
||||||
|
// setup constants
|
||||||
|
String region = Region.AP_SOUTHEAST_1;
|
||||||
|
String tag = "tag";
|
||||||
|
String userSuppliedKeyPair = "myKeyPair";
|
||||||
|
|
||||||
|
// create mocks
|
||||||
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy();
|
||||||
|
EC2TemplateOptions options = createMock(EC2TemplateOptions.class);
|
||||||
|
KeyPair keyPair = createMock(KeyPair.class);
|
||||||
|
|
||||||
|
// setup expectations
|
||||||
|
expect(options.getKeyPair()).andReturn(userSuppliedKeyPair);
|
||||||
|
expect(options.getOverridingCredentials()).andReturn(null);
|
||||||
|
expect(options.getRunScript()).andReturn(Statements.exec("echo foo"));
|
||||||
|
|
||||||
|
expect(strategy.credentialsMap.getUnchecked(new RegionAndName(region, userSuppliedKeyPair))).andReturn(keyPair);
|
||||||
|
|
||||||
|
// replay mocks
|
||||||
|
replay(options);
|
||||||
|
replay(keyPair);
|
||||||
|
replayStrategy(strategy);
|
||||||
|
|
||||||
|
// run
|
||||||
|
assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), userSuppliedKeyPair);
|
||||||
|
|
||||||
|
// verify mocks
|
||||||
|
verify(options);
|
||||||
|
verify(keyPair);
|
||||||
|
verifyStrategy(strategy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldToWithRunScriptAndCredentialsSpecified() {
|
||||||
|
// setup constants
|
||||||
|
String region = Region.AP_SOUTHEAST_1;
|
||||||
|
String tag = "tag";
|
||||||
|
String userSuppliedKeyPair = "myKeyPair";
|
||||||
|
|
||||||
|
// create mocks
|
||||||
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy();
|
||||||
|
EC2TemplateOptions options = createMock(EC2TemplateOptions.class);
|
||||||
|
KeyPair keyPair = createMock(KeyPair.class);
|
||||||
|
|
||||||
|
// setup expectations
|
||||||
|
expect(options.getKeyPair()).andReturn(userSuppliedKeyPair);
|
||||||
|
expect(options.getOverridingCredentials()).andReturn(new Credentials(null, "MyRsa")).atLeastOnce();
|
||||||
|
expect(
|
||||||
|
strategy.knownKeys.put(
|
||||||
|
new RegionAndName(region, userSuppliedKeyPair),
|
||||||
|
KeyPair.builder().region(region).keyName(userSuppliedKeyPair).keyFingerprint("//TODO")
|
||||||
|
.keyMaterial("MyRsa").build())).andReturn(null);
|
||||||
|
strategy.credentialsMap.invalidate(new RegionAndName(region, userSuppliedKeyPair));
|
||||||
|
expect(options.getRunScript()).andReturn(Statements.exec("echo foo"));
|
||||||
|
expect(strategy.credentialsMap.getUnchecked(new RegionAndName(region, userSuppliedKeyPair))).andReturn(keyPair);
|
||||||
|
|
||||||
|
// replay mocks
|
||||||
|
replay(options);
|
||||||
|
replay(keyPair);
|
||||||
|
replayStrategy(strategy);
|
||||||
|
|
||||||
|
// run
|
||||||
|
assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), userSuppliedKeyPair);
|
||||||
|
|
||||||
|
// verify mocks
|
||||||
|
verify(options);
|
||||||
|
verify(keyPair);
|
||||||
|
verifyStrategy(strategy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_createsNewKeyPairAndReturnsItsNameByDefault()
|
||||||
|
throws ExecutionException {
|
||||||
// setup constants
|
// setup constants
|
||||||
String region = Region.AP_SOUTHEAST_1;
|
String region = Region.AP_SOUTHEAST_1;
|
||||||
String tag = "tag";
|
String tag = "tag";
|
||||||
|
@ -219,10 +327,9 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
// setup expectations
|
// setup expectations
|
||||||
expect(options.getKeyPair()).andReturn(userSuppliedKeyPair);
|
expect(options.getKeyPair()).andReturn(userSuppliedKeyPair);
|
||||||
expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair);
|
expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair);
|
||||||
expect(strategy.createUniqueKeyPair.apply(new RegionAndName(region, tag))).andReturn(keyPair);
|
|
||||||
expect(keyPair.getKeyName()).andReturn(systemGeneratedKeyPairName).atLeastOnce();
|
expect(keyPair.getKeyName()).andReturn(systemGeneratedKeyPairName).atLeastOnce();
|
||||||
expect(strategy.credentialsMap.put(new RegionAndName(region, systemGeneratedKeyPairName), keyPair)).andReturn(
|
expect(strategy.credentialsMap.getUnchecked(new RegionAndName(region, tag))).andReturn(keyPair);
|
||||||
null);
|
expect(options.getRunScript()).andReturn(null);
|
||||||
|
|
||||||
// replay mocks
|
// replay mocks
|
||||||
replay(options);
|
replay(options);
|
||||||
|
@ -254,6 +361,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
|
|
||||||
// setup expectations
|
// setup expectations
|
||||||
expect(options.getKeyPair()).andReturn(userSuppliedKeyPair);
|
expect(options.getKeyPair()).andReturn(userSuppliedKeyPair);
|
||||||
|
expect(options.getRunScript()).andReturn(null);
|
||||||
expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair);
|
expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair);
|
||||||
|
|
||||||
// replay mocks
|
// replay mocks
|
||||||
|
@ -270,7 +378,8 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
verifyStrategy(strategy);
|
verifyStrategy(strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetSecurityGroupsForTagAndOptions_createsNewGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesntExist() {
|
public void testGetSecurityGroupsForTagAndOptions_createsNewGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesntExist()
|
||||||
|
throws ExecutionException {
|
||||||
// setup constants
|
// setup constants
|
||||||
String region = Region.AP_SOUTHEAST_1;
|
String region = Region.AP_SOUTHEAST_1;
|
||||||
String tag = "tag";
|
String tag = "tag";
|
||||||
|
@ -278,7 +387,6 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
Set<String> groupIds = ImmutableSet.<String> of();
|
Set<String> groupIds = ImmutableSet.<String> of();
|
||||||
int[] ports = new int[] {};
|
int[] ports = new int[] {};
|
||||||
boolean shouldAuthorizeSelf = true;
|
boolean shouldAuthorizeSelf = true;
|
||||||
boolean groupExisted = false;
|
|
||||||
Set<String> returnVal = ImmutableSet.<String> of(generatedMarkerGroup);
|
Set<String> returnVal = ImmutableSet.<String> of(generatedMarkerGroup);
|
||||||
|
|
||||||
// create mocks
|
// create mocks
|
||||||
|
@ -290,9 +398,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
expect(options.getInboundPorts()).andReturn(ports).atLeastOnce();
|
expect(options.getInboundPorts()).andReturn(ports).atLeastOnce();
|
||||||
RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup,
|
RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup,
|
||||||
ports, shouldAuthorizeSelf);
|
ports, shouldAuthorizeSelf);
|
||||||
expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted);
|
expect(strategy.securityGroupMap.getUnchecked(regionNameAndIngressRules)).andReturn(tag);
|
||||||
expect(strategy.createSecurityGroupIfNeeded.apply(regionNameAndIngressRules)).andReturn(generatedMarkerGroup);
|
|
||||||
expect(strategy.securityGroupMap.put(regionNameAndIngressRules, generatedMarkerGroup)).andReturn(null);
|
|
||||||
|
|
||||||
// replay mocks
|
// replay mocks
|
||||||
replay(options);
|
replay(options);
|
||||||
|
@ -306,7 +412,8 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
verifyStrategy(strategy);
|
verifyStrategy(strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetSecurityGroupsForTagAndOptions_createsNewGroupByDefaultWhenPortsAreSpecifiedWhenDoesntExist() {
|
public void testGetSecurityGroupsForTagAndOptions_createsNewGroupByDefaultWhenPortsAreSpecifiedWhenDoesntExist()
|
||||||
|
throws ExecutionException {
|
||||||
// setup constants
|
// setup constants
|
||||||
String region = Region.AP_SOUTHEAST_1;
|
String region = Region.AP_SOUTHEAST_1;
|
||||||
String tag = "tag";
|
String tag = "tag";
|
||||||
|
@ -314,7 +421,6 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
Set<String> groupIds = ImmutableSet.<String> of();
|
Set<String> groupIds = ImmutableSet.<String> of();
|
||||||
int[] ports = new int[] { 22, 80 };
|
int[] ports = new int[] { 22, 80 };
|
||||||
boolean shouldAuthorizeSelf = true;
|
boolean shouldAuthorizeSelf = true;
|
||||||
boolean groupExisted = false;
|
|
||||||
Set<String> returnVal = ImmutableSet.<String> of(generatedMarkerGroup);
|
Set<String> returnVal = ImmutableSet.<String> of(generatedMarkerGroup);
|
||||||
|
|
||||||
// create mocks
|
// create mocks
|
||||||
|
@ -326,9 +432,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
expect(options.getInboundPorts()).andReturn(ports).atLeastOnce();
|
expect(options.getInboundPorts()).andReturn(ports).atLeastOnce();
|
||||||
RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup,
|
RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup,
|
||||||
ports, shouldAuthorizeSelf);
|
ports, shouldAuthorizeSelf);
|
||||||
expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted);
|
expect(strategy.securityGroupMap.getUnchecked(regionNameAndIngressRules)).andReturn(generatedMarkerGroup);
|
||||||
expect(strategy.createSecurityGroupIfNeeded.apply(regionNameAndIngressRules)).andReturn(generatedMarkerGroup);
|
|
||||||
expect(strategy.securityGroupMap.put(regionNameAndIngressRules, generatedMarkerGroup)).andReturn(null);
|
|
||||||
|
|
||||||
// replay mocks
|
// replay mocks
|
||||||
replay(options);
|
replay(options);
|
||||||
|
@ -342,7 +446,8 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
verifyStrategy(strategy);
|
verifyStrategy(strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetSecurityGroupsForTagAndOptions_reusesGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesExist() {
|
public void testGetSecurityGroupsForTagAndOptions_reusesGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesExist()
|
||||||
|
throws ExecutionException {
|
||||||
// setup constants
|
// setup constants
|
||||||
String region = Region.AP_SOUTHEAST_1;
|
String region = Region.AP_SOUTHEAST_1;
|
||||||
String tag = "tag";
|
String tag = "tag";
|
||||||
|
@ -350,7 +455,6 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
Set<String> groupIds = ImmutableSet.<String> of();
|
Set<String> groupIds = ImmutableSet.<String> of();
|
||||||
int[] ports = new int[] {};
|
int[] ports = new int[] {};
|
||||||
boolean shouldAuthorizeSelf = true;
|
boolean shouldAuthorizeSelf = true;
|
||||||
boolean groupExisted = true;
|
|
||||||
Set<String> returnVal = ImmutableSet.<String> of(generatedMarkerGroup);
|
Set<String> returnVal = ImmutableSet.<String> of(generatedMarkerGroup);
|
||||||
|
|
||||||
// create mocks
|
// create mocks
|
||||||
|
@ -362,7 +466,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
expect(options.getInboundPorts()).andReturn(ports).atLeastOnce();
|
expect(options.getInboundPorts()).andReturn(ports).atLeastOnce();
|
||||||
RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup,
|
RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup,
|
||||||
ports, shouldAuthorizeSelf);
|
ports, shouldAuthorizeSelf);
|
||||||
expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted);
|
expect(strategy.securityGroupMap.getUnchecked(regionNameAndIngressRules)).andReturn(generatedMarkerGroup);
|
||||||
|
|
||||||
// replay mocks
|
// replay mocks
|
||||||
replay(options);
|
replay(options);
|
||||||
|
@ -394,13 +498,9 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
// setup expectations
|
// setup expectations
|
||||||
expect(options.getGroups()).andReturn(groupIds).atLeastOnce();
|
expect(options.getGroups()).andReturn(groupIds).atLeastOnce();
|
||||||
RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup,
|
RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup,
|
||||||
ports, shouldAuthorizeSelf); // note
|
ports, shouldAuthorizeSelf);
|
||||||
// this
|
|
||||||
// works
|
expect(strategy.securityGroupMap.getUnchecked(regionNameAndIngressRules)).andReturn(groupExisted ? "tag" : null);
|
||||||
// since
|
|
||||||
// there's
|
|
||||||
// no equals on portsq
|
|
||||||
expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted);
|
|
||||||
|
|
||||||
// replay mocks
|
// replay mocks
|
||||||
replay(options);
|
replay(options);
|
||||||
|
@ -415,28 +515,24 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyStrategy(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy) {
|
private void verifyStrategy(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy) {
|
||||||
|
verify(strategy.knownKeys);
|
||||||
verify(strategy.credentialsMap);
|
verify(strategy.credentialsMap);
|
||||||
verify(strategy.securityGroupMap);
|
verify(strategy.securityGroupMap);
|
||||||
verify(strategy.createUniqueKeyPair);
|
|
||||||
verify(strategy.createSecurityGroupIfNeeded);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions setupStrategy() {
|
private CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions setupStrategy() {
|
||||||
Map<RegionAndName, KeyPair> credentialsMap = createMock(Map.class);
|
Map<RegionAndName, KeyPair> knownKeys = createMock(Map.class);
|
||||||
Map<RegionAndName, String> securityGroupMap = createMock(Map.class);
|
Cache<RegionAndName, KeyPair> credentialsMap = createMock(Cache.class);
|
||||||
CreateUniqueKeyPair createUniqueKeyPair = createMock(CreateUniqueKeyPair.class);
|
Cache<RegionAndName, String> securityGroupMap = createMock(Cache.class);
|
||||||
Function<RegionNameAndIngressRules, String> createSecurityGroupIfNeeded = createMock(CreateSecurityGroupIfNeeded.class);
|
return new CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions(knownKeys, credentialsMap, securityGroupMap,
|
||||||
|
OPTIONS_PROVIDER);
|
||||||
return new CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions(credentialsMap, securityGroupMap,
|
|
||||||
createUniqueKeyPair, createSecurityGroupIfNeeded, OPTIONS_PROVIDER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void replayStrategy(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy) {
|
private void replayStrategy(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy) {
|
||||||
|
replay(strategy.knownKeys);
|
||||||
replay(strategy.credentialsMap);
|
replay(strategy.credentialsMap);
|
||||||
replay(strategy.securityGroupMap);
|
replay(strategy.securityGroupMap);
|
||||||
replay(strategy.createUniqueKeyPair);
|
|
||||||
replay(strategy.createSecurityGroupIfNeeded);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ import org.jclouds.ec2.options.RunInstancesOptions;
|
||||||
import org.jclouds.ec2.services.InstanceClient;
|
import org.jclouds.ec2.services.InstanceClient;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
@ -222,7 +222,7 @@ public class EC2CreateNodesInGroupThenAddToSetTest {
|
||||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize = createMock(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class);
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize = createMock(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class);
|
||||||
InstancePresent instancePresent = createMock(InstancePresent.class);
|
InstancePresent instancePresent = createMock(InstancePresent.class);
|
||||||
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata = createMock(RunningInstanceToNodeMetadata.class);
|
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata = createMock(RunningInstanceToNodeMetadata.class);
|
||||||
Function<RunningInstance, Credentials> instanceToCredentials = createMock(Function.class);
|
Cache<RunningInstance, Credentials> instanceToCredentials = createMock(Cache.class);
|
||||||
Map<String, Credentials> credentialStore = createMock(Map.class);
|
Map<String, Credentials> credentialStore = createMock(Map.class);
|
||||||
ComputeUtils utils = createMock(ComputeUtils.class);
|
ComputeUtils utils = createMock(ComputeUtils.class);
|
||||||
return new EC2CreateNodesInGroupThenAddToSet(client, Providers.<TemplateBuilder> of(template),
|
return new EC2CreateNodesInGroupThenAddToSet(client, Providers.<TemplateBuilder> of(template),
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
/**
|
||||||
|
* 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.ec2.config;
|
||||||
|
|
||||||
|
import static org.easymock.classextension.EasyMock.*;
|
||||||
|
|
||||||
|
import org.easymock.classextension.IMocksControl;
|
||||||
|
import org.jclouds.ec2.EC2Client;
|
||||||
|
import org.jclouds.ec2.domain.AvailabilityZoneInfo;
|
||||||
|
import org.jclouds.ec2.services.AvailabilityZoneAndRegionClient;
|
||||||
|
import org.jclouds.http.HttpCommand;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
import static org.testng.Assert.*;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A test for {@link EC2RestClientModule}.
|
||||||
|
*
|
||||||
|
* @author Eric Pabst (pabstec@familysearch.org)
|
||||||
|
*/
|
||||||
|
public class EC2RestClientModuleTest {
|
||||||
|
@Test
|
||||||
|
public void testDescribeAvailabilityZonesInRegion_BestEffort() {
|
||||||
|
IMocksControl control = createControl();
|
||||||
|
EC2Client client = control.createMock(EC2Client.class);
|
||||||
|
AvailabilityZoneAndRegionClient regionClient = control.createMock(AvailabilityZoneAndRegionClient.class);
|
||||||
|
AvailabilityZoneInfo info1 = control.createMock(AvailabilityZoneInfo.class);
|
||||||
|
AvailabilityZoneInfo info2 = control.createMock(AvailabilityZoneInfo.class);
|
||||||
|
HttpCommand command = control.createMock(HttpCommand.class);
|
||||||
|
HttpResponseException exception = new HttpResponseException("Error: Unable to tunnel through proxy: ...", command, null);
|
||||||
|
|
||||||
|
expect(client.getAvailabilityZoneAndRegionServices()).andStubReturn(regionClient);
|
||||||
|
expect(regionClient.describeAvailabilityZonesInRegion("accessibleRegion1")).andReturn(Collections.singleton(info1));
|
||||||
|
expect(regionClient.describeAvailabilityZonesInRegion("inaccessibleRegion")).andThrow(exception);
|
||||||
|
expect(regionClient.describeAvailabilityZonesInRegion("accessibleRegion2")).andReturn(Collections.singleton(info2));
|
||||||
|
expect(info1.getZone()).andStubReturn("zone1");
|
||||||
|
expect(info2.getZone()).andStubReturn("zone2");
|
||||||
|
|
||||||
|
Map<String, URI> regions = new LinkedHashMap<String, URI>();
|
||||||
|
regions.put("accessibleRegion1", null);
|
||||||
|
regions.put("inaccessibleRegion", null);
|
||||||
|
regions.put("accessibleRegion2", null);
|
||||||
|
control.replay();
|
||||||
|
|
||||||
|
Map<String,String> expectedResult = new HashMap<String,String>();
|
||||||
|
expectedResult.put("zone1", "accessibleRegion1");
|
||||||
|
expectedResult.put("zone2", "accessibleRegion2");
|
||||||
|
|
||||||
|
EC2RestClientModule.RegionIdToZoneId regionIdToZoneId = new EC2RestClientModule.RegionIdToZoneId(client, regions);
|
||||||
|
assertEquals(regionIdToZoneId.get(), expectedResult);
|
||||||
|
control.verify();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDescribeAvailabilityZonesInRegion_RethrowIfNoneFound() {
|
||||||
|
IMocksControl control = createControl();
|
||||||
|
EC2Client client = control.createMock(EC2Client.class);
|
||||||
|
AvailabilityZoneAndRegionClient regionClient = control.createMock(AvailabilityZoneAndRegionClient.class);
|
||||||
|
HttpCommand command = control.createMock(HttpCommand.class);
|
||||||
|
HttpResponseException exception = new HttpResponseException("Error: Unable to tunnel through proxy: ...", command, null);
|
||||||
|
|
||||||
|
expect(client.getAvailabilityZoneAndRegionServices()).andStubReturn(regionClient);
|
||||||
|
expect(regionClient.describeAvailabilityZonesInRegion("inaccessibleRegion")).andThrow(exception);
|
||||||
|
|
||||||
|
Map<String, URI> regions = new LinkedHashMap<String, URI>();
|
||||||
|
regions.put("inaccessibleRegion", null);
|
||||||
|
control.replay();
|
||||||
|
|
||||||
|
EC2RestClientModule.RegionIdToZoneId regionIdToZoneId = new EC2RestClientModule.RegionIdToZoneId(client, regions);
|
||||||
|
try {
|
||||||
|
regionIdToZoneId.get();
|
||||||
|
fail("expected exception");
|
||||||
|
} catch (HttpResponseException e) {
|
||||||
|
assertEquals(e, exception);
|
||||||
|
}
|
||||||
|
control.verify();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDescribeAvailabilityZonesInRegion_NoZones() {
|
||||||
|
IMocksControl control = createControl();
|
||||||
|
EC2Client client = control.createMock(EC2Client.class);
|
||||||
|
AvailabilityZoneAndRegionClient regionClient = control.createMock(AvailabilityZoneAndRegionClient.class);
|
||||||
|
|
||||||
|
expect(client.getAvailabilityZoneAndRegionServices()).andStubReturn(regionClient);
|
||||||
|
expect(regionClient.describeAvailabilityZonesInRegion("emptyRegion")).andReturn(Collections.<AvailabilityZoneInfo>emptySet());
|
||||||
|
|
||||||
|
Map<String, URI> regions = new LinkedHashMap<String, URI>();
|
||||||
|
regions.put("emptyRegion", null);
|
||||||
|
control.replay();
|
||||||
|
|
||||||
|
EC2RestClientModule.RegionIdToZoneId regionIdToZoneId = new EC2RestClientModule.RegionIdToZoneId(client, regions);
|
||||||
|
assertEquals(regionIdToZoneId.get(), Collections.<String, String>emptyMap());
|
||||||
|
control.verify();
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue