Merge branch 'master' of git://github.com/jclouds/jclouds

Conflicts:
	README.txt
This commit is contained in:
vijaykiran 2011-10-21 13:35:27 +02:00
commit 9a5b1ef15d
939 changed files with 23321 additions and 6247 deletions

View File

@ -24,12 +24,17 @@
<parent> <parent>
<groupId>org.jclouds</groupId> <groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId> <artifactId>jclouds-project</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.3.0-SNAPSHOT</version>
<relativePath>../project/pom.xml</relativePath> <relativePath>../project/pom.xml</relativePath>
</parent> </parent>
<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>

View File

@ -24,7 +24,7 @@
<parent> <parent>
<groupId>org.jclouds</groupId> <groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId> <artifactId>jclouds-project</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.3.0-SNAPSHOT</version>
<relativePath>../project/pom.xml</relativePath> <relativePath>../project/pom.xml</relativePath>
</parent> </parent>
<artifactId>jclouds-allblobstore</artifactId> <artifactId>jclouds-allblobstore</artifactId>

View File

@ -24,7 +24,7 @@
<parent> <parent>
<groupId>org.jclouds</groupId> <groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId> <artifactId>jclouds-project</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.3.0-SNAPSHOT</version>
<relativePath>../project/pom.xml</relativePath> <relativePath>../project/pom.xml</relativePath>
</parent> </parent>
<artifactId>jclouds-allcompute</artifactId> <artifactId>jclouds-allcompute</artifactId>
@ -95,6 +95,11 @@
<artifactId>vcloud</artifactId> <artifactId>vcloud</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>cloudsigma</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.jclouds.provider</groupId> <groupId>org.jclouds.provider</groupId>
<artifactId>trmk-vcloudexpress</artifactId> <artifactId>trmk-vcloudexpress</artifactId>
@ -105,11 +110,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 +170,20 @@
<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>cloudsigma-lvs</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.provider</groupId>
<artifactId>go2cloud-jhb1</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.provider</groupId>
<artifactId>softlayer</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -24,7 +24,7 @@
<parent> <parent>
<groupId>org.jclouds</groupId> <groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId> <artifactId>jclouds-project</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.3.0-SNAPSHOT</version>
<relativePath>../project/pom.xml</relativePath> <relativePath>../project/pom.xml</relativePath>
</parent> </parent>
<artifactId>jclouds-allloadbalancer</artifactId> <artifactId>jclouds-allloadbalancer</artifactId>

View File

@ -24,7 +24,7 @@
<parent> <parent>
<groupId>org.jclouds</groupId> <groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId> <artifactId>jclouds-project</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.3.0-SNAPSHOT</version>
<relativePath>../project/pom.xml</relativePath> <relativePath>../project/pom.xml</relativePath>
</parent> </parent>
<artifactId>jclouds-antcontrib</artifactId> <artifactId>jclouds-antcontrib</artifactId>

View File

@ -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)) {

View File

@ -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

View File

@ -24,7 +24,7 @@
<parent> <parent>
<groupId>org.jclouds</groupId> <groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId> <artifactId>jclouds-project</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.3.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath> <relativePath>../../project/pom.xml</relativePath>
</parent> </parent>

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -24,7 +24,7 @@
<parent> <parent>
<groupId>org.jclouds</groupId> <groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId> <artifactId>jclouds-project</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.3.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath> <relativePath>../../project/pom.xml</relativePath>
</parent> </parent>

View File

@ -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());
}
} }

View File

