added tags to nodemetadata, revised byon to be persistable to blobstore

This commit is contained in:
Adrian Cole 2011-05-16 00:46:02 -07:00
parent ddc514d602
commit 08ee5d5c8d
28 changed files with 767 additions and 155 deletions

View File

@ -44,6 +44,7 @@ public class Node {
private String osFamily;
private String osDescription;
private String osVersion;
private boolean os64Bit;
private String group;
private Set<String> tags = ImmutableSet.of();
private String username;
@ -96,6 +97,11 @@ public class Node {
return this;
}
public Builder os64Bit(boolean os64Bit) {
this.os64Bit = os64Bit;
return this;
}
public Builder group(String group) {
this.group = group;
return this;
@ -128,13 +134,13 @@ public class Node {
public Node build() {
return new Node(id, name, description, hostname, locationId, osArch, osFamily, osDescription, osVersion,
group, tags, username, credential, credentialUrl, sudoPassword);
os64Bit, group, tags, username, credential, credentialUrl, sudoPassword);
}
}
public Node(String id, String name, String description, String hostname, String locationId, String osArch,
String osFamily, String osDescription, String osVersion, String group, Iterable<String> tags,
String username, String credential, URI credentialUrl, String sudoPassword) {
String osFamily, String osDescription, String osVersion, boolean os64Bit, String group,
Iterable<String> tags, String username, String credential, URI credentialUrl, String sudoPassword) {
this.id = id;
this.name = name;
this.description = description;
@ -144,6 +150,7 @@ public class Node {
this.osFamily = osFamily;
this.osDescription = osDescription;
this.osVersion = osVersion;
this.os64Bit = os64Bit;
this.group = group;
this.tags = ImmutableSet.copyOf(tags);
this.username = username;
@ -161,6 +168,7 @@ public class Node {
private final String osFamily;
private final String osDescription;
private final String osVersion;
private final boolean os64Bit;
private final String group;
private final Set<String> tags;
private final String username;
@ -208,6 +216,10 @@ public class Node {
return osVersion;
}
public boolean isOs64Bit() {
return os64Bit;
}
public Set<String> getTags() {
Set<String> tagSet = new HashSet<String>();
for (String tag : tags)
@ -227,15 +239,15 @@ public class Node {
return credentialUrl;
}
public String getSudoPassword() {
return sudoPassword;
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
public String getSudoPassword() {
return sudoPassword;
}
@Override
public boolean equals(Object that) {
if (that == null)
@ -247,9 +259,10 @@ public class Node {
public String toString() {
return Objects.toStringHelper(this).add("id", id).add("name", name).add("description", description).add(
"locationId", locationId).add("hostname", hostname).add("osArch", osArch).add("osFamily", osFamily).add(
"osDescription", osDescription).add("osVersion", osVersion).add("group", group).add("tags", tags).add(
"username", username).add("hasCredential", credential != null || credentialUrl != null).add(
"hasSudoPassword", sudoPassword != null).toString();
"osDescription", osDescription).add("osVersion", osVersion).add("os64Bit", os64Bit).add("group", group)
.add("tags", tags).add("username", username).add("hasCredential",
credential != null || credentialUrl != null).add("hasSudoPassword", sudoPassword != null)
.toString();
}
}

View File

@ -25,7 +25,7 @@ import java.util.Map;
import javax.inject.Singleton;
import org.jclouds.byon.Node;
import org.jclouds.byon.functions.NodesFromYaml;
import org.jclouds.byon.functions.NodesFromYamlStream;
import org.jclouds.byon.internal.BYONComputeServiceAdapter;
import org.jclouds.byon.suppliers.NodesParsedFromSupplier;
import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
@ -72,7 +72,7 @@ public class BYONComputeServiceContextModule extends
}).to(SupplyFromProviderURIOrNodesProperty.class);
// TODO make this somehow overridable via user request
bind(new TypeLiteral<Function<InputStream, Map<String, Node>>>() {
}).to(NodesFromYaml.class);
}).to(NodesFromYamlStream.class);
}
}

View File

@ -0,0 +1,40 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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 java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import com.google.common.annotations.Beta;
/**
* designates the module configures a {@code Map<String, Node>}
*
* @author Adrian Cole
*
*/
@Beta
@Retention(RUNTIME)
@Target(TYPE)
public @interface ConfiguresNodeStore {
}

View File

@ -0,0 +1,92 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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 java.io.InputStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.inject.Singleton;
import org.jclouds.byon.Node;
import org.jclouds.byon.domain.YamlNode;
import org.jclouds.collect.TransformingMap;
import org.jclouds.io.CopyInputStreamInputSupplierMap;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.io.InputSupplier;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
*/
@ConfiguresNodeStore
@Beta
public class YamlNodeStoreModule extends AbstractModule {
private static final Map<String, InputSupplier<InputStream>> BACKING = new ConcurrentHashMap<String, InputSupplier<InputStream>>();
private final Map<String, InputStream> backing;
public YamlNodeStoreModule(Map<String, InputStream> backing) {
this.backing = backing;
}
public YamlNodeStoreModule() {
this(null);
}
@Override
protected void configure() {
bind(new TypeLiteral<Function<YamlNode, InputStream>>() {
}).toInstance(org.jclouds.byon.domain.YamlNode.yamlNodeToInputStream);
bind(new TypeLiteral<Function<InputStream, YamlNode>>() {
}).toInstance(org.jclouds.byon.domain.YamlNode.inputStreamToYamlNode);
bind(new TypeLiteral<Function<Node, YamlNode>>() {
}).toInstance(org.jclouds.byon.domain.YamlNode.nodeToYamlNode);
bind(new TypeLiteral<Function<YamlNode, Node>>() {
}).toInstance(org.jclouds.byon.domain.YamlNode.toNode);
if (backing != null) {
bind(new TypeLiteral<Map<String, InputStream>>() {
}).toInstance(backing);
} else {
bind(new TypeLiteral<Map<String, InputSupplier<InputStream>>>() {
}).toInstance(BACKING);
bind(new TypeLiteral<Map<String, InputStream>>() {
}).to(new TypeLiteral<CopyInputStreamInputSupplierMap>() {
});
}
}
@Provides
@Singleton
protected Map<String, Node> provideNodeStore(Map<String, YamlNode> backing,
Function<Node, YamlNode> yamlSerializer, Function<YamlNode, Node> yamlDeserializer) {
return new TransformingMap<String, YamlNode, Node>(backing, yamlDeserializer, yamlSerializer);
}
@Provides
@Singleton
protected Map<String, YamlNode> provideYamlStore(Map<String, InputStream> backing,
Function<YamlNode, InputStream> yamlSerializer, Function<InputStream, YamlNode> yamlDeserializer) {
return new TransformingMap<String, InputStream, YamlNode>(backing, yamlDeserializer, yamlSerializer);
}
}

View File

@ -0,0 +1,199 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.domain;
import java.io.InputStream;
import java.net.URI;
import java.util.List;
import org.jclouds.byon.Node;
import org.jclouds.util.Strings2;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Loader;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.io.Closeables;
/**
* Serializes to the following
*
* <pre>
* id: cluster-1
* name: cluster-1
* description: xyz
* hostname: cluster-1.mydomain.com
* location_id: virginia
* os_arch: x86
* os_family: linux
* os_description: redhat
* os_version: 5.3
* os_64bit: 5.3
* group: hadoop
* tags:
* - vanilla
* username: kelvin
* credential: password_or_rsa
* or
* credential_url: password_or_rsa_file ex. resource:///id_rsa will get the classpath /id_rsa; file://path/to/id_rsa
* sudo_password: password
* </pre>
*
* @author Kelvin Kakugawa
* @author Adrian Cole
*/
public class YamlNode {
public String id;
public String name;
public String description;
public String hostname;
public String location_id;
public String os_arch;
public String os_family;
public String os_description;
public String os_version;
public boolean os_64bit;
public String group;
public List<String> tags = Lists.newArrayList();
public String username;
public String credential;
public String credential_url;
public String sudo_password;
public static Function<YamlNode, Node> toNode = new Function<YamlNode, Node>() {
@Override
public Node apply(YamlNode arg0) {
if (arg0 == null)
return null;
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(
arg0.os_description).osVersion(arg0.os_version).os64Bit(arg0.os_64bit).group(arg0.group)
.tags(arg0.tags).username(arg0.username).credential(arg0.credential).credentialUrl(
arg0.credential_url != null ? URI.create(arg0.credential_url) : null).sudoPassword(
arg0.sudo_password).build();
}
};
public Node toNode() {
return toNode.apply(this);
}
public static Function<InputStream, YamlNode> inputStreamToYamlNode = new Function<InputStream, YamlNode>() {
@Override
public YamlNode apply(InputStream in) {
if (in == null)
return null;
// note that snakeyaml also throws nosuchmethod error when you use the non-deprecated
// constructor
try {
return (YamlNode) new Yaml(new Loader(new Constructor(YamlNode.class))).load(in);
} finally {
Closeables.closeQuietly(in);
}
}
};
public static YamlNode fromYaml(InputStream in) {
return inputStreamToYamlNode.apply(in);
}
public static Function<YamlNode, InputStream> yamlNodeToInputStream = new Function<YamlNode, InputStream>() {
@Override
public InputStream apply(YamlNode in) {
if (in == null)
return null;
Builder<String, Object> prettier = ImmutableMap.<String, Object> builder();
if (in.id != null)
prettier.put("id", in.id);
if (in.name != null)
prettier.put("name", in.name);
if (in.description != null)
prettier.put("description", in.description);
if (in.hostname != null)
prettier.put("hostname", in.hostname);
if (in.location_id != null)
prettier.put("location_id", in.location_id);
if (in.os_arch != null)
prettier.put("os_arch", in.os_arch);
if (in.os_family != null)
prettier.put("os_family", in.os_family);
if (in.os_description != null)
prettier.put("os_description", in.os_description);
if (in.os_version != null)
prettier.put("os_version", in.os_version);
if (in.os_64bit)
prettier.put("os_64bit", in.os_64bit);
if (in.group != null)
prettier.put("group", in.group);
if (in.tags.size() != 0)
prettier.put("tags", in.tags);
if (in.username != null)
prettier.put("username", in.username);
if (in.credential != null)
prettier.put("credential", in.credential);
if (in.credential_url != null)
prettier.put("credential_url", in.credential_url);
if (in.sudo_password != null)
prettier.put("sudo_password", in.sudo_password);
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
return Strings2.toInputStream(new Yaml(options).dump(prettier.build()));
}
};
public InputStream toYaml() {
return yamlNodeToInputStream.apply(this);
}
public static YamlNode fromNode(Node in) {
return nodeToYamlNode.apply(in);
}
public static Function<Node, YamlNode> nodeToYamlNode = new Function<Node, YamlNode>() {
@Override
public YamlNode apply(Node arg0) {
if (arg0 == null)
return null;
YamlNode yaml = new YamlNode();
yaml.id = arg0.getId();
yaml.name = arg0.getName();
yaml.description = arg0.getDescription();
yaml.hostname = arg0.getHostname();
yaml.location_id = arg0.getLocationId();
yaml.os_arch = arg0.getOsArch();
yaml.os_family = arg0.getOsFamily();
yaml.os_description = arg0.getOsDescription();
yaml.os_version = arg0.getOsVersion();
yaml.os_64bit = arg0.isOs64Bit();
yaml.group = arg0.getGroup();
yaml.tags = ImmutableList.copyOf(arg0.getTags());
yaml.username = arg0.getUsername();
yaml.credential = arg0.getCredential();
yaml.credential_url = arg0.getCredentialUrl() != null ? arg0.getCredentialUrl().toASCIIString() : null;
yaml.sudo_password = arg0.getSudoPassword();
return yaml;
}
};
}

View File