@ -20,10 +20,13 @@ package org.jclouds.byon;
import java.net.URI; import java.net.URI;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
/** /**
* *
@ -48,6 +51,7 @@ public class Node {
private int loginPort = 22; private int loginPort = 22;
private String group; private String group;
private Set<String> tags = ImmutableSet.of(); private Set<String> tags = ImmutableSet.of();
private Map<String, String> metadata = ImmutableMap.<String, String>of();
private String username; private String username;
private String credential; private String credential;
private URI credentialUrl; private URI credentialUrl;
@ -117,7 +121,12 @@ public class Node {
this.tags = ImmutableSet.copyOf(tags); this.tags = ImmutableSet.copyOf(tags);
return this; return this;
} }
public Builder metadata(Map<String, String> metadata) {
this.metadata = ImmutableMap.copyOf(metadata);
return this;
}
public Builder username(String username) { public Builder username(String username) {
this.username = username; this.username = username;
return this; return this;
@ -140,13 +149,14 @@ public class Node {
public Node build() { public Node build() {
return new Node(id, name, description, hostname, locationId, osArch, osFamily, osDescription, osVersion, return new Node(id, name, description, hostname, locationId, osArch, osFamily, osDescription, osVersion,
os64Bit, loginPort, group, tags, username, credential, credentialUrl, sudoPassword); os64Bit, loginPort, group, tags, metadata, username, credential, credentialUrl, sudoPassword);
} }
} }
public Node(String id, String name, String description, String hostname, String locationId, String osArch, public Node(String id, String name, String description, String hostname, String locationId, String osArch,
String osFamily, String osDescription, String osVersion, boolean os64Bit, int loginPort, String group, String osFamily, String osDescription, String osVersion, boolean os64Bit, int loginPort, String group,
Iterable<String> tags, String username, String credential, URI credentialUrl, String sudoPassword) { Iterable<String> tags, Map<String, String> metadata, String username, String credential, URI credentialUrl,
String sudoPassword) {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.description = description; this.description = description;
@ -160,6 +170,7 @@ public class Node {
this.loginPort = loginPort; this.loginPort = loginPort;
this.group = group; this.group = group;
this.tags = ImmutableSet.copyOf(tags); this.tags = ImmutableSet.copyOf(tags);
this.metadata = ImmutableMap.copyOf(metadata);
this.username = username; this.username = username;
this.credential = credential; this.credential = credential;
this.credentialUrl = credentialUrl; this.credentialUrl = credentialUrl;
@ -179,6 +190,7 @@ public class Node {
private final boolean os64Bit; private final boolean os64Bit;
private final String group; private final String group;
private final Set<String> tags; private final Set<String> tags;
private final Map<String, String> metadata;
private final String username; private final String username;
private final String credential; private final String credential;
private final URI credentialUrl; private final URI credentialUrl;
@ -239,6 +251,10 @@ public class Node {
return tagSet; return tagSet;
} }
public Map<String, String> getMetadata() {
return Maps.newLinkedHashMap(this.metadata);
}
public String getUsername() { public String getUsername() {
return username; return username;
} }
@ -269,12 +285,12 @@ public class Node {
@Override @Override
public String toString() { public String toString() {
return Objects.toStringHelper(this).add("id", id).add("name", name).add("description", description).add( return Objects.toStringHelper(this).add("id", id).add("name", name).add("description", description)
"locationId", locationId).add("hostname", hostname).add("osArch", osArch).add("osFamily", osFamily).add( .add("locationId", locationId).add("hostname", hostname).add("osArch", osArch).add("osFamily", osFamily)
"osDescription", osDescription).add("osVersion", osVersion).add("os64Bit", os64Bit).add("group", group) .add("osDescription", osDescription).add("osVersion", osVersion).add("os64Bit", os64Bit)
.add("loginPort", loginPort).add("tags", tags).add("username", username).add("hasCredential", .add("group", group).add("loginPort", loginPort).add("tags", tags).add("metadata", metadata)
credential != null || credentialUrl != null).add("hasSudoPassword", sudoPassword != null) .add("username", username).add("hasCredential", credential != null || credentialUrl != null)
.toString(); .add("hasSudoPassword", sudoPassword != null).toString();
} }
} }

View File

@ -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;
@ -47,7 +45,7 @@ import com.google.inject.TypeLiteral;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@SingleThreaded @SingleThreaded
public class BYONComputeServiceContextModule extends public class BYONComputeServiceContextModule extends
JCloudsNativeComputeServiceAdapterContextModule<Supplier, Supplier> { JCloudsNativeComputeServiceAdapterContextModule<Supplier, Supplier> {
public BYONComputeServiceContextModule() { public BYONComputeServiceContextModule() {
super(Supplier.class, Supplier.class, BYONComputeServiceAdapter.class); super(Supplier.class, Supplier.class, BYONComputeServiceAdapter.class);
@ -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);
} }
} }

View File

@ -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));
}
}

View File

@ -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
* *

View File

@ -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,27 +81,37 @@ 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);
} }
} }

View File

@ -21,6 +21,7 @@ package org.jclouds.byon.domain;
import java.io.InputStream; import java.io.InputStream;
import java.net.URI; import java.net.URI;
import java.util.List; import java.util.List;
import java.util.Map;
import org.jclouds.byon.Node; import org.jclouds.byon.Node;
import org.jclouds.util.Strings2; import org.jclouds.util.Strings2;
@ -34,6 +35,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.Closeables; import com.google.common.io.Closeables;
/** /**
@ -54,6 +56,8 @@ import com.google.common.io.Closeables;
* group: hadoop * group: hadoop
* tags: * tags:
* - vanilla * - vanilla
* metadata:
* key1: val1
* username: kelvin * username: kelvin
* credential: password_or_rsa * credential: password_or_rsa
* or * or
@ -78,6 +82,7 @@ public class YamlNode {
public boolean os_64bit; public boolean os_64bit;
public String group; public String group;
public List<String> tags = Lists.newArrayList(); public List<String> tags = Lists.newArrayList();
public Map<String, String> metadata = Maps.newLinkedHashMap();
public String username; public String username;
public String credential; public String credential;
public String credential_url; public String credential_url;
@ -91,7 +96,7 @@ public class YamlNode {
return Node.builder().id(arg0.id).name(arg0.name).description(arg0.description).locationId(arg0.location_id) return Node.builder().id(arg0.id).name(arg0.name).description(arg0.description).locationId(arg0.location_id)
.hostname(arg0.hostname).osArch(arg0.os_arch).osFamily(arg0.os_family).osDescription( .hostname(arg0.hostname).osArch(arg0.os_arch).osFamily(arg0.os_family).osDescription(
arg0.os_description).osVersion(arg0.os_version).os64Bit(arg0.os_64bit).group(arg0.group) arg0.os_description).osVersion(arg0.os_version).os64Bit(arg0.os_64bit).group(arg0.group)
.loginPort(arg0.login_port).tags(arg0.tags).username(arg0.username).credential(arg0.credential).credentialUrl( .loginPort(arg0.login_port).tags(arg0.tags).metadata(arg0.metadata).username(arg0.username).credential(arg0.credential).credentialUrl(
arg0.credential_url != null ? URI.create(arg0.credential_url) : null).sudoPassword( arg0.credential_url != null ? URI.create(arg0.credential_url) : null).sudoPassword(
arg0.sudo_password).build(); arg0.sudo_password).build();
} }
@ -152,6 +157,8 @@ public class YamlNode {
prettier.put("group", in.group); prettier.put("group", in.group);
if (in.tags.size() != 0) if (in.tags.size() != 0)
prettier.put("tags", in.tags); prettier.put("tags", in.tags);
if (in.metadata.size() != 0)
prettier.put("metadata", in.metadata);
if (in.username != null) if (in.username != null)
prettier.put("username", in.username); prettier.put("username", in.username);
if (in.credential != null) if (in.credential != null)
@ -193,6 +200,7 @@ public class YamlNode {
yaml.login_port = arg0.getLoginPort(); yaml.login_port = arg0.getLoginPort();
yaml.group = arg0.getGroup(); yaml.group = arg0.getGroup();
yaml.tags = ImmutableList.copyOf(arg0.getTags()); yaml.tags = ImmutableList.copyOf(arg0.getTags());
yaml.metadata = ImmutableMap.copyOf(arg0.getMetadata());
yaml.username = arg0.getUsername(); yaml.username = arg0.getUsername();
yaml.credential = arg0.getCredential(); yaml.credential = arg0.getCredential();
yaml.credential_url = arg0.getCredentialUrl() != null ? arg0.getCredentialUrl().toASCIIString() : null; yaml.credential_url = arg0.getCredentialUrl() != null ? arg0.getCredentialUrl().toASCIIString() : null;

View File

@ -84,6 +84,7 @@ public class NodeToNodeMetadata implements Function<Node, NodeMetadata> {
builder.location(findLocationWithId(from.getLocationId())); builder.location(findLocationWithId(from.getLocationId()));
builder.group(from.getGroup()); builder.group(from.getGroup());
builder.tags(from.getTags()); builder.tags(from.getTags());
builder.userMetadata(from.getMetadata());
builder.operatingSystem(OperatingSystem.builder().arch(from.getOsArch()).family( builder.operatingSystem(OperatingSystem.builder().arch(from.getOsArch()).family(
OsFamily.fromValue(from.getOsFamily())).description(from.getOsDescription()) OsFamily.fromValue(from.getOsFamily())).description(from.getOsDescription())
.version(from.getOsVersion()).build()); .version(from.getOsVersion()).build());

View File

@ -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),
public String apply(Node node) { new Function<Node, String>() {
return node.getId(); public String apply(Node node) {
} 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;
} }
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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,26 +98,27 @@ 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, 2022))); 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 {
if (context != null) if (context != null)

View File

@ -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);
}
}

View File

@ -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,12 +52,12 @@ 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() {
return new Object[][] { { "instance1", "bear" }, { "instance2", "apple" }, { "instance2", "francis" }, return new Object[][] { { "instance1", "bear" }, { "instance2", "apple" }, { "instance2", "francis" },
{ "instance4", "robot" } }; { "instance4", "robot" } };
} }
@Test(dataProvider = "names") @Test(dataProvider = "names")
@ -62,7 +69,7 @@ public class YamlNodeStoreModuleTest {
public void testProvidedMapWithValue() throws IOException { public void testProvidedMapWithValue() throws IOException {
Map<String, InputStream> map = new CopyInputStreamInputSupplierMap( Map<String, InputStream> map = new CopyInputStreamInputSupplierMap(
new ConcurrentHashMap<String, InputSupplier<InputStream>>()); new ConcurrentHashMap<String, InputSupplier<InputStream>>());
map.put("test", new ByteArrayInputStream("id: instance1\nname: instancename\n".getBytes())); map.put("test", new ByteArrayInputStream("id: instance1\nname: instancename\n".getBytes()));
checkConsistent(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename"); checkConsistent(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename");
@ -73,12 +80,12 @@ public class YamlNodeStoreModuleTest {
public void testProvidedConsistentAcrossRepeatedWrites() throws IOException { public void testProvidedConsistentAcrossRepeatedWrites() throws IOException {
Map<String, InputStream> map = new CopyInputStreamInputSupplierMap( Map<String, InputStream> map = new CopyInputStreamInputSupplierMap(
new ConcurrentHashMap<String, InputSupplier<InputStream>>()); new ConcurrentHashMap<String, InputSupplier<InputStream>>());
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);
@ -87,7 +94,7 @@ public class YamlNodeStoreModuleTest {
public void testProvidedConsistentAcrossMultipleInjectors() throws IOException { public void testProvidedConsistentAcrossMultipleInjectors() throws IOException {
Map<String, InputStream> map = new CopyInputStreamInputSupplierMap( Map<String, InputStream> map = new CopyInputStreamInputSupplierMap(
new ConcurrentHashMap<String, InputSupplier<InputStream>>()); new ConcurrentHashMap<String, InputSupplier<InputStream>>());
put(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename"); put(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename");
checkConsistent(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename"); checkConsistent(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename");
@ -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);
} }
} }

View File

@ -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,9 +61,9 @@ 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) {
return expectedNodeMetadataFromResource(resource, expectedProviderLocationFromResource(resource)); return expectedNodeMetadataFromResource(resource, expectedProviderLocationFromResource(resource));
@ -75,7 +76,7 @@ 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); return expectedNodeMetadataFromResource(id, resource, location, 22);
} }
public static NodeMetadata expectedNodeMetadataFromResource(int id, String resource, Location location, int loginPort) { public static NodeMetadata expectedNodeMetadataFromResource(int id, String resource, Location location, int loginPort) {
return new NodeMetadataBuilder() return new NodeMetadataBuilder()
.ids("cluster-" + id) .ids("cluster-" + id)
@ -84,6 +85,7 @@ public class NodeToNodeMetadataTest {
.loginPort(loginPort) .loginPort(loginPort)
.hostname("cluster-" + id + ".mydomain.com") .hostname("cluster-" + id + ".mydomain.com")
.location(location) .location(location)
.userMetadata(ImmutableMap.of("Name", "foo"))
.state(NodeState.RUNNING) .state(NodeState.RUNNING)
.operatingSystem( .operatingSystem(
OperatingSystem.builder().description("redhat").family(OsFamily.RHEL).arch("x86").version("5.3") OperatingSystem.builder().description("redhat").family(OsFamily.RHEL).arch("x86").version("5.3")
@ -99,11 +101,11 @@ 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 @Test
public void testNodesParseLoginPort() throws Exception { public void testNodesParseLoginPort() throws Exception {
assertEquals(parser.apply(NodesFromYamlTest.TEST3), expectedNodeMetadataFromResource(2, resource, provider, 2022)); assertEquals(parser.apply(NodesFromYamlTest.TEST3), expectedNodeMetadataFromResource(2, resource, provider, 2022));

View File

@ -34,23 +34,23 @@ import com.google.common.collect.ImmutableMap;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class NodesFromYamlTest { public class NodesFromYamlTest {
public static final String key = new StringBuilder().append("-----BEGIN RSA PRIVATE KEY-----\n").append( public static final String key = new StringBuilder().append("-----BEGIN RSA PRIVATE KEY-----\n")
"MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2\n").append( .append("MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2\n")
"u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ\n").append( .append("u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ\n")
"lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o\n").append("-----END RSA PRIVATE KEY-----\n") .append("lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o\n").append("-----END RSA PRIVATE KEY-----\n")
.toString(); .toString();
public static final Node TEST1 = new Node("cluster-1", "cluster-1", "accounting analytics cluster", public static final Node TEST1 = new Node("cluster-1", "cluster-1", "accounting analytics cluster",
"cluster-1.mydomain.com", null, "x86", "rhel", "redhat", "5.3", false, 22, "hadoop", ImmutableList.of("vanilla"), "cluster-1.mydomain.com", null, "x86", "rhel", "redhat", "5.3", false, 22, "hadoop",
"myUser", key, null, "happy bear"); ImmutableList.of("vanilla"), ImmutableMap.of("Name", "foo"), "myUser", key, null, "happy bear");
public static final Node TEST2 = new Node("cluster-1", "cluster-1", "accounting analytics cluster", public static final Node TEST2 = new Node("cluster-1", "cluster-1", "accounting analytics cluster",
"cluster-1.mydomain.com", "virginia", "x86", "rhel", "redhat", "5.3", false, 22, "hadoop", "cluster-1.mydomain.com", "virginia", "x86", "rhel", "redhat", "5.3", false, 22, "hadoop",
ImmutableList.of("vanilla"), "myUser", key, null, "happy bear"); ImmutableList.of("vanilla"), ImmutableMap.of("Name", "foo"), "myUser", key, null, "happy bear");
public static final Node TEST3 = new Node("cluster-2", "cluster-2", "accounting analytics cluster", public static final Node TEST3 = new Node("cluster-2", "cluster-2", "accounting analytics cluster",
"cluster-2.mydomain.com", "maryland", "x86", "rhel", "redhat", "5.3", false, 2022, "hadoop", "cluster-2.mydomain.com", "maryland", "x86", "rhel", "redhat", "5.3", false, 2022, "hadoop",
ImmutableList.of("vanilla"), "myUser", key, null, "happy bear"); ImmutableList.of("vanilla"), ImmutableMap.of("Name", "foo"), "myUser", key, null, "happy bear");
@Test @Test
public void testNodesParse() throws Exception { public void testNodesParse() throws Exception {
@ -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)

View File

@ -10,6 +10,8 @@ nodes:
group: hadoop group: hadoop
tags: tags:
- vanilla - vanilla
metadata:
Name: foo
username: myUser username: myUser
credential: | credential: |
-----BEGIN RSA PRIVATE KEY----- -----BEGIN RSA PRIVATE KEY-----

View File

@ -11,6 +11,8 @@ nodes:
group: hadoop group: hadoop
tags: tags:
- vanilla - vanilla
metadata:
Name: foo
username: myUser username: myUser
credential: | credential: |
-----BEGIN RSA PRIVATE KEY----- -----BEGIN RSA PRIVATE KEY-----
@ -33,6 +35,8 @@ nodes:
group: hadoop group: hadoop
tags: tags:
- vanilla - vanilla
metadata:
Name: foo
username: myUser username: myUser
credential: | credential: |
-----BEGIN RSA PRIVATE KEY----- -----BEGIN RSA PRIVATE KEY-----

View File

@ -10,6 +10,8 @@ nodes:
group: hadoop group: hadoop
tags: tags:
- vanilla - vanilla
metadata:
Name: foo
username: myUser username: myUser
credential_url: classpath:///testkey.txt credential_url: classpath:///testkey.txt
sudo_password: happy bear sudo_password: happy bear

View File

@ -24,7 +24,7 @@
<parent> <parent>
<groupId>org.jclouds</groupId> <groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId> <artifactId>jclouds-project</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.3.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath> <relativePath>../../project/pom.xml</relativePath>
</parent> </parent>
<groupId>org.jclouds.api</groupId> <groupId>org.jclouds.api</groupId>

View File

@ -24,7 +24,7 @@
<parent> <parent>
<groupId>org.jclouds</groupId> <groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId> <artifactId>jclouds-project</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.3.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath> <relativePath>../../project/pom.xml</relativePath>
</parent> </parent>

View File

@ -19,18 +19,19 @@
package org.jclouds.cloudservers.compute.strategy; package org.jclouds.cloudservers.compute.strategy;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.cloudservers.options.CreateServerOptions.Builder.withMetadata;
import java.util.Map; import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.cloudservers.CloudServersClient;
import org.jclouds.cloudservers.domain.Server;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.cloudservers.CloudServersClient;
import org.jclouds.cloudservers.domain.Server;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -53,8 +54,9 @@ public class CloudServersCreateNodeWithGroupEncodedIntoName implements CreateNod
@Override @Override
public NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template) { public NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template) {
Server from = client.createServer(name, Integer.parseInt(template.getImage().getProviderId()), Integer Server from = client.createServer(name, Integer.parseInt(template.getImage().getProviderId()),
.parseInt(template.getHardware().getProviderId())); Integer.parseInt(template.getHardware().getProviderId()),
withMetadata(template.getOptions().getUserMetadata()));
credentialStore.put("node#" + from.getId(), new Credentials("root", from.getAdminPass())); credentialStore.put("node#" + from.getId(), new Credentials("root", from.getAdminPass()));
return serverToNodeMetadata.apply(from); return serverToNodeMetadata.apply(from);
} }

View File

@ -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;

View File

@ -40,7 +40,7 @@ import com.google.inject.Module;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", enabled = true, sequential = true) @Test(groups = "live", enabled = true, singleThreaded = true, testName = "CloudServersComputeServiceLiveTest")
public class CloudServersComputeServiceLiveTest extends BaseComputeServiceLiveTest { public class CloudServersComputeServiceLiveTest extends BaseComputeServiceLiveTest {
public CloudServersComputeServiceLiveTest() { public CloudServersComputeServiceLiveTest() {
provider = "cloudservers"; provider = "cloudservers";
@ -54,12 +54,12 @@ public class CloudServersComputeServiceLiveTest extends BaseComputeServiceLiveTe
public void testAssignability() throws Exception { public void testAssignability() throws Exception {
@SuppressWarnings("unused") @SuppressWarnings("unused")
RestContext<CloudServersClient, CloudServersAsyncClient> tmContext = new ComputeServiceContextFactory() RestContext<CloudServersClient, CloudServersAsyncClient> tmContext = new ComputeServiceContextFactory()
.createContext(provider, identity, credential).getProviderSpecificContext(); .createContext(provider, identity, credential).getProviderSpecificContext();
} }
@Override @Override
protected void checkNodes(Iterable<? extends NodeMetadata> nodes, String tag) throws IOException { protected void checkNodes(Iterable<? extends NodeMetadata> nodes, String group, String task) throws IOException {
super.checkNodes(nodes, tag); super.checkNodes(nodes, group, task);
for (NodeMetadata node : nodes) { for (NodeMetadata node : nodes) {
assertEquals(node.getLocation().getScope(), LocationScope.HOST); assertEquals(node.getLocation().getScope(), LocationScope.HOST);
} }

139
apis/cloudsigma/pom.xml Normal file
View File

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId>
<version>1.3.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath>
</parent>
<groupId>org.jclouds.api</groupId>
<artifactId>cloudsigma</artifactId>
<name>jclouds CloudSigma API</name>
<description>ComputeService binding to the CloudSigma API</description>
<packaging>bundle</packaging>
<properties>
<test.cloudsigma.endpoint>https://api.cloudsigma.com</test.cloudsigma.endpoint>
<test.cloudsigma.apiversion>1.0</test.cloudsigma.apiversion>
<test.cloudsigma.identity>FIXME</test.cloudsigma.identity>
<test.cloudsigma.credential>FIXME</test.cloudsigma.credential>
</properties>
<dependencies>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-compute</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-sshj</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-compute</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-log4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<systemProperties>
<property>
<name>test.cloudsigma.endpoint</name>
<value>${test.cloudsigma.endpoint}</value>
</property>
<property>
<name>test.cloudsigma.apiversion</name>
<value>${test.cloudsigma.apiversion}</value>
</property>
<property>
<name>test.cloudsigma.identity</name>
<value>${test.cloudsigma.identity}</value>
</property>
<property>
<name>test.cloudsigma.credential</name>
<value>${test.cloudsigma.credential}</value>
</property>
<property>
<name>jclouds.compute.blacklist-nodes</name>
<value>${jclouds.compute.blacklist-nodes}</value>
</property>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Export-Package>org.jclouds.cloudsigma.*;version="${project.version}"</Export-Package>
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -70,7 +70,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* <p/> * <p/>
* *
* @see CloudSigmaClient * @see CloudSigmaClient
* @see <a href="TODO: insert URL of provider documentation" /> * @see <a href="http://cloudsigma.com/en/platform-details/the-api" />
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(BasicAuthentication.class) @RequestFilters(BasicAuthentication.class)

View File

@ -32,7 +32,6 @@ import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.cloudsigma.CloudSigmaAsyncClient;
import org.jclouds.cloudsigma.CloudSigmaClient; import org.jclouds.cloudsigma.CloudSigmaClient;
import org.jclouds.cloudsigma.domain.Device; import org.jclouds.cloudsigma.domain.Device;
import org.jclouds.cloudsigma.domain.DriveInfo; import org.jclouds.cloudsigma.domain.DriveInfo;
@ -60,33 +59,35 @@ import org.jclouds.logging.Logger;
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.Predicates; import com.google.common.base.Predicates;
import com.google.common.cache.Cache;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
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.Futures;
import com.google.common.util.concurrent.UncheckedExecutionException;
/** /**
* defines the connection between the {@link CloudSigmaClient} implementation and the jclouds * defines the connection between the {@link CloudSigmaClient} implementation
* {@link ComputeService} * and the jclouds {@link ComputeService}
* *
*/ */
@Singleton @Singleton
public class CloudSigmaComputeServiceAdapter implements public class CloudSigmaComputeServiceAdapter implements
ComputeServiceAdapter<ServerInfo, Hardware, DriveInfo, Location> { ComputeServiceAdapter<ServerInfo, Hardware, DriveInfo, Location> {
private static final Predicate<DriveInfo> PREINSTALLED_DISK = Predicates.and(Predicates.notNull(), private static final Predicate<DriveInfo> PREINSTALLED_DISK = Predicates.and(Predicates.notNull(),
new Predicate<DriveInfo>() { new Predicate<DriveInfo>() {
@Override @Override
public boolean apply(DriveInfo drive) { public boolean apply(DriveInfo drive) {
return drive.getType().equals(DriveType.DISK) && drive.getDriveType().contains("preinstalled"); return drive.getType().equals(DriveType.DISK) && drive.getDriveType().contains("preinstalled");
} }
}); });
private final CloudSigmaClient client; private final CloudSigmaClient client;
private final CloudSigmaAsyncClient aclient;
private final Predicate<DriveInfo> driveNotClaimed; private final Predicate<DriveInfo> driveNotClaimed;
private final JustProvider locationSupplier; private final JustProvider locationSupplier;
private final String defaultVncPassword; private final String defaultVncPassword;
private final Map<String, DriveInfo> cache; private final Cache<String, DriveInfo> cache;
private final ExecutorService executor; private final ExecutorService executor;
@Resource @Resource
@ -94,12 +95,10 @@ public class CloudSigmaComputeServiceAdapter implements
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
@Inject @Inject
public CloudSigmaComputeServiceAdapter(CloudSigmaClient client, CloudSigmaAsyncClient aclient, public CloudSigmaComputeServiceAdapter(CloudSigmaClient client, Predicate<DriveInfo> driveNotClaimed,
Predicate<DriveInfo> driveNotClaimed, JustProvider locationSupplier, JustProvider locationSupplier, @Named(CloudSigmaConstants.PROPERTY_VNC_PASSWORD) String defaultVncPassword,
@Named(CloudSigmaConstants.PROPERTY_VNC_PASSWORD) String defaultVncPassword, Map<String, DriveInfo> cache, Cache<String, DriveInfo> cache, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
this.client = checkNotNull(client, "client"); this.client = checkNotNull(client, "client");
this.aclient = checkNotNull(aclient, "aclient");
this.driveNotClaimed = checkNotNull(driveNotClaimed, "driveNotClaimed"); this.driveNotClaimed = checkNotNull(driveNotClaimed, "driveNotClaimed");
this.locationSupplier = checkNotNull(locationSupplier, "locationSupplier"); this.locationSupplier = checkNotNull(locationSupplier, "locationSupplier");
this.defaultVncPassword = checkNotNull(defaultVncPassword, "defaultVncPassword"); this.defaultVncPassword = checkNotNull(defaultVncPassword, "defaultVncPassword");
@ -109,21 +108,20 @@ public class CloudSigmaComputeServiceAdapter implements
@Override @Override
public ServerInfo createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, public ServerInfo createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template,
Map<String, Credentials> credentialStore) { Map<String, Credentials> credentialStore) {
long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024l); long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024l);
logger.debug(">> imaging boot drive source(%s) bytes(%d)", template.getImage().getId(), bootSize); logger.debug(">> imaging boot drive source(%s) bytes(%d)", template.getImage().getId(), bootSize);
DriveInfo drive = client.cloneDrive(template.getImage().getId(), template.getImage().getId(), DriveInfo drive = client.cloneDrive(template.getImage().getId(), template.getImage().getId(),
new CloneDriveOptions().size(bootSize)); new CloneDriveOptions().size(bootSize));
boolean success = driveNotClaimed.apply(drive); boolean success = driveNotClaimed.apply(drive);
logger.debug("<< image(%s) complete(%s)", drive.getUuid(), success); logger.debug("<< image(%s) complete(%s)", drive.getUuid(), success);
if (!success) { if (!success) {
client.destroyDrive(drive.getUuid()); client.destroyDrive(drive.getUuid());
throw new IllegalStateException("could not image drive in time!"); throw new IllegalStateException("could not image drive in time!");
} }
cache.put(drive.getUuid(), drive);
Server toCreate = Servers.small(name, drive.getUuid(), defaultVncPassword).mem(template.getHardware().getRam()) Server toCreate = Servers.small(name, drive.getUuid(), defaultVncPassword).mem(template.getHardware().getRam())
.cpu((int) (template.getHardware().getProcessors().get(0).getSpeed())).build(); .cpu((int) (template.getHardware().getProcessors().get(0).getSpeed())).build();
logger.debug(">> creating server"); logger.debug(">> creating server");
ServerInfo from = client.createServer(toCreate); ServerInfo from = client.createServer(toCreate);
@ -131,7 +129,7 @@ public class CloudSigmaComputeServiceAdapter implements
logger.debug(">> starting server(%s)", from.getUuid()); logger.debug(">> starting server(%s)", from.getUuid());
client.startServer(from.getUuid()); client.startServer(from.getUuid());
// store the credentials so that later functions can use them // store the credentials so that later functions can use them
credentialStore.put("node#"+ from.getUuid(), new Credentials("cloudsigma", "cloudsigma")); credentialStore.put("node#" + from.getUuid(), new Credentials("root", defaultVncPassword));
return from; return from;
} }
@ -155,30 +153,39 @@ public class CloudSigmaComputeServiceAdapter implements
return "sizeLessThanOrEqual(" + size + ")"; return "sizeLessThanOrEqual(" + size + ")";
} }
}).ids(id).ram(ram).processors(ImmutableList.of(new Processor(1, cpu))).volumes( }).ids(id).ram(ram).processors(ImmutableList.of(new Processor(1, cpu)))
ImmutableList.<Volume> of(new VolumeImpl(size, true, true))).build()); .volumes(ImmutableList.<Volume> of(new VolumeImpl(size, true, true))).build());
} }
return hardware.build(); return hardware.build();
} }
/** /**
* look up the current standard images and do not error out, if they are not found. * look up the current standard images and do not error out, if they are not
* found.
*/ */
@Override @Override
public Iterable<DriveInfo> listImages() { public Iterable<DriveInfo> listImages() {
Iterable<DriveInfo> drives = transformParallel(client.listStandardDrives(), Iterable<DriveInfo> drives = transformParallel(client.listStandardDrives(),
new Function<String, Future<DriveInfo>>() { new Function<String, Future<DriveInfo>>() {
@Override @Override
public Future<DriveInfo> apply(String input) { public Future<DriveInfo> apply(String input) {
return aclient.getDriveInfo(input); try {
return Futures.immediateFuture(cache.getUnchecked(input));
} catch (NullPointerException e) {
logger.debug("drive %s not found", input);
} catch (UncheckedExecutionException e) {
logger.warn(e, "error finding drive %s: %s", input, e.getMessage());
} }
return Futures.immediateFuture(null);
}
}, executor, null, logger, "drives"); @Override
Iterable<DriveInfo> returnVal = filter(drives, PREINSTALLED_DISK); public String toString() {
for (DriveInfo drive : returnVal) return "seedDriveCache()";
cache.put(drive.getUuid(), drive); }
return returnVal; }, executor, null, logger, "drives");
return filter(drives, PREINSTALLED_DISK);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@ -18,9 +18,6 @@
*/ */
package org.jclouds.cloudsigma.compute.config; package org.jclouds.cloudsigma.compute.config;
import static org.jclouds.compute.domain.OsFamily.UBUNTU;
import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.inject.Inject; import javax.inject.Inject;
@ -45,6 +42,7 @@ import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
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;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.OsFamilyVersion64Bit; import org.jclouds.compute.domain.OsFamilyVersion64Bit;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.domain.Volume; import org.jclouds.compute.domain.Volume;
@ -58,7 +56,9 @@ import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
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.collect.MapMaker; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Provides; import com.google.inject.Provides;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
@ -77,7 +77,7 @@ public class CloudSigmaComputeServiceContextModule
@Override @Override
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) { protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
return template.osFamily(UBUNTU).osVersionMatches("1[10].[10][04]").os64Bit(true).minRam(1024); return template.osFamily(OsFamily.UBUNTU).imageNameMatches(".*automated SSH Access.*");
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@ -108,12 +108,12 @@ public class CloudSigmaComputeServiceContextModule
@Provides @Provides
@Singleton @Singleton
protected Map<String, DriveInfo> cache(GetDrive getDrive) { protected Cache<String, DriveInfo> cache(GetDrive getDrive) {
return new MapMaker().makeComputingMap(getDrive); return CacheBuilder.newBuilder().build(getDrive);
} }
@Singleton @Singleton
public static class GetDrive implements Function<String, DriveInfo> { public static class GetDrive extends CacheLoader<String, DriveInfo> {
private final CloudSigmaClient client; private final CloudSigmaClient client;
@Inject @Inject
@ -122,7 +122,7 @@ public class CloudSigmaComputeServiceContextModule
} }
@Override @Override
public DriveInfo apply(String input) { public DriveInfo load(String input) {
return client.getDriveInfo(input); return client.getDriveInfo(input);
} }
} }