@ -81,7 +81,7 @@ public class NodeToNodeMetadata implements Function<Node, NodeMetadata> {
builder.name(from.getName());
builder.location(findLocationWithId(from.getLocationId()));
builder.group(from.getGroup());
// TODO add tags!
builder.tags(from.getTags());
builder.operatingSystem(OperatingSystem.builder().arch(from.getOsArch()).family(
OsFamily.fromValue(from.getOsFamily())).description(from.getOsDescription())
.version(from.getOsVersion()).build());

View File

@ -21,13 +21,13 @@ package org.jclouds.byon.functions;
import static com.google.common.base.Preconditions.checkState;
import java.io.InputStream;
import java.net.URI;
import java.util.List;
import java.util.Map;
import javax.inject.Singleton;
import org.jclouds.byon.Node;
import org.jclouds.byon.domain.YamlNode;
import org.yaml.snakeyaml.Loader;
import org.yaml.snakeyaml.TypeDescription;
import org.yaml.snakeyaml.Yaml;
@ -35,7 +35,6 @@ import org.yaml.snakeyaml.constructor.Constructor;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
@ -66,38 +65,14 @@ import com.google.common.collect.Maps;
* @author Adrian Cole
*/
@Singleton
public class NodesFromYaml implements Function<InputStream, Map<String, Node>> {
public class NodesFromYamlStream implements Function<InputStream, Map<String, Node>> {
/**
* Type-safe config class for YAML
*
*/
public static class Config {
public List<CrappyNode> nodes;
}
// crappy, as snakeyaml..
// 1. complains on illegalaccesserror for extends Constructor.ConstructMapping, so we can't use a
// real constructor
// 2. cannot set non-public fields, or fill non-public classes
// 3. doesn't support a SerializedName annotation, so your fields need to be named the same as
// the text
public static class CrappyNode {
public String id;
public String name;
public String description;
public String hostname;
public String location_id;
public String os_arch;
public String os_family;
public String os_description;
public String os_version;
public String group;
public List<String> tags = Lists.newArrayList();
public String username;
public String credential;
public String credential_url;
public String sudo_password;
public List<YamlNode> nodes;
}
@Override
@ -105,12 +80,12 @@ public class NodesFromYaml implements Function<InputStream, Map<String, Node>> {
Constructor constructor = new Constructor(Config.class);
TypeDescription nodeDesc = new TypeDescription(CrappyNode.class);
TypeDescription nodeDesc = new TypeDescription(YamlNode.class);
nodeDesc.putListPropertyType("tags", String.class);
constructor.addTypeDescription(nodeDesc);
TypeDescription configDesc = new TypeDescription(Config.class);
configDesc.putListPropertyType("nodes", CrappyNode.class);
configDesc.putListPropertyType("nodes", YamlNode.class);
constructor.addTypeDescription(configDesc);
// note that snakeyaml also throws nosuchmethod error when you use the non-deprecated
// constructor
@ -119,19 +94,7 @@ public class NodesFromYaml implements Function<InputStream, Map<String, Node>> {
checkState(config != null, "missing config: class");
checkState(config.nodes != null, "missing nodes: collection");
return Maps.uniqueIndex(Iterables.transform(config.nodes, new Function<CrappyNode, Node>() {
@Override
public Node apply(CrappyNode arg0) {
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(arg0.os_description).osVersion(arg0.os_version).group(
arg0.group).tags(arg0.tags).username(arg0.username).credential(arg0.credential)
.credentialUrl(arg0.credential_url != null ? URI.create(arg0.credential_url) : null).sudoPassword(
arg0.sudo_password).build();
}
}), new Function<Node, String>() {
return Maps.uniqueIndex(Iterables.transform(config.nodes, YamlNode.toNode), new Function<Node, String>() {
public String apply(Node node) {
return node.getId();
}

View File

@ -0,0 +1,163 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.jclouds.byon.Node;
import org.jclouds.io.CopyInputStreamInputSupplierMap;
import org.jclouds.util.Strings2;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.yaml.snakeyaml.Yaml;
import com.google.common.io.InputSupplier;
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)
public class YamlNodeStoreModuleTest {
Yaml json = createInjector().getInstance(Yaml.class);
@DataProvider(name = "names")
public Object[][] createData() {
return new Object[][] { { "instance1", "bear" }, { "instance2", "apple" }, { "instance2", "francis" },
{ "instance4", "robot" } };
}
@Test(dataProvider = "names")
public void deleteObject(String id, String name) throws InterruptedException, IOException {
Injector injector = createInjector();
Map<String, InputStream> map = getMap(injector);
check(map, getStore(injector), "i-20312", id, name);
}
public void testProvidedMapWithValue() throws IOException {
Map<String, InputStream> map = new CopyInputStreamInputSupplierMap(
new ConcurrentHashMap<String, InputSupplier<InputStream>>());
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");
remove(map, getStore(createInjectorWithProvidedMap(map)), "test");
}
public void testProvidedConsistentAcrossRepeatedWrites() throws IOException {
Map<String, InputStream> map = new CopyInputStreamInputSupplierMap(
new ConcurrentHashMap<String, InputSupplier<InputStream>>());
Injector injector = createInjectorWithProvidedMap(map);
assertEquals(injector.getInstance(Key.get(new TypeLiteral<Map<String, InputStream>>() {
})), map);
Map<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, InputStream> map = new CopyInputStreamInputSupplierMap(
new ConcurrentHashMap<String, InputSupplier<InputStream>>());
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 testDefaultConsistentAcrossMultipleInjectors() throws IOException {
Map<String, InputStream> map = getMap(createInjector());
put(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");
}
protected Map<String, Node> getStore(Injector injector) {
return injector.getInstance(Key.get(new TypeLiteral<Map<String, Node>>() {
}));
}
protected Map<String, InputStream> getMap(Injector injector) {
return injector.getInstance(Key.get(new TypeLiteral<Map<String, InputStream>>() {
}));
}
protected Injector createInjectorWithProvidedMap(Map<String, InputStream> map) {
return Guice.createInjector(new YamlNodeStoreModule(map));
}
protected Injector createInjector() {
return Guice.createInjector(new YamlNodeStoreModule());
}
protected void check(Map<String, InputStream> map, Map<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);
}
protected void remove(Map<String, InputStream> map, Map<String, Node> store, String key) {
store.remove(key);
assertEquals(store.size(), 0);
assertEquals(map.size(), 0);
assertEquals(store.get(key), null);
assertEquals(map.get(key), null);
}
protected void checkConsistent(Map<String, InputStream> map, Map<String, Node> store, String key, String id,
String name) throws IOException {
assertEquals(store.size(), 1);
assertEquals(map.size(), 1);
// checkRepeatedRead
assertEquals(store.get(key), Node.builder().id(id).name(name).build());
assertEquals(store.get(key), Node.builder().id(id).name(name).build());
// checkRepeatedRead
checkToYaml(map, key, id, name);
checkToYaml(map, key, id, name);
}
protected void checkToYaml(Map<String, InputStream> map, String key, String id, String name) throws IOException {
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) {
assertEquals(store.size(), 0);
assertEquals(map.size(), 0);
store.put(key, Node.builder().id(id).name(name).build());
}
}

View File

@ -41,22 +41,22 @@ public class NodesFromYamlTest {
.toString();
public static final Node TEST1 = new Node("cluster-1", "cluster-1", "accounting analytics cluster",
"cluster-1.mydomain.com", null, "x86", "rhel", "redhat", "5.3", "hadoop", ImmutableList.of("vanilla"),
"cluster-1.mydomain.com", null, "x86", "rhel", "redhat", "5.3", false, "hadoop", ImmutableList.of("vanilla"),
"myUser", key, null, "happy bear");
public static final Node TEST2 = new Node("cluster-1", "cluster-1", "accounting analytics cluster",
"cluster-1.mydomain.com", "virginia", "x86", "rhel", "redhat", "5.3", "hadoop",
"cluster-1.mydomain.com", "virginia", "x86", "rhel", "redhat", "5.3", false, "hadoop",
ImmutableList.of("vanilla"), "myUser", key, null, "happy bear");
public static final Node TEST3 = new Node("cluster-2", "cluster-2", "accounting analytics cluster",
"cluster-2.mydomain.com", "maryland", "x86", "rhel", "redhat", "5.3", "hadoop",
"cluster-2.mydomain.com", "maryland", "x86", "rhel", "redhat", "5.3", false, "hadoop",
ImmutableList.of("vanilla"), "myUser", key, null, "happy bear");
@Test
public void testNodesParse() throws Exception {
InputStream is = getClass().getResourceAsStream("/test1.yaml");
NodesFromYaml parser = new NodesFromYaml();
NodesFromYamlStream parser = new NodesFromYamlStream();
assertEquals(parser.apply(is), ImmutableMap.of(TEST1.getId(), TEST1));
}
@ -65,7 +65,7 @@ public class NodesFromYamlTest {
public void testNodesParseLocation() throws Exception {
InputStream is = getClass().getResourceAsStream("/test_location.yaml");
NodesFromYaml parser = new NodesFromYaml();
NodesFromYamlStream parser = new NodesFromYamlStream();
assertEquals(parser.apply(is), ImmutableMap.of(TEST2.getId(), TEST2, TEST3.getId(), TEST3));
}
@ -74,14 +74,14 @@ public class NodesFromYamlTest {
public void testNodesParseWhenCredentialInUrl() throws Exception {
InputStream is = getClass().getResourceAsStream("/test_with_url.yaml");
NodesFromYaml parser = new NodesFromYaml();
NodesFromYamlStream parser = new NodesFromYamlStream();
assertEquals(parser.apply(is), ImmutableMap.of(TEST1.getId(), TEST1));
}
@Test(expectedExceptions = IllegalStateException.class)
public void testMustParseSomething() throws Exception {
new NodesFromYaml().apply(Strings2.toInputStream(""));
new NodesFromYamlStream().apply(Strings2.toInputStream(""));
}
}

View File

@ -18,7 +18,7 @@
*/
package org.jclouds.byon.suppliers;
import org.jclouds.byon.functions.NodesFromYaml;
import org.jclouds.byon.functions.NodesFromYamlStream;
import org.jclouds.util.Strings2;
import org.testng.annotations.Test;
@ -33,7 +33,7 @@ public class NodesParsedFromSupplierTest {
@Test(expectedExceptions = IllegalStateException.class)
public void testMustParseSomething() throws Exception {
new NodesParsedFromSupplier(Suppliers.ofInstance(Strings2.toInputStream("nodes:\n")), new NodesFromYaml()).get();
new NodesParsedFromSupplier(Suppliers.ofInstance(Strings2.toInputStream("nodes:\n")), new NodesFromYamlStream()).get();
}
}

View File

@ -65,7 +65,7 @@ public class Volume implements Comparable<Volume> {
}
public static enum Status {
CREATING, AVAILABLE, IN_USE, DELETING, UNRECOGNIZED;
CREATING, AVAILABLE, IN_USE, DELETING, ERROR, UNRECOGNIZED;
public String value() {
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name());
}

View File

@ -66,7 +66,7 @@ import static org.testng.Assert.assertEquals;
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "NovaAsyncClientTest")
@Test(groups = "unit", singleThreaded = true, testName = "NovaAsyncClientTest")
public class NovaAsyncClientTest extends RestClientTest<NovaAsyncClient> {
private static final Class<? extends ListOptions[]> listOptionsVarargsClass = new ListOptions[]{}.getClass();
private static final Class<? extends CreateServerOptions[]> createServerOptionsVarargsClass = new CreateServerOptions[]{}

View File

@ -18,6 +18,10 @@
*/
package org.jclouds.compute.domain;
import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
import org.jclouds.domain.ResourceMetadata;
@ -30,24 +34,23 @@ import com.google.inject.ImplementedBy;
@ImplementedBy(ComputeMetadataImpl.class)
public interface ComputeMetadata extends ResourceMetadata<ComputeType> {
/**
* Type of the resource, ex node, image, size
*
* @return Type of the resource, ex node, image, size
*/
@Override
public ComputeType getType();
/**
* id of the server within the naming scope it was created. potentially generated by the service.
*
* @return id of the server within the naming scope it was created. potentially generated by the
* service.
*/
@Override
public String getProviderId();
/**
* user defined name of the server.
*
* @return user defined name of the server.
*/
@Override
@Nullable
public String getName();
/**
@ -56,7 +59,12 @@ public interface ComputeMetadata extends ResourceMetadata<ComputeType> {
* a node or image is region based, the id will likely include both the region and the
* provider-supplied id encoded to avoid collisions.
*
* @return unique id within your account on the provider
*/
public String getId();
/**
* @return tags describing this resource, if supported
*/
public Set<String> getTags();
}

View File

@ -22,11 +22,14 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Map;
import java.util.Set;
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
import org.jclouds.domain.Location;
import org.jclouds.domain.ResourceMetadataBuilder;
import com.google.common.collect.ImmutableSet;
/**
*
* @author Adrian Cole
@ -34,9 +37,9 @@ import org.jclouds.domain.ResourceMetadataBuilder;
public class ComputeMetadataBuilder extends ResourceMetadataBuilder<ComputeType> {
protected String id;
protected ComputeType type;
protected Set<String> tags = ImmutableSet.<String>of();
public ComputeMetadataBuilder(ComputeType type) {
super();
this.type = checkNotNull(type, "type");
}
@ -45,6 +48,11 @@ public class ComputeMetadataBuilder extends ResourceMetadataBuilder<ComputeType>
return this;
}
public ComputeMetadataBuilder tags(Set<String> tags) {
this.tags = ImmutableSet.<String> copyOf(checkNotNull(tags, "tags"));
return this;
}
/**
* set id and providerId to the same value;
*/
@ -79,11 +87,11 @@ public class ComputeMetadataBuilder extends ResourceMetadataBuilder<ComputeType>
}
public ComputeMetadata build() {
return new ComputeMetadataImpl(type, providerId, name, id, location, uri, userMetadata);
return new ComputeMetadataImpl(type, providerId, name, id, location, uri, userMetadata, tags);
}
public static ComputeMetadataBuilder fromComputeMetadata(ComputeMetadata in) {
return new ComputeMetadataBuilder(in.getType()).id(in.getId()).location(in.getLocation()).name(in.getName())
.uri(in.getUri()).userMetadata(in.getUserMetadata());
.uri(in.getUri()).userMetadata(in.getUserMetadata()).tags(in.getTags());
}
}

View File

@ -25,6 +25,7 @@ import static org.jclouds.compute.predicates.ImagePredicates.any;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jclouds.compute.domain.internal.HardwareImpl;
import org.jclouds.compute.predicates.ImagePredicates;
@ -87,6 +88,11 @@ public class HardwareBuilder extends ComputeMetadataBuilder {
public HardwareBuilder id(String id) {
return HardwareBuilder.class.cast(super.id(id));
}
@Override
public HardwareBuilder tags(Set<String> tags) {
return HardwareBuilder.class.cast(super.tags(tags));
}
@Override
public HardwareBuilder ids(String id) {
@ -120,14 +126,14 @@ public class HardwareBuilder extends ComputeMetadataBuilder {
@Override
public Hardware build() {
return new HardwareImpl(providerId, name, id, location, uri, userMetadata, processors, ram, volumes,
return new HardwareImpl(providerId, name, id, location, uri, userMetadata, tags, processors, ram, volumes,
supportsImage);
}
@SuppressWarnings("unchecked")
public static HardwareBuilder fromHardware(Hardware in) {
return new HardwareBuilder().id(in.getId()).providerId(in.getProviderId()).location(in.getLocation()).name(
in.getName()).uri(in.getUri()).userMetadata(in.getUserMetadata()).processors(
in.getName()).uri(in.getUri()).userMetadata(in.getUserMetadata()).tags(in.getTags()).processors(
List.class.cast(in.getProcessors())).ram(in.getRam()).volumes(List.class.cast(in.getVolumes()))
.supportsImage(in.supportsImage());
}

View File

@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
@ -73,6 +74,10 @@ public class ImageBuilder extends ComputeMetadataBuilder {
public ImageBuilder id(String id) {
return ImageBuilder.class.cast(super.id(id));
}
public ImageBuilder tags(Set<String> tags) {
return ImageBuilder.class.cast(super.tags(tags));
}
@Override
public ImageBuilder ids(String id) {
@ -106,13 +111,13 @@ public class ImageBuilder extends ComputeMetadataBuilder {
@Override
public Image build() {
return new ImageImpl(providerId, name, id, location, uri, userMetadata, operatingSystem, description, version,
return new ImageImpl(providerId, name, id, location, uri, userMetadata, tags, operatingSystem, description, version,
adminPassword, defaultCredentials);
}
public static ImageBuilder fromImage(Image image) {
return new ImageBuilder().providerId(image.getProviderId()).name(image.getName()).id(image.getId()).location(
image.getLocation()).uri(image.getUri()).userMetadata(image.getUserMetadata()).version(
image.getLocation()).uri(image.getUri()).userMetadata(image.getUserMetadata()).tags(image.getTags()).version(
image.getVersion()).description(image.getDescription()).operatingSystem(image.getOperatingSystem())
.adminPassword(image.getAdminPassword()).defaultCredentials(image.getDefaultCredentials());
}

View File

@ -113,6 +113,11 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder {
return NodeMetadataBuilder.class.cast(super.id(id));
}
@Override
public NodeMetadataBuilder tags(Set<String> tags) {
return NodeMetadataBuilder.class.cast(super.tags(tags));
}
@Override
public NodeMetadataBuilder ids(String id) {
return NodeMetadataBuilder.class.cast(super.ids(id));
@ -145,17 +150,17 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder {
@Override
public NodeMetadata build() {
return new NodeMetadataImpl(providerId, name, id, location, uri, userMetadata, group, hardware, imageId, os, state,
loginPort, publicAddresses, privateAddresses, adminPassword, credentials);
return new NodeMetadataImpl(providerId, name, id, location, uri, userMetadata, tags, group, hardware, imageId,
os, state, loginPort, publicAddresses, privateAddresses, adminPassword, credentials);
}
public static NodeMetadataBuilder fromNodeMetadata(NodeMetadata node) {
return new NodeMetadataBuilder().providerId(node.getProviderId()).name(node.getName()).id(node.getId()).location(
node.getLocation()).uri(node.getUri()).userMetadata(node.getUserMetadata()).group(node.getGroup()).hardware(
node.getHardware()).imageId(node.getImageId()).operatingSystem(node.getOperatingSystem()).state(
node.getState()).loginPort(node.getLoginPort()).publicAddresses(node.getPublicAddresses())
.privateAddresses(node.getPrivateAddresses()).adminPassword(node.getAdminPassword()).credentials(
node.getCredentials());
node.getLocation()).uri(node.getUri()).userMetadata(node.getUserMetadata()).tags(node.getTags()).group(
node.getGroup()).hardware(node.getHardware()).imageId(node.getImageId()).operatingSystem(
node.getOperatingSystem()).state(node.getState()).loginPort(node.getLoginPort()).publicAddresses(
node.getPublicAddresses()).privateAddresses(node.getPrivateAddresses()).adminPassword(
node.getAdminPassword()).credentials(node.getCredentials());
}
}

View File

@ -22,12 +22,15 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Map;
import java.util.Set;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType;
import org.jclouds.domain.Location;
import org.jclouds.domain.internal.ResourceMetadataImpl;
import com.google.common.collect.ImmutableSet;
/**
* @author Adrian Cole
* @author Ivan Meredith
@ -37,12 +40,14 @@ public class ComputeMetadataImpl extends ResourceMetadataImpl<ComputeType> imple
private static final long serialVersionUID = 7374704415964898694L;
private final String id;
private final ComputeType type;
protected final Set<String> tags;
public ComputeMetadataImpl(ComputeType type, String providerId, String name, String id, Location location, URI uri,
Map<String, String> userMetadata) {
Map<String, String> userMetadata, Set<String> tags) {
super(providerId, name, location, uri, userMetadata);
this.id = checkNotNull(id, "id");
this.type = checkNotNull(type, "type");
this.tags = ImmutableSet.<String> copyOf(checkNotNull(tags, "tags"));
}
/**
@ -61,6 +66,14 @@ public class ComputeMetadataImpl extends ResourceMetadataImpl<ComputeType> imple
return id;
}
/**
* {@inheritDoc}
*/
@Override
public Set<String> getTags() {
return tags;
}
@Override
public int hashCode() {
final int prime = 31;

View File

@ -25,6 +25,7 @@ import static org.jclouds.compute.util.ComputeServiceUtils.getSpace;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
@ -53,9 +54,9 @@ public class HardwareImpl extends ComputeMetadataImpl implements Hardware {
private final Predicate<Image> supportsImage;
public HardwareImpl(String providerId, String name, String id, @Nullable Location location, URI uri,
Map<String, String> userMetadata, Iterable<? extends Processor> processors, int ram,
Map<String, String> userMetadata, Set<String> tags, Iterable<? extends Processor> processors, int ram,
Iterable<? extends Volume> volumes, Predicate<Image> supportsImage) {
super(ComputeType.HARDWARE, providerId, name, id, location, uri, userMetadata);
super(ComputeType.HARDWARE, providerId, name, id, location, uri, userMetadata, tags);
this.processors = ImmutableList.copyOf(checkNotNull(processors, "processors"));
this.ram = ram;
this.volumes = ImmutableList.copyOf(checkNotNull(volumes, "volumes"));
@ -106,7 +107,7 @@ public class HardwareImpl extends ComputeMetadataImpl implements Hardware {
@Override
public String toString() {
return "[id=" + getId() + ", providerId=" + getProviderId() + ", name=" + getName() + ", processors="
+ processors + ", ram=" + ram + ", volumes=" + volumes + ", supportsImage=" + supportsImage + "]";
+ processors + ", ram=" + ram + ", volumes=" + volumes + ", supportsImage=" + supportsImage + ", tags=" + tags + "]";
}
/**

View File

@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
@ -47,9 +48,9 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
private final Credentials defaultCredentials;
public ImageImpl(String providerId, String name, String id, Location location, URI uri,
Map<String, String> userMetadata, OperatingSystem operatingSystem, String description,
Map<String, String> userMetadata, Set<String> tags, OperatingSystem operatingSystem, String description,
@Nullable String version, @Nullable String adminPassword, @Nullable Credentials defaultCredentials) {
super(ComputeType.IMAGE, providerId, name, id, location, uri, userMetadata);
super(ComputeType.IMAGE, providerId, name, id, location, uri, userMetadata, tags);
this.operatingSystem = checkNotNull(operatingSystem, "operatingSystem");
this.version = version;
this.description = checkNotNull(description, "description");
@ -102,7 +103,7 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
return "[id=" + getId() + ", name=" + getName() + ", operatingSystem=" + operatingSystem + ", description="
+ description + ", version=" + version + ", location=" + getLocation() + ", loginUser="
+ ((defaultCredentials != null) ? defaultCredentials.identity : null) + ", userMetadata="
+ getUserMetadata() + "]";
+ getUserMetadata() + ", tags=" + tags + "]";
}
@Override

View File

@ -63,11 +63,11 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
private final OperatingSystem os;
public NodeMetadataImpl(String providerId, String name, String id, Location location, URI uri,
Map<String, String> userMetadata, @Nullable String group, @Nullable Hardware hardware,
Map<String, String> userMetadata, Set<String> tags, @Nullable String group, @Nullable Hardware hardware,
@Nullable String imageId, @Nullable OperatingSystem os, NodeState state, int loginPort,
Iterable<String> publicAddresses, Iterable<String> privateAddresses, @Nullable String adminPassword,
@Nullable Credentials credentials) {
super(ComputeType.NODE, providerId, name, id, location, uri, userMetadata);
super(ComputeType.NODE, providerId, name, id, location, uri, userMetadata, tags);
this.group = group;
this.hardware = hardware;
this.imageId = imageId;
@ -175,7 +175,7 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
+ getOperatingSystem() + ", state=" + getState() + ", loginPort=" + getLoginPort()
+ ", privateAddresses=" + privateAddresses + ", publicAddresses=" + publicAddresses + ", hardware="
+ getHardware() + ", loginUser=" + ((credentials != null) ? credentials.identity : null)
+ ", userMetadata=" + getUserMetadata() + "]";
+ ", userMetadata=" + getUserMetadata() + ", tags=" + tags + "]";
}
@Override

View File

@ -23,6 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.io.IOException;
import java.util.Arrays;
import java.util.Set;
import org.jclouds.domain.Credentials;
import org.jclouds.io.Payload;
@ -31,6 +32,7 @@ import org.jclouds.scriptbuilder.domain.Statements;
import org.jclouds.util.Strings2;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableSet;
/**
* Contains options supported in the {@code ComputeService#runNodesWithTag} operation. <h2>
@ -70,6 +72,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
to.blockOnPort(this.getPort(), this.getSeconds());
if (this.isIncludeMetadata())
to.withMetadata();
if (this.getTags().size() > 0)
to.tags(getTags());
if (!this.shouldBlockUntilRunning())
to.blockUntilRunning(false);
if (!this.shouldBlockOnComplete())
@ -276,6 +280,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
protected Statement script;
protected Set<String> tags = ImmutableSet.of();
protected String privateKey;
protected String publicKey;
@ -292,6 +298,10 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
return script;
}
public Set<String> getTags() {
return tags;
}
public String getPrivateKey() {
return privateKey;
}
@ -350,7 +360,7 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
*/
public TemplateOptions installPrivateKey(String privateKey) {
checkArgument(checkNotNull(privateKey, "privateKey").startsWith("-----BEGIN RSA PRIVATE KEY-----"),
"key should start with -----BEGIN RSA PRIVATE KEY-----");
"key should start with -----BEGIN RSA PRIVATE KEY-----");
this.privateKey = privateKey;
return this;
}
@ -403,6 +413,14 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
}
}
/**
* assigns tags to the created nodes
*/
public TemplateOptions tags(Iterable<String> tags) {
this.tags = ImmutableSet.copyOf(checkNotNull(tags, "tags"));
return this;
}
/**
* Opens the set of ports to public access.
*/
@ -461,6 +479,14 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
return options.inboundPorts(ports);
}
/**
* @see TemplateOptions#tags
*/
public static TemplateOptions tags(Iterable<String> tags) {
TemplateOptions options = new TemplateOptions();
return options.tags(tags);
}
/**
* @see TemplateOptions#blockUntilRunning
*/
@ -556,9 +582,9 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
@Override
public String toString() {
return "[inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey=" + (privateKey != null) + ", publicKey="
+ (publicKey != null) + ", runScript=" + (script != null) + ", blockUntilRunning=" + blockUntilRunning
+ ", blockOnComplete=" + blockOnComplete + ", port:seconds=" + port + ":" + seconds
+ ", metadata/details: " + includeMetadata + "]";
+ (publicKey != null) + ", runScript=" + (script != null) + ", blockUntilRunning=" + blockUntilRunning
+ ", blockOnComplete=" + blockOnComplete + ", port:seconds=" + port + ":" + seconds
+ ", metadata/details: " + includeMetadata + "]";
}
public TemplateOptions blockUntilRunning(boolean blockUntilRunning) {

View File

@ -45,8 +45,9 @@ import org.jclouds.rest.ResourceNotFoundException;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.collect.ImmutableList.Builder;
/**
*
@ -85,6 +86,7 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
String id = idProvider.get() + "";
builder.ids(id);
builder.name(name);
builder.tags(template.getOptions().getTags());
builder.group(group);
builder.location(location.get());
builder.imageId(template.getImage().getId());
@ -110,18 +112,19 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
@Override
public Iterable<Image> listImages() {
Credentials defaultCredentials = new Credentials("root", null);
Set<Image> images = Sets.newLinkedHashSet();
// initializing as a List, as ImmutableSet does not allow you to put duplicates
Builder<Image> images = ImmutableList.<Image>builder();
int id = 1;
for (boolean is64Bit : new boolean[] { true, false })
for (Entry<OsFamily, Map<String, String>> osVersions : this.osToVersionMap.entrySet()) {
for (String version : Sets.newLinkedHashSet(osVersions.getValue().values())) {
for (String version : ImmutableSet.copyOf(osVersions.getValue().values())) {
String desc = String.format("stub %s %s", osVersions.getKey(), is64Bit);
images.add(new ImageBuilder().ids(id++ + "").name(osVersions.getKey().name()).location(location.get())
.operatingSystem(new OperatingSystem(osVersions.getKey(), desc, version, null, desc, is64Bit))
.description(desc).defaultCredentials(defaultCredentials).build());
}
}
return images;
return images.build();
}
@Override

View File

@ -0,0 +1,47 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.io;
import java.io.InputStream;
import java.util.Map;
import javax.inject.Inject;
import org.jclouds.collect.InputSupplierMap;
import com.google.common.annotations.Beta;
import com.google.common.io.InputSupplier;
/**
*
* @author Adrian Cole
*/
@Beta
public class CopyInputStreamInputSupplierMap extends InputSupplierMap<String, InputStream> {
@Inject
public CopyInputStreamInputSupplierMap(Map<String, InputSupplier<InputStream>> toMap,
CopyInputStreamIntoSupplier putFunction) {
super(toMap, putFunction);
}
public CopyInputStreamInputSupplierMap(Map<String, InputSupplier<InputStream>> toMap) {
super(toMap, new CopyInputStreamIntoSupplier());
}
}

View File

@ -0,0 +1,64 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.io;
import java.io.IOException;
import java.io.InputStream;
import javax.annotation.Resource;
import org.jclouds.logging.Logger;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closeables;
import com.google.common.io.InputSupplier;
/**
*
* @author Adrian Cole
*/
@Beta
public class CopyInputStreamIntoSupplier implements Function<InputStream, InputSupplier<InputStream>> {
@Resource
protected Logger logger = Logger.NULL;
@SuppressWarnings("unchecked")
@Override
public InputSupplier<InputStream> apply(InputStream from) {
if (from == null)
return new InputSupplier<InputStream>() {
@Override
public InputStream getInput() throws IOException {
return null;
}
};
try {
return InputSupplier.class.cast(ByteStreams.newInputStreamSupplier(ByteStreams.toByteArray(from)));
} catch (Exception e) {
logger.warn(e, "ignoring problem retrieving credentials");
return null;
} finally {
Closeables.closeQuietly(from);
}
}
}

View File

@ -20,7 +20,6 @@ package org.jclouds.rest.config;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -29,9 +28,9 @@ import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.collect.InputSupplierMap;
import org.jclouds.collect.TransformingMap;
import org.jclouds.domain.Credentials;
import org.jclouds.io.CopyInputStreamInputSupplierMap;
import org.jclouds.json.Json;
import org.jclouds.logging.Logger;
import org.jclouds.rest.ConfiguresCredentialStore;
@ -39,8 +38,6 @@ import org.jclouds.util.Strings2;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closeables;
import com.google.common.io.InputSupplier;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@ -97,48 +94,6 @@ public class CredentialStoreModule extends AbstractModule {
}
}
@Singleton
public static class CopyInputStreamInputSupplierMap extends InputSupplierMap<String, InputStream> {
@Singleton
public static class CopyInputStreamIntoSupplier implements Function<InputStream, InputSupplier<InputStream>> {
@Resource
protected Logger logger = Logger.NULL;
@SuppressWarnings("unchecked")
@Override
public InputSupplier<InputStream> apply(InputStream from) {
if (from == null)
return new InputSupplier<InputStream>() {
@Override
public InputStream getInput() throws IOException {
return null;
}
};
try {
return InputSupplier.class.cast(ByteStreams.newInputStreamSupplier(ByteStreams.toByteArray(from)));
} catch (Exception e) {
logger.warn(e, "ignoring problem retrieving credentials");
return null;
} finally {
Closeables.closeQuietly(from);
}
}
}
@Inject
public CopyInputStreamInputSupplierMap(Map<String, InputSupplier<InputStream>> toMap,
CopyInputStreamIntoSupplier putFunction) {
super(toMap, putFunction);
}
public CopyInputStreamInputSupplierMap(Map<String, InputSupplier<InputStream>> toMap) {
super(toMap, new CopyInputStreamIntoSupplier());
}
}
@Singleton
public static class CredentialsFromJsonInputStream implements Function<InputStream, Credentials> {
@Resource

View File

@ -28,10 +28,10 @@ import java.util.concurrent.ConcurrentHashMap;
import org.jclouds.crypto.PemsTest;
import org.jclouds.domain.Credentials;
import org.jclouds.io.CopyInputStreamInputSupplierMap;
import org.jclouds.json.Json;
import org.jclouds.json.config.GsonModule;
import org.jclouds.rest.config.CredentialStoreModule;
import org.jclouds.rest.config.CredentialStoreModule.CopyInputStreamInputSupplierMap;
import org.jclouds.util.Strings2;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@ -46,7 +46,7 @@ import com.google.inject.TypeLiteral;
*
* @author Adrian Cole
*/
@Test(groups = "unit", sequential = true)
@Test(groups = "unit", singleThreaded = true)
public class CredentialStoreModuleTest {
Json json = createInjector().getInstance(Json.class);

View File

@ -125,11 +125,11 @@ public class AWSEC2ImageParserTest {
assertEquals(
new Gson().toJson(Iterables.get(result, 1)),
"{\"operatingSystem\":{\"family\":\"UBUNTU\",\"arch\":\"paravirtual\",\"version\":\"9.10\",\"description\":\"411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"is64Bit\":true},\"version\":\"4.5.3_EBS_Alpha\",\"description\":\"RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"defaultCredentials\":{\"identity\":\"root\"},\"id\":\"us-east-1/ami-c19db6b5\",\"type\":\"IMAGE\",\"providerId\":\"ami-c19db6b5\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}");
"{\"operatingSystem\":{\"family\":\"UBUNTU\",\"arch\":\"paravirtual\",\"version\":\"9.10\",\"description\":\"411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"is64Bit\":true},\"version\":\"4.5.3_EBS_Alpha\",\"description\":\"RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"defaultCredentials\":{\"identity\":\"root\"},\"id\":\"us-east-1/ami-c19db6b5\",\"type\":\"IMAGE\",\"tags\":[],\"providerId\":\"ami-c19db6b5\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}");
assertEquals(
new Gson().toJson(Iterables.get(result, 2)),
"{\"operatingSystem\":{\"family\":\"WINDOWS\",\"arch\":\"hvm\",\"version\":\"2003\",\"description\":\"411009282317/RightImage Windows_2003_i386_v5.4.3\",\"is64Bit\":false},\"version\":\"5.4.3\",\"description\":\"Built by RightScale\",\"defaultCredentials\":{\"identity\":\"root\"},\"id\":\"us-east-1/ami-710c2605\",\"type\":\"IMAGE\",\"providerId\":\"ami-710c2605\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}");
"{\"operatingSystem\":{\"family\":\"WINDOWS\",\"arch\":\"hvm\",\"version\":\"2003\",\"description\":\"411009282317/RightImage Windows_2003_i386_v5.4.3\",\"is64Bit\":false},\"version\":\"5.4.3\",\"description\":\"Built by RightScale\",\"defaultCredentials\":{\"identity\":\"root\"},\"id\":\"us-east-1/ami-710c2605\",\"type\":\"IMAGE\",\"tags\":[],\"providerId\":\"ami-710c2605\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}");
}
public void testParseAmznImage() {