View File

@ -53,7 +53,8 @@ public class ParseOsFamilyVersion64BitFromImageName implements Function<String,
} }
// ex CentOS 5.5 Linux 64bit Preinstalled System with AppFirst Monitoring // ex CentOS 5.5 Linux 64bit Preinstalled System with AppFirst Monitoring
public static final Pattern PATTERN = Pattern.compile("([^ ]+)[^0-9]([0-9.]+) .*"); // ex. Centos-5.6-20110917 pub
public static final Pattern PATTERN = Pattern.compile("([^ -]+)[^0-9]([0-9.]+)[ -].*");
@Override @Override
public OsFamilyVersion64Bit apply(String input) { public OsFamilyVersion64Bit apply(String input) {

View File

@ -56,8 +56,9 @@ public class PreinstalledDiskToImage implements Function<DriveInfo, Image> {
String description = drive.getDescription() != null ? drive.getDescription() : drive.getName(); String description = drive.getDescription() != null ? drive.getDescription() : drive.getName();
Builder builder = OperatingSystem.builder(); Builder builder = OperatingSystem.builder();
OsFamilyVersion64Bit parsed = imageParser.apply(drive.getName()); OsFamilyVersion64Bit parsed = imageParser.apply(drive.getName());
builder.name(drive.getName()).description(description).is64Bit(parsed.is64Bit).version(parsed.version).family( builder.name(drive.getName()).description(description)
parsed.family); .is64Bit(drive.getBits() != null ? drive.getBits() == 64 : parsed.is64Bit).version(parsed.version)
.family(parsed.family);
return new ImageBuilder().ids(drive.getUuid()).adminPassword("cloudsigma").userMetadata( return new ImageBuilder().ids(drive.getUuid()).adminPassword("cloudsigma").userMetadata(
ImmutableMap.<String, String> of("size", drive.getSize() / 1024 / 1024 / 1024 + "")).defaultCredentials( ImmutableMap.<String, String> of("size", drive.getSize() / 1024 / 1024 / 1024 + "")).defaultCredentials(
new Credentials("cloudsigma", "cloudsigma")).location(locationSupplier.get()).name(drive.getName()) new Credentials("cloudsigma", "cloudsigma")).location(locationSupplier.get()).name(drive.getName())

View File

@ -25,6 +25,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -45,13 +46,16 @@ import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.VolumeBuilder; import org.jclouds.compute.domain.VolumeBuilder;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
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;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
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.util.concurrent.UncheckedExecutionException;
/** /**
* @author Adrian Cole * @author Adrian Cole
@ -113,10 +117,13 @@ public class ServerInfoToNodeMetadata implements Function<ServerInfo, NodeMetada
@Singleton @Singleton
public static final class DeviceToVolume implements Function<Device, Volume> { public static final class DeviceToVolume implements Function<Device, Volume> {
private final Map<String, DriveInfo> cache; @Resource
protected Logger logger = Logger.NULL;
private final Cache<String, DriveInfo> cache;
@Inject @Inject
public DeviceToVolume(Map<String, DriveInfo> cache) { public DeviceToVolume(Cache<String, DriveInfo> cache) {
this.cache = checkNotNull(cache, "cache"); this.cache = checkNotNull(cache, "cache");
} }
@ -124,9 +131,13 @@ public class ServerInfoToNodeMetadata implements Function<ServerInfo, NodeMetada
public Volume apply(Device input) { public Volume apply(Device input) {
VolumeBuilder builder = new VolumeBuilder(); VolumeBuilder builder = new VolumeBuilder();
builder.id(input.getId()); builder.id(input.getId());
DriveInfo drive = cache.get(input.getDriveUuid()); try {
if (drive != null) { DriveInfo drive = cache.getUnchecked(input.getDriveUuid());
builder.size(drive.getSize() / 1024 / 1024f); builder.size(drive.getSize() / 1024 / 1024f);
} catch (NullPointerException e) {
logger.debug("drive %s not found", input.getDriveUuid());
} catch (UncheckedExecutionException e) {
logger.warn(e, "error finding drive %s: %s", input.getDriveUuid(), e.getMessage());
} }
return new VolumeBuilder().durable(true).type(Volume.Type.NAS).build(); return new VolumeBuilder().durable(true).type(Volume.Type.NAS).build();
} }
@ -141,10 +152,13 @@ public class ServerInfoToNodeMetadata implements Function<ServerInfo, NodeMetada
*/ */
@Singleton @Singleton
public static class GetImageIdFromServer implements Function<Server, String> { public static class GetImageIdFromServer implements Function<Server, String> {
private final Map<String, DriveInfo> cache; @Resource
protected Logger logger = Logger.NULL;
private final Cache<String, DriveInfo> cache;
@Inject @Inject
public GetImageIdFromServer(Map<String, DriveInfo> cache) { public GetImageIdFromServer(Cache<String, DriveInfo> cache) {
this.cache = cache; this.cache = cache;
} }
@ -155,9 +169,12 @@ public class ServerInfoToNodeMetadata implements Function<ServerInfo, NodeMetada
Device bootDevice = from.getDevices().get(bootDeviceId); Device bootDevice = from.getDevices().get(bootDeviceId);
if (bootDevice != null) { if (bootDevice != null) {
try { try {
imageId = cache.get(bootDevice.getDriveUuid()).getName(); DriveInfo drive = cache.getUnchecked(bootDevice.getDriveUuid());
imageId = drive.getName();
} catch (NullPointerException e) { } catch (NullPointerException e) {
logger.debug("drive %s not found", bootDevice.getDriveUuid());
} catch (UncheckedExecutionException e) {
logger.warn(e, "error finding drive %s: %s", bootDevice.getDriveUuid(), e.getMessage());
} }
} }
return imageId; return imageId;

View File

@ -22,7 +22,7 @@ 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 com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;

View File

@ -22,7 +22,7 @@ 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 com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;

View File

@ -18,7 +18,7 @@
*/ */
package org.jclouds.cloudsigma.domain; package org.jclouds.cloudsigma.domain;
import javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
/** /**
* *

View File

@ -23,7 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI; import java.net.URI;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;

View File

@ -22,7 +22,7 @@ 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 com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;

View File

@ -22,7 +22,7 @@ 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 com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;

View File

@ -24,7 +24,7 @@ import java.util.List;
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.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;

View File

@ -21,7 +21,7 @@ package org.jclouds.cloudsigma.domain;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
/** /**
* *

View File

@ -22,7 +22,7 @@ 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 com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudsigma.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;
/** /**
* *

View File

@ -18,7 +18,7 @@
*/ */
package org.jclouds.cloudsigma.domain; package org.jclouds.cloudsigma.domain;
import javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
/** /**
* *

Some files were not shown because too many files have changed in this diff Show More