mirror of https://github.com/apache/jclouds.git
fixed merge issues after pull from jclouds/master
This commit is contained in:
commit
4445c16112
|
@ -2,7 +2,7 @@
|
|||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -28,9 +28,12 @@
|
|||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../../project/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>org.jclouds.api</groupId>
|
||||
<artifactId>atmos</artifactId>
|
||||
<name>jclouds atmos components</name>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<properties>
|
||||
<test.initializer>org.jclouds.atmos.blobstore.integration.AtmosStorageTestInitializer</test.initializer>
|
||||
<test.atmos.endpoint>https://accesspoint.atmos.com</test.atmos.endpoint>
|
||||
|
@ -38,6 +41,7 @@
|
|||
<test.atmos.identity>FIXME</test.atmos.identity>
|
||||
<test.atmos.credential>FIXME</test.atmos.credential>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
@ -125,5 +129,21 @@
|
|||
</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.atmos.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -65,6 +65,8 @@ Here are the properties:
|
|||
* description - optional; long description of this node
|
||||
* note this is not yet in jclouds NodeMetadata
|
||||
* hostname - name or ip address to contact the node on
|
||||
* location_id - optional; correlates to a ZONE-scoped Location
|
||||
* note that if present for one node, must be present for all
|
||||
* os_arch - ex. x86
|
||||
* os_family - must conform to org.jclouds.compute.domain.OsFamily in lower-hyphen format
|
||||
ex. rhel, ubuntu, centos, debian, amzn-linux
|
||||
|
@ -96,6 +98,7 @@ nodes:
|
|||
name: cluster-1
|
||||
description: accounting analytics cluster
|
||||
hostname: cluster-1.mydomain.com
|
||||
location_id: virginia
|
||||
os_arch: x86
|
||||
os_family: rhel
|
||||
os_description: redhat with CDH
|
||||
|
|
|
@ -28,9 +28,12 @@
|
|||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../../project/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>org.jclouds.api</groupId>
|
||||
<artifactId>byon</artifactId>
|
||||
<name>jclouds bring your own node provider</name>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<properties>
|
||||
<test.byon.endpoint>file://c:/test.txt</test.byon.endpoint>
|
||||
<test.byon.sudo-password> </test.byon.sudo-password>
|
||||
|
@ -81,7 +84,7 @@
|
|||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.6</version>
|
||||
<version>1.8</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -120,4 +123,20 @@
|
|||
</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.byon.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -20,60 +20,170 @@ package org.jclouds.byon;
|
|||
|
||||
import java.net.URI;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class Node {
|
||||
// public due to snakeyaml
|
||||
public Node() {
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Node(String id, String name, String description, String hostname, String osArch, String osFamily,
|
||||
String osDescription, String osVersion, String group, List<String> tags, String username,
|
||||
String credential, URI credentialUrl, String sudo_password) {
|
||||
public static class Builder {
|
||||
private String id;
|
||||
private String name;
|
||||
private String description;
|
||||
private String hostname;
|
||||
private String locationId;
|
||||
private String osArch;
|
||||
private String osFamily;
|
||||
private String osDescription;
|
||||
private String osVersion;
|
||||
private boolean os64Bit;
|
||||
private String group;
|
||||
private Set<String> tags = ImmutableSet.of();
|
||||
private String username;
|
||||
private String credential;
|
||||
private URI credentialUrl;
|
||||
private String sudoPassword;
|
||||
|
||||
public Builder id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder description(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder hostname(String hostname) {
|
||||
this.hostname = hostname;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder locationId(String locationId) {
|
||||
this.locationId = locationId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder osArch(String osArch) {
|
||||
this.osArch = osArch;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder osFamily(String osFamily) {
|
||||
this.osFamily = osFamily;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder osDescription(String osDescription) {
|
||||
this.osDescription = osDescription;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder osVersion(String osVersion) {
|
||||
this.osVersion = osVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder os64Bit(boolean os64Bit) {
|
||||
this.os64Bit = os64Bit;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder group(String group) {
|
||||
this.group = group;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder tags(Iterable<String> tags) {
|
||||
this.tags = ImmutableSet.copyOf(tags);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder username(String username) {
|
||||
this.username = username;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder credential(String credential) {
|
||||
this.credential = credential;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder credentialUrl(URI credentialUrl) {
|
||||
this.credentialUrl = credentialUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder sudoPassword(String sudoPassword) {
|
||||
this.sudoPassword = sudoPassword;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Node build() {
|
||||
return new Node(id, name, description, hostname, locationId, osArch, osFamily, osDescription, osVersion,
|
||||
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, boolean os64Bit, String group,
|
||||
Iterable<String> tags, String username, String credential, URI credentialUrl, String sudoPassword) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.hostname = hostname;
|
||||
this.os_arch = osArch;
|
||||
this.os_family = osFamily;
|
||||
this.os_description = osDescription;
|
||||
this.os_version = osVersion;
|
||||
this.locationId = locationId;
|
||||
this.osArch = osArch;
|
||||
this.osFamily = osFamily;
|
||||
this.osDescription = osDescription;
|
||||
this.osVersion = osVersion;
|
||||
this.os64Bit = os64Bit;
|
||||
this.group = group;
|
||||
this.tags = ImmutableList.copyOf(tags);
|
||||
this.tags = ImmutableSet.copyOf(tags);
|
||||
this.username = username;
|
||||
this.credential = credential;
|
||||
this.credential_url = credentialUrl != null ? credentialUrl.toASCIIString() : null;
|
||||
this.sudo_password = sudo_password;
|
||||
this.credentialUrl = credentialUrl;
|
||||
this.sudoPassword = sudoPassword;
|
||||
}
|
||||
|
||||
// public due to snakeyaml
|
||||
public String id;
|
||||
public String name;
|
||||
public String description;
|
||||
public String hostname;
|
||||
public String os_arch;
|
||||
public String os_family;
|
||||
public String os_description;
|
||||
public String os_version;
|
||||
public String group;
|
||||
public List<String> tags;
|
||||
public String username;
|
||||
public String credential;
|
||||
public String credential_url;
|
||||
public String sudo_password;
|
||||
private final String id;
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final String hostname;
|
||||
private final String locationId;
|
||||
private final String osArch;
|
||||
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;
|
||||
private final String credential;
|
||||
private final URI credentialUrl;
|
||||
private final String sudoPassword;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getLocationId() {
|
||||
return locationId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
@ -91,19 +201,23 @@ public class Node {
|
|||
}
|
||||
|
||||
public String getOsArch() {
|
||||
return os_arch;
|
||||
return osArch;
|
||||
}
|
||||
|
||||
public String getOsFamily() {
|
||||
return os_family;
|
||||
return osFamily;
|
||||
}
|
||||
|
||||
public String getOsDescription() {
|
||||
return os_description;
|
||||
return osDescription;
|
||||
}
|
||||
|
||||
public String getOsVersion() {
|
||||
return os_version;
|
||||
return osVersion;
|
||||
}
|
||||
|
||||
public boolean isOs64Bit() {
|
||||
return os64Bit;
|
||||
}
|
||||
|
||||
public Set<String> getTags() {
|
||||
|
@ -122,7 +236,11 @@ public class Node {
|
|||
}
|
||||
|
||||
public URI getCredentialUrl() {
|
||||
return credential_url != null ? URI.create(credential_url) : null;
|
||||
return credentialUrl;
|
||||
}
|
||||
|
||||
public String getSudoPassword() {
|
||||
return sudoPassword;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -130,10 +248,6 @@ public class Node {
|
|||
return Objects.hashCode(id);
|
||||
}
|
||||
|
||||
public String getSudoPassword() {
|
||||
return sudo_password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (that == null)
|
||||
|
@ -144,10 +258,11 @@ public class Node {
|
|||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper(this).add("id", id).add("name", name).add("description", description).add(
|
||||
"hostname", hostname).add("osArch", os_arch).add("osFamily", os_family).add("osDescription",
|
||||
os_description).add("osVersion", os_version).add("group", group).add("tags", tags).add("username",
|
||||
username).add("hasCredential", credential != null || credential_url != null).add("hasSudoPassword",
|
||||
sudo_password != null).toString();
|
||||
"locationId", locationId).add("hostname", hostname).add("osArch", osArch).add("osFamily", osFamily).add(
|
||||
"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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -44,7 +44,7 @@ import com.google.inject.TypeLiteral;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@SuppressWarnings( { "rawtypes", "unchecked" })
|
||||
@SuppressWarnings("unchecked")
|
||||
@SingleThreaded
|
||||
public class BYONComputeServiceContextModule extends
|
||||
JCloudsNativeComputeServiceAdapterContextModule<Supplier, Supplier> {
|
||||
|
@ -53,7 +53,6 @@ public class BYONComputeServiceContextModule extends
|
|||
super(Supplier.class, Supplier.class, BYONComputeServiceAdapter.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Provides
|
||||
@Singleton
|
||||
Supplier provideApi(Supplier<Map<String, Node>> in) {
|
||||
|
@ -73,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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,13 +16,25 @@
|
|||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.cloudstack.parse;
|
||||
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
|
||||
*
|
||||
*/
|
||||
public abstract class BaseItemParserTest<T> extends BaseParserTest<T, T> {
|
||||
@Beta
|
||||
@Retention(RUNTIME)
|
||||
@Target(TYPE)
|
||||
public @interface ConfiguresNodeStore {
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -24,25 +24,32 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.byon.Node;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.compute.domain.OperatingSystemBuilder;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.util.Strings2;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -50,16 +57,19 @@ import com.google.common.collect.ImmutableSet;
|
|||
@Singleton
|
||||
public class NodeToNodeMetadata implements Function<Node, NodeMetadata> {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final Supplier<Location> location;
|
||||
private final Supplier<Set<? extends Location>> locations;
|
||||
private final Map<String, Credentials> credentialStore;
|
||||
private final Function<URI, InputStream> slurp;
|
||||
|
||||
@Inject
|
||||
NodeToNodeMetadata(Supplier<Location> location, Function<URI, InputStream> slurp,
|
||||
Map<String, Credentials> credentialStore) {
|
||||
NodeToNodeMetadata(Supplier<Location> location, @Memoized Supplier<Set<? extends Location>> locations,
|
||||
Function<URI, InputStream> slurp, Map<String, Credentials> credentialStore) {
|
||||
this.location = checkNotNull(location, "location");
|
||||
this.locations = checkNotNull(locations, "locations");
|
||||
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
||||
this.slurp = checkNotNull(slurp, "slurp");
|
||||
}
|
||||
|
@ -69,10 +79,10 @@ public class NodeToNodeMetadata implements Function<Node, NodeMetadata> {
|
|||
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
||||
builder.ids(from.getId());
|
||||
builder.name(from.getName());
|
||||
builder.location(location.get());
|
||||
builder.location(findLocationWithId(from.getLocationId()));
|
||||
builder.group(from.getGroup());
|
||||
// TODO add tags!
|
||||
builder.operatingSystem(new OperatingSystemBuilder().arch(from.getOsArch()).family(
|
||||
builder.tags(from.getTags());
|
||||
builder.operatingSystem(OperatingSystem.builder().arch(from.getOsArch()).family(
|
||||
OsFamily.fromValue(from.getOsFamily())).description(from.getOsDescription())
|
||||
.version(from.getOsVersion()).build());
|
||||
builder.state(NodeState.RUNNING);
|
||||
|
@ -99,4 +109,24 @@ public class NodeToNodeMetadata implements Function<Node, NodeMetadata> {
|
|||
builder.adminPassword(from.getSudoPassword());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private Location findLocationWithId(final String locationId) {
|
||||
if (locationId == null)
|
||||
return location.get();
|
||||
try {
|
||||
Location location = Iterables.find(locations.get(), new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(locationId);
|
||||
}
|
||||
|
||||
});
|
||||
return location;
|
||||
|
||||
} catch (NoSuchElementException e) {
|
||||
logger.debug("couldn't match instance location %s in: %s", locationId, locations.get());
|
||||
return location.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,12 +27,14 @@ 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;
|
||||
import org.yaml.snakeyaml.constructor.Constructor;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
|
@ -44,6 +46,7 @@ import com.google.common.collect.Maps;
|
|||
* name: cluster-1
|
||||
* description: xyz
|
||||
* hostname: cluster-1.mydomain.com
|
||||
* location_id: virginia
|
||||
* os_arch: x86
|
||||
* os_family: linux
|
||||
* os_description: redhat
|
||||
|
@ -59,36 +62,39 @@ import com.google.common.collect.Maps;
|
|||
* </pre>
|
||||
*
|
||||
* @author Kelvin Kakugawa
|
||||
* @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<Node> nodes;
|
||||
public List<YamlNode> nodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Node> apply(InputStream source) {
|
||||
|
||||
Constructor constructor = new Constructor(Config.class);
|
||||
|
||||
TypeDescription nodeDesc = new TypeDescription(Node.class);
|
||||
TypeDescription nodeDesc = new TypeDescription(YamlNode.class);
|
||||
nodeDesc.putListPropertyType("tags", String.class);
|
||||
constructor.addTypeDescription(nodeDesc);
|
||||
|
||||
TypeDescription configDesc = new TypeDescription(Config.class);
|
||||
configDesc.putListPropertyType("nodes", Node.class);
|
||||
configDesc.putListPropertyType("nodes", YamlNode.class);
|
||||
constructor.addTypeDescription(configDesc);
|
||||
|
||||
// note that snakeyaml also throws nosuchmethod error when you use the non-deprecated
|
||||
// constructor
|
||||
Yaml yaml = new Yaml(new Loader(constructor));
|
||||
Config config = (Config) yaml.load(source);
|
||||
checkState(config != null, "missing config: class");
|
||||
checkState(config.nodes != null, "missing nodes: collection");
|
||||
|
||||
return Maps.uniqueIndex(config.nodes, 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();
|
||||
}
|
|
@ -21,6 +21,7 @@ package org.jclouds.byon.internal;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
@ -34,11 +35,16 @@ import org.jclouds.compute.domain.NodeMetadata;
|
|||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.location.suppliers.JustProvider;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.ImmutableSet.Builder;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -59,8 +65,8 @@ public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
|||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template,
|
||||
Map<String, Credentials> credentialStore) {
|
||||
public NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name,
|
||||
Template template, Map<String, Credentials> credentialStore) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
@ -79,10 +85,26 @@ public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
|||
return Iterables.transform(nodes.get().values(), converter);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Iterable<Location> listLocations() {
|
||||
return (Iterable<Location>) locationSupplier.get();
|
||||
Builder<Location> locations = ImmutableSet.builder();
|
||||
Location provider = Iterables.getOnlyElement(locationSupplier.get());
|
||||
Set<String> zones = ImmutableSet.copyOf(Iterables.filter(Iterables.transform(nodes.get().values(),
|
||||
new Function<Node, String>() {
|
||||
|
||||
@Override
|
||||
public String apply(Node arg0) {
|
||||
return arg0.getLocationId();
|
||||
}
|
||||
}), Predicates.notNull()));
|
||||
if (zones.size() == 0)
|
||||
return locations.add(provider).build();
|
||||
else
|
||||
for (String zone : zones) {
|
||||
locations.add(new LocationBuilder().scope(LocationScope.ZONE).id(zone).description(zone).parent(provider)
|
||||
.build());
|
||||
}
|
||||
return locations.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -18,16 +18,19 @@
|
|||
*/
|
||||
package org.jclouds.byon;
|
||||
|
||||
import static org.jclouds.byon.functions.NodeToNodeMetadataTest.expectedNodeMetadataFromResource;
|
||||
import static org.jclouds.byon.functions.NodeToNodeMetadataTest.expectedProviderLocationFromResource;
|
||||
import static org.jclouds.byon.functions.NodeToNodeMetadataTest.zoneCalled;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.byon.functions.NodeToNodeMetadataTest;
|
||||
import org.jclouds.byon.functions.NodesFromYamlTest;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -56,6 +59,7 @@ public class BYONComputeServiceTest {
|
|||
private void assertNodesParse(String endpoint) {
|
||||
ComputeServiceContext context = null;
|
||||
try {
|
||||
Location providerLocation = expectedProviderLocationFromResource(endpoint);
|
||||
|
||||
Properties props = new Properties();
|
||||
props.setProperty("byon.endpoint", endpoint);
|
||||
|
@ -69,12 +73,45 @@ public class BYONComputeServiceTest {
|
|||
.getApi();
|
||||
|
||||
assertEquals(supplier.get().size(), context.getComputeService().listNodes().size());
|
||||
assertEquals(supplier.get(), ImmutableMap.<String, Node> of(NodesFromYamlTest.TEST1.id,
|
||||
assertEquals(supplier.get(), ImmutableMap.<String, Node> of(NodesFromYamlTest.TEST1.getId(),
|
||||
NodesFromYamlTest.TEST1));
|
||||
|
||||
assertEquals(context.getComputeService().listNodes(), ImmutableSet.of(NodeToNodeMetadataTest
|
||||
.expectedNodeMetadataFromResource(endpoint)));
|
||||
assertEquals(context.getComputeService().listNodes(), ImmutableSet
|
||||
.of(expectedNodeMetadataFromResource(endpoint)));
|
||||
assertEquals(context.getComputeService().listAssignableLocations(), ImmutableSet.of(providerLocation));
|
||||
} finally {
|
||||
if (context != null)
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void testNodesWithLocations() {
|
||||
ComputeServiceContext context = null;
|
||||
try {
|
||||
String endpoint = "file://" + getClass().getResource("/test_location.yaml").getPath();
|
||||
Properties props = new Properties();
|
||||
props.setProperty("byon.endpoint", endpoint);
|
||||
context = new ComputeServiceContextFactory().createContext("byon", "foo", "bar", ImmutableSet
|
||||
.<Module> of(new JschSshClientModule()), props);
|
||||
|
||||
assertEquals(context.getProviderSpecificContext().getEndpoint(), URI.create(endpoint));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Supplier<Map<String, Node>> supplier = (Supplier<Map<String, Node>>) context.getProviderSpecificContext()
|
||||
.getApi();
|
||||
|
||||
assertEquals(supplier.get().size(), context.getComputeService().listNodes().size());
|
||||
assertEquals(supplier.get(), ImmutableMap.<String, Node> of(NodesFromYamlTest.TEST2.getId(),
|
||||
NodesFromYamlTest.TEST2, NodesFromYamlTest.TEST3.getId(), NodesFromYamlTest.TEST3));
|
||||
Location providerLocation = expectedProviderLocationFromResource(endpoint);
|
||||
|
||||
Location virginia = zoneCalled("virginia", providerLocation);
|
||||
Location maryland = zoneCalled("maryland", providerLocation);
|
||||
|
||||
assertEquals(context.getComputeService().listNodes(), ImmutableSet.of(expectedNodeMetadataFromResource(1,
|
||||
endpoint, virginia), expectedNodeMetadataFromResource(2, endpoint, maryland)));
|
||||
|
||||
assertEquals(context.getComputeService().listAssignableLocations(), ImmutableSet.of(virginia, maryland));
|
||||
} finally {
|
||||
if (context != null)
|
||||
context.close();
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -22,12 +22,13 @@ import static org.testng.Assert.assertEquals;
|
|||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.compute.domain.OperatingSystemBuilder;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
|
@ -45,31 +46,51 @@ import com.google.common.collect.Maps;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class NodeToNodeMetadataTest {
|
||||
public static Location expectedLocationFromResource(String resource) {
|
||||
public static Location expectedProviderLocationFromResource(String resource) {
|
||||
return new LocationBuilder().scope(LocationScope.PROVIDER).id("byon").description(resource).build();
|
||||
}
|
||||
|
||||
public static NodeMetadata expectedNodeMetadataFromResource(String resource) {
|
||||
Location location = expectedLocationFromResource(resource);
|
||||
public static Location zoneCalled(String zone, Location parent) {
|
||||
return new LocationBuilder().scope(LocationScope.ZONE).id(zone).description(zone).parent(parent).build();
|
||||
}
|
||||
|
||||
return new NodeMetadataBuilder().ids("cluster-1").group("hadoop").name("cluster-1").location(location).state(
|
||||
NodeState.RUNNING).operatingSystem(
|
||||
new OperatingSystemBuilder().description("redhat").family(OsFamily.RHEL).arch("x86").version("5.3")
|
||||
.build()).publicAddresses(ImmutableSet.of("cluster-1.mydomain.com")).credentials(
|
||||
new Credentials("myUser", NodesFromYamlTest.key)).adminPassword("happy bear").build();
|
||||
String resource = "location";
|
||||
|
||||
Location provider = expectedProviderLocationFromResource(resource);
|
||||
|
||||
Map<String, Credentials> credentialStore = Maps.newLinkedHashMap();
|
||||
|
||||
NodeToNodeMetadata parser = new NodeToNodeMetadata(Suppliers.ofInstance(provider), Suppliers
|
||||
.<Set<? extends Location>> ofInstance(ImmutableSet.of(provider, zoneCalled("virginia", provider))),
|
||||
new SupplyFromProviderURIOrNodesProperty(URI.create("test")), credentialStore);
|
||||
|
||||
public static NodeMetadata expectedNodeMetadataFromResource(String resource) {
|
||||
return expectedNodeMetadataFromResource(resource, expectedProviderLocationFromResource(resource));
|
||||
}
|
||||
|
||||
public static NodeMetadata expectedNodeMetadataFromResource(String resource, Location location) {
|
||||
return expectedNodeMetadataFromResource(1, resource, location);
|
||||
}
|
||||
|
||||
public static NodeMetadata expectedNodeMetadataFromResource(int id, String resource, Location location) {
|
||||
return new NodeMetadataBuilder().ids("cluster-" + id).group("hadoop").name("cluster-" + id).location(location)
|
||||
.state(NodeState.RUNNING).operatingSystem(
|
||||
OperatingSystem.builder().description("redhat").family(OsFamily.RHEL).arch("x86")
|
||||
.version("5.3").build()).publicAddresses(
|
||||
ImmutableSet.of("cluster-" + id + ".mydomain.com")).credentials(
|
||||
new Credentials("myUser", NodesFromYamlTest.key)).adminPassword("happy bear").build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesParse() throws Exception {
|
||||
|
||||
Map<String, Credentials> credentialStore = Maps.newLinkedHashMap();
|
||||
|
||||
NodeToNodeMetadata parser = new NodeToNodeMetadata(
|
||||
Suppliers.ofInstance(expectedLocationFromResource("location")),
|
||||
new SupplyFromProviderURIOrNodesProperty(URI.create("test")), credentialStore);
|
||||
|
||||
assertEquals(parser.apply(NodesFromYamlTest.TEST1), expectedNodeMetadataFromResource("location"));
|
||||
assertEquals(parser.apply(NodesFromYamlTest.TEST1), expectedNodeMetadataFromResource(resource, provider));
|
||||
assertEquals(credentialStore, ImmutableMap.of("node#cluster-1", new Credentials("myUser", NodesFromYamlTest.key)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesParseLocation() throws Exception {
|
||||
assertEquals(parser.apply(NodesFromYamlTest.TEST2), expectedNodeMetadataFromResource(resource, zoneCalled(
|
||||
"virginia", provider)));
|
||||
assertEquals(credentialStore, ImmutableMap.of("node#cluster-1", new Credentials("myUser", NodesFromYamlTest.key)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,29 +41,47 @@ public class NodesFromYamlTest {
|
|||
.toString();
|
||||
|
||||
public static final Node TEST1 = new Node("cluster-1", "cluster-1", "accounting analytics cluster",
|
||||
"cluster-1.mydomain.com", "x86", "rhel", "redhat", "5.3", "hadoop", ImmutableList.of("vanilla"), "myUser",
|
||||
key, null, "happy bear");
|
||||
"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", 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", 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));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesParseLocation() throws Exception {
|
||||
|
||||
InputStream is = getClass().getResourceAsStream("/test_location.yaml");
|
||||
NodesFromYamlStream parser = new NodesFromYamlStream();
|
||||
|
||||
assertEquals(parser.apply(is), ImmutableMap.of(TEST2.getId(), TEST2, TEST3.getId(), TEST3));
|
||||
}
|
||||
|
||||
@Test
|
||||
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(""));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
nodes:
|
||||
- id: cluster-1
|
||||
name: cluster-1
|
||||
description: accounting analytics cluster
|
||||
hostname: cluster-1.mydomain.com
|
||||
location_id: virginia
|
||||
os_arch: x86
|
||||
os_family: rhel
|
||||
os_description: redhat
|
||||
os_version: 5.3
|
||||
group: hadoop
|
||||
tags:
|
||||
- vanilla
|
||||
username: myUser
|
||||
credential: |
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2
|
||||
u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ
|
||||
lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o
|
||||
-----END RSA PRIVATE KEY-----
|
||||
sudo_password: happy bear
|
||||
|
||||
- id: cluster-2
|
||||
name: cluster-2
|
||||
description: accounting analytics cluster
|
||||
hostname: cluster-2.mydomain.com
|
||||
location_id: maryland
|
||||
os_arch: x86
|
||||
os_family: rhel
|
||||
os_description: redhat
|
||||
os_version: 5.3
|
||||
group: hadoop
|
||||
tags:
|
||||
- vanilla
|
||||
username: myUser
|
||||
credential: |
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2
|
||||
u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ
|
||||
lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o
|
||||
-----END RSA PRIVATE KEY-----
|
||||
sudo_password: happy bear
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
<artifactId>cloudfiles</artifactId>
|
||||
<name>jcloud cloudfiles api</name>
|
||||
<description>jclouds components to access an implementation of CloudFiles</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<properties>
|
||||
<test.initializer>org.jclouds.cloudfiles.blobstore.integration.CloudFilesTestInitializer</test.initializer>
|
||||
|
@ -145,6 +146,21 @@
|
|||
</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.cloudfiles.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
|
|
|
@ -29,10 +29,12 @@
|
|||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../../project/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>org.jclouds.api</groupId>
|
||||
<artifactId>cloudservers</artifactId>
|
||||
<name>jcloud cloudservers api</name>
|
||||
<description>jclouds components to access an implementation of CloudServers</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<properties>
|
||||
<test.cloudservers.endpoint>https://auth.api.rackspacecloud.com</test.cloudservers.endpoint>
|
||||
|
@ -145,6 +147,21 @@
|
|||
</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.cloudservers.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
<artifactId>deltacloud</artifactId>
|
||||
<name>jclouds deltacloud core</name>
|
||||
<description>jclouds components to access deltacloud</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<!-- bootstrapping: need to fetch the project POM -->
|
||||
<repositories>
|
||||
|
@ -141,4 +142,21 @@
|
|||
</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.deltacloud.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<artifactId>ec2</artifactId>
|
||||
<name>jcloud ec2 api</name>
|
||||
<description>jclouds components to access an implementation of EC2</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<properties>
|
||||
<!-- when instances are hung, open a ticket and add here -->
|
||||
|
@ -142,6 +143,21 @@
|
|||
</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.ec2.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
|
|
|
@ -25,20 +25,20 @@
|
|||
(:use (clojure.contrib def core))
|
||||
(:import org.jclouds.aws.domain.Region
|
||||
org.jclouds.compute.domain.NodeMetadata
|
||||
(org.jclouds.aws.ec2.domain Volume Volume$Status Snapshot Snapshot$Status AvailabilityZone)
|
||||
(org.jclouds.aws.ec2.options DescribeSnapshotsOptions DetachVolumeOptions CreateSnapshotOptions)))
|
||||
(org.jclouds.ec2.domain Volume Volume$Status Snapshot Snapshot$Status AvailabilityZoneInfo)
|
||||
(org.jclouds.ec2.options DescribeSnapshotsOptions DetachVolumeOptions CreateSnapshotOptions)))
|
||||
|
||||
(defn snapshot?
|
||||
"Returns true iff the argument is a org.jclouds.aws.ec2.domain.Snapshot."
|
||||
"Returns true iff the argument is a org.jclouds.ec2.domain.Snapshot."
|
||||
[s]
|
||||
(instance? Snapshot s))
|
||||
|
||||
(defn volume?
|
||||
"Returns true iff the argument is a org.jclouds.aws.ec2.domain.Volume."
|
||||
"Returns true iff the argument is a org.jclouds.ec2.domain.Volume."
|
||||
[v]
|
||||
(instance? Volume v))
|
||||
|
||||
(defn #^org.jclouds.aws.ec2.services.ElasticBlockStoreClient
|
||||
(defn #^org.jclouds.ec2.services.ElasticBlockStoreClient
|
||||
ebs-service
|
||||
"Returns the synchronous ElasticBlockStoreClient associated with
|
||||
the specified compute service, or compute/*compute* as bound by with-compute-service."
|
||||
|
@ -74,7 +74,7 @@
|
|||
(str "Can't obtain volume id from argument of type " (class v))))))
|
||||
|
||||
(defn volumes
|
||||
"Returns a set of org.jclouds.aws.ec2.domain.Volume instances corresponding to the
|
||||
"Returns a set of org.jclouds.ec2.domain.Volume instances corresponding to the
|
||||
volumes in the specified region (defaulting to your account's default region).
|
||||
|
||||
e.g. (with-compute-service [compute] (volumes))
|
||||
|
@ -172,7 +172,7 @@
|
|||
(defn get-zone
|
||||
[v]
|
||||
(cond
|
||||
(instance? AvailabilityZone v) v
|
||||
(instance? AvailabilityZoneInfo v) (.getZone v)
|
||||
(instance? NodeMetadata v) (compute/location #^NodeMetadata v)
|
||||
(string? v) v
|
||||
(keyword? v) (name v)
|
||||
|
@ -225,14 +225,14 @@
|
|||
(defn create-volume
|
||||
"Creates a new volume given a set of options:
|
||||
|
||||
- one of :zone (keyword, string, or AvailabilityZone) or :node (NodeMetadata)
|
||||
- one of :zone (keyword, string, or AvailabilityZoneInfo) or :node (NodeMetadata)
|
||||
- one or both of :snapshot (keyword, string, or Snapshot instance) or :size
|
||||
(string, keyword, or number)
|
||||
- :device (string or keyword) provided *only* when you want to attach the new volume to
|
||||
the :node you specified!
|
||||
|
||||
Returns a vector of [created org.jclouds.aws.ec2.domain.Volume,
|
||||
optional org.jclouds.aws.ec2.domain.Attachment]
|
||||
Returns a vector of [created org.jclouds.ec2.domain.Volume,
|
||||
optional org.jclouds.ec2.domain.Attachment]
|
||||
|
||||
Note that specifying :node instead of :zone will only attach the created volume
|
||||
:device is also provided. Otherwise, the node is only used to obtain the desired
|
||||
|
|
|
@ -22,12 +22,12 @@
|
|||
:doc "A clojure binding for the jclouds AWS elastic IP address interface."}
|
||||
org.jclouds.ec2.elastic-ip
|
||||
(:require (org.jclouds [compute :as compute])
|
||||
[org.jclouds.aws.ebs :as ebs])
|
||||
[org.jclouds.ec2.ebs :as ebs])
|
||||
(:use (clojure.contrib def core))
|
||||
(:import org.jclouds.compute.domain.NodeMetadata
|
||||
(org.jclouds.aws.ec2.domain PublicIpInstanceIdPair)))
|
||||
(org.jclouds.ec2.domain PublicIpInstanceIdPair)))
|
||||
|
||||
(defn #^org.jclouds.aws.ec2.services.ElasticIPAddressClient
|
||||
(defn #^org.jclouds.ec2.services.ElasticIPAddressClient
|
||||
eip-service
|
||||
"Returns the synchronous ElasticIPAddressClient associated with
|
||||
the specified compute service, or compute/*compute* as bound by with-compute-service."
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.jclouds.Constants;
|
|||
import org.jclouds.aws.util.AWSUtils;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.callables.RunScriptOnNode;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
|
@ -91,14 +92,16 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess,
|
||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory,
|
||||
RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess,
|
||||
PersistNodeCredentials persistNodeCredentials, Timeouts timeouts,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
|
||||
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap) {
|
||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy,
|
||||
templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended,
|
||||
initScriptRunnerFactory, initAdminAccess, persistNodeCredentials, timeouts, executor);
|
||||
initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, persistNodeCredentials, timeouts,
|
||||
executor);
|
||||
this.ec2Client = ec2Client;
|
||||
this.credentialsMap = credentialsMap;
|
||||
this.securityGroupMap = securityGroupMap;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
<artifactId>elasticstack</artifactId>
|
||||
<name>jclouds elasticstack core</name>
|
||||
<description>jclouds components to access elasticstack</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<!-- bootstrapping: need to fetch the project POM -->
|
||||
<repositories>
|
||||
|
@ -147,4 +148,20 @@
|
|||
</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.elastichosts.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<artifactId>eucalyptus</artifactId>
|
||||
<name>jclouds Eucalyptus api</name>
|
||||
<description>EC2 implementation based on Eucalyptus</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<properties>
|
||||
<test.eucalyptus.endpoint>http://ecc.eucalyptus.com:8773/services/Eucalyptus</test.eucalyptus.endpoint>
|
||||
|
@ -136,6 +137,21 @@
|
|||
</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.eucalyptus.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<artifactId>filesystem</artifactId>
|
||||
<name>jcloud filesystem core</name>
|
||||
<description>jclouds components to access filesystem</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
@ -72,5 +73,21 @@
|
|||
<test.initializer>org.jclouds.filesystem.integration.FilesystemTestInitializer</test.initializer>
|
||||
</properties>
|
||||
|
||||
<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.filesystem.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<artifactId>nova</artifactId>
|
||||
<name>jcloud nova api</name>
|
||||
<description>jclouds components to access an implementation of OpenStack Nova</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<properties>
|
||||
|
||||
|
@ -96,22 +97,6 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-remote-resources-plugin</artifactId>
|
||||
<version>1.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>process-remote-resources</id>
|
||||
<!-- plugin is tuned off due to incorrect work in Eclipse-->
|
||||
<phase></phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>live</id>
|
||||
|
@ -175,5 +160,20 @@
|
|||
</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.openstack.nova.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -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[]{}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<artifactId>s3</artifactId>
|
||||
<name>jcloud s3 api</name>
|
||||
<description>jclouds components to access an implementation of S3</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<properties>
|
||||
<test.initializer>org.jclouds.s3.blobstore.integration.S3TestInitializer</test.initializer>
|
||||
|
@ -143,6 +144,21 @@
|
|||
</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.s3.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<artifactId>scality-rs2</artifactId>
|
||||
<name>jclouds Eucalyptus Walrus api</name>
|
||||
<description>Simple Storage Service (S3) implementation based on Scality RING RS2</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<properties>
|
||||
<test.initializer>org.jclouds.scality.rs2.blobstore.ScalityRS2TestInitializer</test.initializer>
|
||||
|
@ -139,6 +140,21 @@
|
|||
</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.scality.rs2.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<artifactId>swift</artifactId>
|
||||
<name>jcloud swift api</name>
|
||||
<description>jclouds components to access an implementation of OpenStack Swift</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<properties>
|
||||
<test.initializer>org.jclouds.openstack.swift.blobstore.integration.SwiftTestInitializer</test.initializer>
|
||||
|
@ -143,6 +144,21 @@
|
|||
</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.openstack.swift.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
<artifactId>vcloud</artifactId>
|
||||
<name>jcloud vcloud api</name>
|
||||
<description>jclouds components to access an implementation of VMWare vCloud</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<properties>
|
||||
<!-- when instances are hung, open a ticket and add here -->
|
||||
|
@ -156,4 +157,20 @@
|
|||
</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.vcloud.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
<artifactId>vcloudexpress</artifactId>
|
||||
<name>jcloud vcloudexpress api</name>
|
||||
<description>jclouds components to access an implementation of VMWare vCloud Express</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<properties>
|
||||
<!-- when instances are hung, open a ticket and add here -->
|
||||
|
@ -156,4 +157,20 @@
|
|||
</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.vcloud.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<artifactId>walrus</artifactId>
|
||||
<name>jclouds Eucalyptus Walrus api</name>
|
||||
<description>Simple Storage Service (S3) implementation based on Eucalyptus Walrus</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<properties>
|
||||
<test.initializer>org.jclouds.walrus.blobstore.WalrusTestInitializer</test.initializer>
|
||||
|
@ -139,6 +140,21 @@
|
|||
</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.walrus.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
<artifactId>jclouds-blobstore</artifactId>
|
||||
<name>jclouds blobstore core</name>
|
||||
<description>jclouds components to access blobstore</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<scm>
|
||||
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/blobstore</connection>
|
||||
|
@ -118,6 +119,18 @@
|
|||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||
<Export-Package>org.jclouds.blobstore.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
<Fragment-Host>jclouds-core;version="${project.version}"</Fragment-Host>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
<artifactId>aws-common</artifactId>
|
||||
<name>jclouds Amazon AWS Components Core</name>
|
||||
<description>jclouds Core components to access Amazon AWS</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
@ -47,4 +49,20 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<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.aws.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -32,6 +32,8 @@
|
|||
<artifactId>azure-common</artifactId>
|
||||
<name>jclouds Azure Components Core</name>
|
||||
<description>jclouds Core components to access Azure</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
@ -47,4 +49,20 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<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.azure.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -28,10 +28,13 @@
|
|||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../../project/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>org.jclouds.common</groupId>
|
||||
<artifactId>openstack-common</artifactId>
|
||||
<name>jclouds Rackspace Components Core</name>
|
||||
<description>jclouds Core components to access Rackspace apis</description>
|
||||
<name>jclouds OpenStack Components Core</name>
|
||||
<description>jclouds Core components to access OpenStack apis</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
@ -47,4 +50,20 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<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.openstack.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -28,10 +28,13 @@
|
|||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../../project/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>org.jclouds.common</groupId>
|
||||
<artifactId>trmk-common</artifactId>
|
||||
<name>common Terremark components</name>
|
||||
<description>common Terremark components</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.api</groupId>
|
||||
|
@ -91,4 +94,20 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<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.vcloud.terremark.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -31,6 +31,7 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.Constants;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.callables.RunScriptOnNode;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
|
@ -77,14 +78,16 @@ public class TerremarkVCloudComputeService extends BaseComputeService {
|
|||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess,
|
||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory,
|
||||
RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess,
|
||||
PersistNodeCredentials persistNodeCredentials, Timeouts timeouts,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, CleanupOrphanKeys cleanupOrphanKeys,
|
||||
ConcurrentMap<OrgAndName, KeyPairCredentials> credentialsMap, NodeMetadataToOrgAndName nodeToOrgAndName) {
|
||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, resumeNodeStrategy,
|
||||
suspendNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated,
|
||||
nodeSuspended, initScriptRunnerFactory, initAdminAccess, persistNodeCredentials, timeouts, executor);
|
||||
nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, persistNodeCredentials,
|
||||
timeouts, executor);
|
||||
this.cleanupOrphanKeys = cleanupOrphanKeys;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,10 +28,13 @@
|
|||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../../project/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>org.jclouds.common</groupId>
|
||||
<artifactId>vcloud-common</artifactId>
|
||||
<name>common vCloud components</name>
|
||||
<description>common vCloud components</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.jamesmurty.utils</groupId>
|
||||
|
@ -82,4 +85,19 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<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.vcloud.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -28,7 +28,6 @@ import java.util.regex.Pattern;
|
|||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
|
@ -49,36 +48,35 @@ import com.google.common.base.Function;
|
|||
*/
|
||||
@Singleton
|
||||
public class ParseLoginResponseFromHeaders implements Function<HttpResponse, VCloudSession> {
|
||||
static final Pattern pattern = Pattern.compile("vcloud-token=([^;]+);.*");
|
||||
static final Pattern pattern = Pattern.compile("(vcloud-token=)?([^;]+)(;.*)?");
|
||||
|
||||
private final ParseSax.Factory factory;
|
||||
private final Provider<OrgListHandler> orgHandlerProvider;
|
||||
|
||||
@Inject
|
||||
private ParseLoginResponseFromHeaders(Factory factory,
|
||||
Provider<OrgListHandler> orgHandlerProvider) {
|
||||
private ParseLoginResponseFromHeaders(Factory factory, Provider<OrgListHandler> orgHandlerProvider) {
|
||||
this.factory = factory;
|
||||
this.orgHandlerProvider = orgHandlerProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* parses the http response headers to create a new {@link VCloudSession} object.
|
||||
* parses the http response headers to create a new {@link VCloudSession}
|
||||
* object.
|
||||
*/
|
||||
public VCloudSession apply(HttpResponse from) {
|
||||
String cookieHeader = checkNotNull(from.getFirstHeaderOrNull(HttpHeaders.SET_COOKIE),
|
||||
HttpHeaders.SET_COOKIE);
|
||||
String cookieHeader = checkNotNull(from.getFirstHeaderOrNull("x-vcloud-authorization"), "x-vcloud-authorization");
|
||||
|
||||
final Matcher matcher = pattern.matcher(cookieHeader);
|
||||
boolean matchFound = matcher.find();
|
||||
try {
|
||||
if (matchFound) {
|
||||
final Map<String, ReferenceType> org = factory.create(orgHandlerProvider.get()).parse(
|
||||
from.getPayload().getInput());
|
||||
from.getPayload().getInput());
|
||||
|
||||
return new VCloudSession() {
|
||||
@VCloudToken
|
||||
public String getVCloudToken() {
|
||||
return matcher.group(1);
|
||||
return matcher.group(2);
|
||||
}
|
||||
|
||||
@Org
|
||||
|
@ -91,6 +89,6 @@ public class ParseLoginResponseFromHeaders implements Function<HttpResponse, VCl
|
|||
} finally {
|
||||
releasePayload(from);
|
||||
}
|
||||
throw new HttpResponseException("not found ", null, from);
|
||||
throw new HttpResponseException("x-vcloud-authorization not found ", null, from);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.vcloud.xml;
|
||||
|
||||
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
|
||||
import static org.jclouds.vcloud.util.Utils.newReferenceType;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -271,11 +272,11 @@ public class OrgNetworkHandler extends ParseSax.HandlerWithResult<OrgNetwork> {
|
|||
this.vmNicId = -1;
|
||||
} else if (qName.equalsIgnoreCase("ExternalPort")) {
|
||||
externalPort = Integer.parseInt(currentOrNull());
|
||||
} else if (qName.equalsIgnoreCase("IxternalIP")) {
|
||||
} else if (qName.equalsIgnoreCase("InternalIP")) {
|
||||
internalIP = currentOrNull();
|
||||
} else if (qName.equalsIgnoreCase("InternalPort")) {
|
||||
internalPort = Integer.parseInt(currentOrNull());
|
||||
} else if (qName.equals("NatProtocol")) {
|
||||
} else if (equalsOrSuffix(qName, "Protocol")) {
|
||||
natProtocol = NatProtocol.valueOf(currentOrNull());
|
||||
} else if (qName.equals("PortForwardingRule")) {
|
||||
natRules.add(new PortForwardingRule(externalIP, externalPort, internalIP, internalPort, natProtocol));
|
||||
|
|
|
@ -22,8 +22,6 @@ import static org.testng.Assert.assertEquals;
|
|||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.jclouds.io.Payloads;
|
||||
|
@ -55,7 +53,7 @@ public class ParseLoginResponseFromHeadersTest extends BaseHandlerTest {
|
|||
@Test
|
||||
public void testApply() {
|
||||
HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass()
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String,String>of(HttpHeaders.SET_COOKIE, "vcloud-token=9er4d061-4bff-48fa-84b1-5da7166764d2; path=/"));
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String,String>of("x-vcloud-authorization", "vcloud-token=9er4d061-4bff-48fa-84b1-5da7166764d2; path=/"));
|
||||
response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8");
|
||||
response.getPayload().getContentMetadata().setContentLength(307l);
|
||||
|
||||
|
@ -69,15 +67,28 @@ public class ParseLoginResponseFromHeadersTest extends BaseHandlerTest {
|
|||
@Test
|
||||
public void testApplyBlueLock() {
|
||||
HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass()
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String,String>of(HttpHeaders.SET_COOKIE,"vcloud-token=c9f232506df9b65d7b7d97b7499eddd7; Domain=.bluelock.com; Path=/") );
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String,String>of("x-vcloud-authorization","MUKOJ2HoAfoMmLnHRp4esNb2MtWscCLLhVysnsIsCG0=") );
|
||||
response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8");
|
||||
response.getPayload().getContentMetadata().setContentLength(307l);
|
||||
|
||||
VCloudSession reply = parser.apply(response);
|
||||
assertEquals(reply.getVCloudToken(), "c9f232506df9b65d7b7d97b7499eddd7");
|
||||
assertEquals(reply.getVCloudToken(), "MUKOJ2HoAfoMmLnHRp4esNb2MtWscCLLhVysnsIsCG0=");
|
||||
assertEquals(reply.getOrgs(), ImmutableMap.of("adrian@jclouds.org", new ReferenceTypeImpl("adrian@jclouds.org",
|
||||
VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48"))));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyVirtacore() {
|
||||
HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass()
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String,String>of("x-vcloud-authorization","vcloud-token=IPy0w7UGD4lwtdWAK/ZVzfuLK+dztxGRqsOhWqV0i48=") );
|
||||
response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8");
|
||||
response.getPayload().getContentMetadata().setContentLength(307l);
|
||||
|
||||
VCloudSession reply = parser.apply(response);
|
||||
assertEquals(reply.getVCloudToken(), "IPy0w7UGD4lwtdWAK/ZVzfuLK+dztxGRqsOhWqV0i48=");
|
||||
assertEquals(reply.getOrgs(), ImmutableMap.of("adrian@jclouds.org", new ReferenceTypeImpl("adrian@jclouds.org",
|
||||
VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48"))));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,15 +29,11 @@
|
|||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../project/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>jclouds-compute</artifactId>
|
||||
<name>jclouds compute core</name>
|
||||
<description>jclouds components to access compute providers</description>
|
||||
|
||||
<scm>
|
||||
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/compute</connection>
|
||||
<developerConnection>scm:svn:https://jclouds.googlecode.com/svn/trunk/compute</developerConnection>
|
||||
<url>http://jclouds.googlecode.com/svn/trunk/compute</url>
|
||||
</scm>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
@ -70,4 +66,21 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<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.compute.*;version="${project.version}",org.jclouds.ssh.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>!org.jclouds.compute.*;org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
<Fragment-Host>jclouds-core;version="${project.version}"</Fragment-Host>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -69,7 +69,8 @@ Here's an example of creating and running a small linux node in the group webser
|
|||
[org.jclouds.compute.domain
|
||||
Template TemplateBuilder ComputeMetadata NodeMetadata Hardware
|
||||
OsFamily Image]
|
||||
[org.jclouds.compute.options TemplateOptions]
|
||||
[org.jclouds.compute.options TemplateOptions RunScriptOptions
|
||||
RunScriptOptions$Builder]
|
||||
[org.jclouds.compute.predicates
|
||||
NodePredicates]
|
||||
[com.google.common.collect ImmutableSet])
|
||||
|
@ -197,7 +198,7 @@ Here's an example of creating and running a small linux node in the group webser
|
|||
|
||||
(defn suspend-node
|
||||
"Suspend a node, given its id."
|
||||
([id #^ComputeService compute]
|
||||
([#^ComputeService compute id]
|
||||
(.suspendNode compute id)))
|
||||
|
||||
(defn resume-nodes-matching
|
||||
|
@ -208,7 +209,7 @@ Here's an example of creating and running a small linux node in the group webser
|
|||
|
||||
(defn resume-node
|
||||
"Resume a node, given its id."
|
||||
([id #^ComputeService compute]
|
||||
([#^ComputeService compute id]
|
||||
(.resumeNode compute id)))
|
||||
|
||||
(defn reboot-nodes-matching
|
||||
|
@ -219,7 +220,7 @@ Here's an example of creating and running a small linux node in the group webser
|
|||
|
||||
(defn reboot-node
|
||||
"Reboot a node, given its id."
|
||||
([id #^ComputeService compute]
|
||||
([#^ComputeService compute id]
|
||||
(.rebootNode compute id)))
|
||||
|
||||
(defn destroy-nodes-matching
|
||||
|
@ -230,9 +231,19 @@ Here's an example of creating and running a small linux node in the group webser
|
|||
|
||||
(defn destroy-node
|
||||
"Destroy a node, given its id."
|
||||
([id #^ComputeService compute]
|
||||
([#^ComputeService compute id]
|
||||
(.destroyNode compute id)))
|
||||
|
||||
(defn run-script-on-node
|
||||
"Run a script on a node"
|
||||
([#^ComputeService compute id command #^RunScriptOptions options]
|
||||
(.runScriptOnNode compute id command options)))
|
||||
|
||||
(defn run-script-on-nodes-matching
|
||||
"Run a script on the nodes matching the given predicate"
|
||||
([#^ComputeService compute pred command #^RunScriptOptions options]
|
||||
(.runScriptOnNodesMatching compute (to-predicate pred) command options)))
|
||||
|
||||
(defmacro state-predicate [node state]
|
||||
`(= (.getState ~node)
|
||||
(. org.jclouds.compute.domain.NodeState ~state)))
|
||||
|
|
|
@ -319,4 +319,40 @@ public interface ComputeService {
|
|||
Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
|
||||
Statement runScript, RunScriptOptions options) throws RunScriptOnNodesException;
|
||||
|
||||
/**
|
||||
* Run the script on a specific node
|
||||
*
|
||||
* @param id
|
||||
* node the script is to be executed on
|
||||
* @param runScript
|
||||
* statement containing the script to run
|
||||
* @param options
|
||||
* nullable options to how to run the script, whether to override credentials
|
||||
* @return map with node identifiers and corresponding responses
|
||||
* @throws NoSuchElementException
|
||||
* if the node is not found
|
||||
* @throws IllegalStateException
|
||||
* if the node is not in running state
|
||||
*
|
||||
* @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
|
||||
* @see org.jclouds.scriptbuilder.domain.Statements
|
||||
*/
|
||||
ExecResponse runScriptOnNode(String id, Statement runScript, RunScriptOptions options);
|
||||
|
||||
/**
|
||||
* @see #runScriptOnNode(String, Statement, RunScriptOptions)
|
||||
*/
|
||||
ExecResponse runScriptOnNode(String id, Statement runScript);
|
||||
|
||||
/**
|
||||
* @see #runScriptOnNode(String, Statement, RunScriptOptions)
|
||||
* @see org.jclouds.scriptbuilder.domain.Statements#exec
|
||||
*/
|
||||
ExecResponse runScriptOnNode(String id, String runScript, RunScriptOptions options);
|
||||
|
||||
/**
|
||||
* @see #runScriptOnNode(String, String, RunScriptOptions)
|
||||
*/
|
||||
ExecResponse runScriptOnNode(String id, String runScript);
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -42,7 +42,7 @@ public class OsFamilyVersion64Bit {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OsFamilyVersion64Bit [family=" + family + ", version=" + version + ", is64Bit=" + is64Bit + "]";
|
||||
return "[family=" + family + ", version=" + version + ", is64Bit=" + is64Bit + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -557,10 +557,10 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
|||
}
|
||||
|
||||
protected Hardware resolveSize(Ordering<Hardware> hardwareOrdering, final Iterable<? extends Image> images) {
|
||||
Set<? extends Hardware> hardwaresl = hardwares.get();
|
||||
Set<? extends Hardware> hardwarel = hardwares.get();
|
||||
Hardware hardware;
|
||||
try {
|
||||
Iterable<? extends Hardware> hardwaresThatAreCompatibleWithOurImages = filter(hardwaresl,
|
||||
Iterable<? extends Hardware> hardwaresThatAreCompatibleWithOurImages = filter(hardwarel,
|
||||
new Predicate<Hardware>() {
|
||||
@Override
|
||||
public boolean apply(final Hardware hardware) {
|
||||
|
@ -582,7 +582,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
|||
});
|
||||
hardware = hardwareOrdering.max(filter(hardwaresThatAreCompatibleWithOurImages, hardwarePredicate));
|
||||
} catch (NoSuchElementException exception) {
|
||||
throw new NoSuchElementException("hardwares don't support any images: " + toString() + "\n" + hardwaresl
|
||||
throw new NoSuchElementException("hardware don't support any images: " + toString() + "\n" + hardwarel
|
||||
+ "\n" + images);
|
||||
}
|
||||
logger.debug("<< matched hardware(%s)", hardware);
|
||||
|
|
|
@ -62,6 +62,7 @@ import org.jclouds.compute.domain.Hardware;
|
|||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.options.RunScriptOptions;
|
||||
|
@ -78,8 +79,8 @@ import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
|||
import org.jclouds.compute.strategy.RunScriptOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Credentials.Builder;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.Credentials.Builder;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
|
@ -132,22 +133,25 @@ public class BaseComputeService implements ComputeService {
|
|||
private final Timeouts timeouts;
|
||||
private final InitAdminAccess initAdminAccess;
|
||||
private final PersistNodeCredentials persistNodeCredentials;
|
||||
private final RunScriptOnNode.Factory runScriptOnNodeFactory;
|
||||
private final ExecutorService executor;
|
||||
|
||||
@Inject
|
||||
protected BaseComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore,
|
||||
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> hardwareProfiles,
|
||||
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
ResumeNodeStrategy resumeNodeStrategy, SuspendNodeStrategy suspendNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess,
|
||||
PersistNodeCredentials persistNodeCredentials, Timeouts timeouts,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
@Memoized Supplier<Set<? extends Image>> images,
|
||||
@Memoized Supplier<Set<? extends Hardware>> hardwareProfiles,
|
||||
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy,
|
||||
CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy,
|
||||
DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy resumeNodeStrategy,
|
||||
SuspendNodeStrategy suspendNodeStrategy, Provider<TemplateBuilder> templateBuilderProvider,
|
||||
Provider<TemplateOptions> templateOptionsProvider,
|
||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess,
|
||||
RunScriptOnNode.Factory runScriptOnNodeFactory, PersistNodeCredentials persistNodeCredentials,
|
||||
Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
this.context = checkNotNull(context, "context");
|
||||
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
||||
this.images = checkNotNull(images, "images");
|
||||
|
@ -168,6 +172,7 @@ public class BaseComputeService implements ComputeService {
|
|||
this.initScriptRunnerFactory = checkNotNull(initScriptRunnerFactory, "initScriptRunnerFactory");
|
||||
this.timeouts = checkNotNull(timeouts, "timeouts");
|
||||
this.initAdminAccess = checkNotNull(initAdminAccess, "initAdminAccess");
|
||||
this.runScriptOnNodeFactory = checkNotNull(runScriptOnNodeFactory, "runScriptOnNodeFactory");
|
||||
this.persistNodeCredentials = checkNotNull(persistNodeCredentials, "persistNodeCredentials");
|
||||
this.executor = checkNotNull(executor, "executor");
|
||||
}
|
||||
|
@ -185,7 +190,7 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> runNodesWithTag(String group, int count, Template template)
|
||||
throws RunNodesException {
|
||||
throws RunNodesException {
|
||||
return createNodesInGroup(group, count, template);
|
||||
}
|
||||
|
||||
|
@ -194,7 +199,7 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> runNodesWithTag(String group, int count, TemplateOptions templateOptions)
|
||||
throws RunNodesException {
|
||||
throws RunNodesException {
|
||||
return createNodesInGroup(group, count, templateBuilder().any().options(templateOptions).build());
|
||||
}
|
||||
|
||||
|
@ -208,12 +213,12 @@ public class BaseComputeService implements ComputeService {
|
|||
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, Template template)
|
||||
throws RunNodesException {
|
||||
throws RunNodesException {
|
||||
checkNotNull(group, "group cannot be null");
|
||||
checkNotNull(template.getLocation(), "location");
|
||||
logger.debug(">> running %d node%s group(%s) location(%s) image(%s) hardwareProfile(%s) options(%s)", count,
|
||||
count > 1 ? "s" : "", group, template.getLocation().getId(), template.getImage().getId(), template
|
||||
.getHardware().getId(), template.getOptions());
|
||||
count > 1 ? "s" : "", group, template.getLocation().getId(), template.getImage().getId(), template
|
||||
.getHardware().getId(), template.getOptions());
|
||||
Set<NodeMetadata> goodNodes = newLinkedHashSet();
|
||||
Map<NodeMetadata, Exception> badNodes = newLinkedHashMap();
|
||||
Multimap<NodeMetadata, CustomizationResponse> customizationResponses = LinkedHashMultimap.create();
|
||||
|
@ -222,9 +227,9 @@ public class BaseComputeService implements ComputeService {
|
|||
template.getOptions().runScript(initAdminAccess.apply(template.getOptions().getRunScript()));
|
||||
|
||||
Map<?, Future<Void>> responses = runNodesAndAddToSetStrategy.execute(group, count, template, goodNodes, badNodes,
|
||||
customizationResponses);
|
||||
customizationResponses);
|
||||
Map<?, Exception> executionExceptions = awaitCompletion(responses, executor, null, logger, "runNodesWithTag("
|
||||
+ group + ")");
|
||||
+ group + ")");
|
||||
Function<NodeMetadata, NodeMetadata> fn = persistNodeCredentials.always(template.getOptions().getRunScript());
|
||||
badNodes = Maps2.transformKeys(badNodes, fn);
|
||||
goodNodes = ImmutableSet.copyOf(Iterables.transform(goodNodes, fn));
|
||||
|
@ -236,7 +241,7 @@ public class BaseComputeService implements ComputeService {
|
|||
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, TemplateOptions templateOptions)
|
||||
throws RunNodesException {
|
||||
throws RunNodesException {
|
||||
return createNodesInGroup(group, count, templateBuilder().any().options(templateOptions).build());
|
||||
}
|
||||
|
||||
|
@ -282,27 +287,27 @@ public class BaseComputeService implements ComputeService {
|
|||
public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
|
||||
logger.debug(">> destroying nodes matching(%s)", filter);
|
||||
Set<NodeMetadata> set = newLinkedHashSet(transformParallel(nodesMatchingFilterAndNotTerminated(filter),
|
||||
new Function<NodeMetadata, Future<NodeMetadata>>() {
|
||||
new Function<NodeMetadata, Future<NodeMetadata>>() {
|
||||
|
||||
// TODO make an async interface instead of re-wrapping
|
||||
@Override
|
||||
public Future<NodeMetadata> apply(final NodeMetadata from) {
|
||||
return executor.submit(new Callable<NodeMetadata>() {
|
||||
// TODO make an async interface instead of re-wrapping
|
||||
@Override
|
||||
public Future<NodeMetadata> apply(final NodeMetadata from) {
|
||||
return executor.submit(new Callable<NodeMetadata>() {
|
||||
|
||||
@Override
|
||||
public NodeMetadata call() throws Exception {
|
||||
destroyNode(from.getId());
|
||||
return from;
|
||||
}
|
||||
@Override
|
||||
public NodeMetadata call() throws Exception {
|
||||
destroyNode(from.getId());
|
||||
return from;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "destroyNode(" + from.getId() + ")";
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "destroyNode(" + from.getId() + ")";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}, executor, null, logger, "destroyNodesMatching(" + filter + ")"));
|
||||
}, executor, null, logger, "destroyNodesMatching(" + filter + ")"));
|
||||
logger.debug("<< destroyed(%d)", set.size());
|
||||
return set;
|
||||
}
|
||||
|
@ -316,7 +321,7 @@ public class BaseComputeService implements ComputeService {
|
|||
* if none found
|
||||
*/
|
||||
Iterable<? extends NodeMetadata> nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(
|
||||
Predicate<NodeMetadata> filter) {
|
||||
Predicate<NodeMetadata> filter) {
|
||||
Iterable<? extends NodeMetadata> nodes = nodesMatchingFilterAndNotTerminated(filter);
|
||||
if (Iterables.size(nodes) == 0)
|
||||
throw new NoSuchElementException("no nodes matched filter: " + filter);
|
||||
|
@ -406,15 +411,15 @@ public class BaseComputeService implements ComputeService {
|
|||
public void rebootNodesMatching(Predicate<NodeMetadata> filter) {
|
||||
logger.debug(">> rebooting nodes matching(%s)", filter);
|
||||
transformParallel(nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter),
|
||||
new Function<NodeMetadata, Future<Void>>() {
|
||||
// TODO use native async
|
||||
@Override
|
||||
public Future<Void> apply(NodeMetadata from) {
|
||||
rebootNode(from.getId());
|
||||
return immediateFuture(null);
|
||||
}
|
||||
new Function<NodeMetadata, Future<Void>>() {
|
||||
// TODO use native async
|
||||
@Override
|
||||
public Future<Void> apply(NodeMetadata from) {
|
||||
rebootNode(from.getId());
|
||||
return immediateFuture(null);
|
||||
}
|
||||
|
||||
}, executor, null, logger, "rebootNodesMatching(" + filter + ")");
|
||||
}, executor, null, logger, "rebootNodesMatching(" + filter + ")");
|
||||
logger.debug("<< rebooted");
|
||||
}
|
||||
|
||||
|
@ -437,15 +442,15 @@ public class BaseComputeService implements ComputeService {
|
|||
public void resumeNodesMatching(Predicate<NodeMetadata> filter) {
|
||||
logger.debug(">> resuming nodes matching(%s)", filter);
|
||||
transformParallel(nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter),
|
||||
new Function<NodeMetadata, Future<Void>>() {
|
||||
// TODO use native async
|
||||
@Override
|
||||
public Future<Void> apply(NodeMetadata from) {
|
||||
resumeNode(from.getId());
|
||||
return immediateFuture(null);
|
||||
}
|
||||
new Function<NodeMetadata, Future<Void>>() {
|
||||
// TODO use native async
|
||||
@Override
|
||||
public Future<Void> apply(NodeMetadata from) {
|
||||
resumeNode(from.getId());
|
||||
return immediateFuture(null);
|
||||
}
|
||||
|
||||
}, executor, null, logger, "resumeNodesMatching(" + filter + ")");
|
||||
}, executor, null, logger, "resumeNodesMatching(" + filter + ")");
|
||||
logger.debug("<< resumed");
|
||||
}
|
||||
|
||||
|
@ -468,15 +473,15 @@ public class BaseComputeService implements ComputeService {
|
|||
public void suspendNodesMatching(Predicate<NodeMetadata> filter) {
|
||||
logger.debug(">> suspending nodes matching(%s)", filter);
|
||||
transformParallel(nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter),
|
||||
new Function<NodeMetadata, Future<Void>>() {
|
||||
// TODO use native async
|
||||
@Override
|
||||
public Future<Void> apply(NodeMetadata from) {
|
||||
suspendNode(from.getId());
|
||||
return immediateFuture(null);
|
||||
}
|
||||
new Function<NodeMetadata, Future<Void>>() {
|
||||
// TODO use native async
|
||||
@Override
|
||||
public Future<Void> apply(NodeMetadata from) {
|
||||
suspendNode(from.getId());
|
||||
return immediateFuture(null);
|
||||
}
|
||||
|
||||
}, executor, null, logger, "suspendNodesMatching(" + filter + ")");
|
||||
}, executor, null, logger, "suspendNodesMatching(" + filter + ")");
|
||||
logger.debug("<< suspended");
|
||||
}
|
||||
|
||||
|
@ -485,7 +490,7 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Payload runScript)
|
||||
throws RunScriptOnNodesException {
|
||||
throws RunScriptOnNodesException {
|
||||
return runScriptOnNodesMatching(filter, runScript, RunScriptOptions.NONE);
|
||||
}
|
||||
|
||||
|
@ -494,10 +499,10 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Payload runScript,
|
||||
RunScriptOptions options) throws RunScriptOnNodesException {
|
||||
RunScriptOptions options) throws RunScriptOnNodesException {
|
||||
try {
|
||||
return runScriptOnNodesMatching(filter,
|
||||
Statements.exec(Strings2.toStringAndClose(checkNotNull(runScript, "runScript").getInput())), options);
|
||||
return runScriptOnNodesMatching(filter, Statements.exec(Strings2.toStringAndClose(checkNotNull(runScript,
|
||||
"runScript").getInput())), options);
|
||||
} catch (IOException e) {
|
||||
Throwables.propagate(e);
|
||||
return null;
|
||||
|
@ -509,7 +514,7 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, String runScript)
|
||||
throws RunScriptOnNodesException {
|
||||
throws RunScriptOnNodesException {
|
||||
return runScriptOnNodesMatching(filter, Statements.exec(checkNotNull(runScript, "runScript")));
|
||||
}
|
||||
|
||||
|
@ -518,15 +523,15 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Statement runScript)
|
||||
throws RunScriptOnNodesException {
|
||||
throws RunScriptOnNodesException {
|
||||
return runScriptOnNodesMatching(filter, runScript, RunScriptOptions.NONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
|
||||
String runScript, RunScriptOptions options) throws RunScriptOnNodesException {
|
||||
String runScript, RunScriptOptions options) throws RunScriptOnNodesException {
|
||||
return runScriptOnNodesMatching(filter, Statements.exec(checkNotNull(runScript, "runScript")),
|
||||
RunScriptOptions.NONE);
|
||||
RunScriptOptions.NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -534,7 +539,7 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Statement runScript,
|
||||
RunScriptOptions options) throws RunScriptOnNodesException {
|
||||
RunScriptOptions options) throws RunScriptOnNodesException {
|
||||
|
||||
checkNotNull(filter, "filter");
|
||||
checkNotNull(runScript, "runScript");
|
||||
|
@ -548,11 +553,11 @@ public class BaseComputeService implements ComputeService {
|
|||
runScript = initAdminAccess.apply(runScript);
|
||||
|
||||
Iterable<? extends RunScriptOnNode> scriptRunners = transformNodesIntoInitializedScriptRunners(
|
||||
nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter), runScript, options, badNodes);
|
||||
nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter), runScript, options, badNodes);
|
||||
if (Iterables.size(scriptRunners) > 0) {
|
||||
for (RunScriptOnNode runner : scriptRunners) {
|
||||
responses.put(runner.getNode(), executor.submit(new RunScriptOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap(
|
||||
runner, goodNodes, badNodes)));
|
||||
runner, goodNodes, badNodes)));
|
||||
}
|
||||
exceptions = awaitCompletion(responses, executor, null, logger, "runScriptOnNodesMatching(" + filter + ")");
|
||||
}
|
||||
|
@ -566,13 +571,50 @@ public class BaseComputeService implements ComputeService {
|
|||
}
|
||||
return goodNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public ExecResponse runScriptOnNode(String id, String runScript) {
|
||||
return runScriptOnNode(id, runScript, RunScriptOptions.NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public ExecResponse runScriptOnNode(String id, String runScript, RunScriptOptions options) {
|
||||
return runScriptOnNode(id, Statements.exec(checkNotNull(runScript, "runScript")), options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public ExecResponse runScriptOnNode(String id, Statement runScript) {
|
||||
return runScriptOnNode(id, runScript, RunScriptOptions.NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public ExecResponse runScriptOnNode(String id, Statement runScript, RunScriptOptions options) {
|
||||
NodeMetadata node = this.getNodeMetadata(id);
|
||||
if (node == null)
|
||||
throw new NoSuchElementException(id);
|
||||
if (node.getState() != NodeState.RUNNING)
|
||||
throw new IllegalStateException("node " + id
|
||||
+ " needs to be running before executing a script on it. current state: " + node.getState());
|
||||
return runScriptOnNodeFactory.create(node, runScript, options).init().call();
|
||||
}
|
||||
|
||||
private Iterable<? extends RunScriptOnNode> transformNodesIntoInitializedScriptRunners(
|
||||
Iterable<? extends NodeMetadata> nodes, Statement script, RunScriptOptions options,
|
||||
Map<NodeMetadata, Exception> badNodes) {
|
||||
return filter(
|
||||
transformParallel(nodes, new TransformNodesIntoInitializedScriptRunners(script, options, badNodes),
|
||||
executor, null, logger, "initialize script runners"), notNull());
|
||||
Iterable<? extends NodeMetadata> nodes, Statement script, RunScriptOptions options,
|
||||
Map<NodeMetadata, Exception> badNodes) {
|
||||
return filter(transformParallel(nodes, new TransformNodesIntoInitializedScriptRunners(script, options, badNodes),
|
||||
executor, null, logger, "initialize script runners"), notNull());
|
||||
}
|
||||
|
||||
private Set<? extends NodeMetadata> detailsOnAllNodes() {
|
||||
|
@ -585,13 +627,13 @@ public class BaseComputeService implements ComputeService {
|
|||
}
|
||||
|
||||
private final class TransformNodesIntoInitializedScriptRunners implements
|
||||
Function<NodeMetadata, Future<RunScriptOnNode>> {
|
||||
Function<NodeMetadata, Future<RunScriptOnNode>> {
|
||||
private final Map<NodeMetadata, Exception> badNodes;
|
||||
private final Statement script;
|
||||
private final RunScriptOptions options;
|
||||
|
||||
private TransformNodesIntoInitializedScriptRunners(Statement script, RunScriptOptions options,
|
||||
Map<NodeMetadata, Exception> badNodes) {
|
||||
Map<NodeMetadata, Exception> badNodes) {
|
||||
this.badNodes = checkNotNull(badNodes, "badNodes");
|
||||
this.script = checkNotNull(script, "script");
|
||||
this.options = checkNotNull(options, "options");
|
||||
|
@ -602,7 +644,7 @@ public class BaseComputeService implements ComputeService {
|
|||
checkNotNull(node, "node");
|
||||
if (options.getOverridingCredentials() != null) {
|
||||
Builder<? extends Credentials> builder = node.getCredentials() != null ? node.getCredentials().toBuilder()
|
||||
: new Credentials.Builder<Credentials>();
|
||||
: new Credentials.Builder<Credentials>();
|
||||
if (options.getOverridingCredentials().identity != null)
|
||||
builder.identity(options.getOverridingCredentials().identity);
|
||||
if (options.getOverridingCredentials().credential != null)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -57,7 +57,7 @@ public interface ComputeServiceConstants {
|
|||
public static class ReferenceData {
|
||||
@Inject(optional = true)
|
||||
@Named(PROPERTY_OS_VERSION_MAP_JSON)
|
||||
public String osVersionMapJson = "{\"centos\":{\"\":\"\",\"5\":\"5.0\",\"5.2\":\"5.2\",\"5.3\":\"5.3\",\"5.4\":\"5.4\",\"5.5\":\"5.5\"},\"rhel\":{\"\":\"\",\"5\":\"5.0\",\"5.2\":\"5.2\",\"5.3\":\"5.3\",\"5.4\":\"5.4\",\"5.5\":\"5.5\"},\"solaris\":{\"\":\"\",\"10\":\"10\"},\"ubuntu\":{\"\":\"\",\"hardy\":\"8.04\",\"karmic\":\"9.10\",\"lucid\":\"10.04\",\"maverick\":\"10.10\",\"natty\":\"11.04\"},\"windows\":{\"\":\"\",\"2003\":\"2003\",\"2003 Standard\":\"2003\",\"2003 R2\":\"2003 R2\",\"2008\":\"2008\",\"2008 Web\":\"2008\",\"2008 Server\":\"2008\",\"Server 2008\":\"2008\",\"2008 R2\":\"2008 R2\",\"Server 2008 R2\":\"2008 R2\",\"2008 Server R2\":\"2008 R2\",\"2008 SP2\":\"2008 SP2\",\"Server 2008 SP2\":\"2008 SP2\"}}";
|
||||
public String osVersionMapJson = "{\"suse\":{\"\":\"\",\"11\":\"11\",\"11 SP1\":\"11 SP1\"},\"centos\":{\"\":\"\",\"5\":\"5.0\",\"5.2\":\"5.2\",\"5.3\":\"5.3\",\"5.4\":\"5.4\",\"5.5\":\"5.5\"},\"rhel\":{\"\":\"\",\"5\":\"5.0\",\"5.2\":\"5.2\",\"5.3\":\"5.3\",\"5.4\":\"5.4\",\"5.5\":\"5.5\"},\"solaris\":{\"\":\"\",\"10\":\"10\"},\"ubuntu\":{\"\":\"\",\"hardy\":\"8.04\",\"karmic\":\"9.10\",\"lucid\":\"10.04\",\"maverick\":\"10.10\",\"natty\":\"11.04\"},\"windows\":{\"\":\"\",\"2003\":\"2003\",\"2003 Standard\":\"2003\",\"2003 R2\":\"2003 R2\",\"2008\":\"2008\",\"2008 Web\":\"2008\",\"2008 Server\":\"2008\",\"Server 2008\":\"2008\",\"2008 R1\":\"2008 R1\",\"2008 R2\":\"2008 R2\",\"Server 2008 R2\":\"2008 R2\",\"2008 Server R2\":\"2008 R2\",\"2008 SP2\":\"2008 SP2\",\"Server 2008 SP2\":\"2008 SP2\"}}";
|
||||
}
|
||||
|
||||
@Singleton
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -105,6 +105,8 @@ public class ComputeServiceUtils {
|
|||
* @return null if group cannot be parsed
|
||||
*/
|
||||
public static String parseGroupFromName(String from) {
|
||||
if (from == null)
|
||||
return null;
|
||||
Matcher matcher = DELIMETED_BY_HYPHEN_ENDING_IN_HYPHEN_HEX.matcher(from);
|
||||
return matcher.find() ? matcher.group(1) : null;
|
||||
}
|
||||
|
|
|
@ -20,10 +20,19 @@
|
|||
(ns org.jclouds.compute2-test
|
||||
(:use [org.jclouds.compute2] :reload-all)
|
||||
(:use clojure.test)
|
||||
(:require [org.jclouds.ssh-test :as ssh-test])
|
||||
(:import
|
||||
org.jclouds.compute.domain.OsFamily
|
||||
clojure.contrib.condition.Condition))
|
||||
|
||||
org.jclouds.compute.domain.OsFamily
|
||||
clojure.contrib.condition.Condition
|
||||
java.net.InetAddress
|
||||
org.jclouds.scriptbuilder.domain.Statements
|
||||
org.jclouds.compute.options.TemplateOptions
|
||||
org.jclouds.compute.options.TemplateOptions$Builder
|
||||
org.jclouds.compute.options.RunScriptOptions
|
||||
org.jclouds.compute.options.RunScriptOptions$Builder
|
||||
org.jclouds.domain.Credentials
|
||||
java.util.NoSuchElementException
|
||||
))
|
||||
|
||||
(defmacro with-private-vars [[ns fns] & tests]
|
||||
"Refers private fns from ns and runs tests in context. From users mailing
|
||||
|
@ -34,16 +43,16 @@ list, Alan Dipert and MeikelBrandmeyer."
|
|||
(deftest os-families-test
|
||||
(is (some #{"centos"} (map str (os-families)))))
|
||||
|
||||
(def *compute* (compute-service "stub" "" "" :extensions [(ssh-test/ssh-test-client ssh-test/no-op-ssh-client)]))
|
||||
|
||||
(defn clean-stub-fixture
|
||||
"This should allow basic tests to easily be run with another service."
|
||||
[compute-service]
|
||||
(fn [f]
|
||||
(doseq [node (nodes compute-service)]
|
||||
(destroy-node (.getId node)))
|
||||
(destroy-node compute-service (.getId node)))
|
||||
(f)))
|
||||
|
||||
(def *compute* (compute-service "stub" "" ""))
|
||||
|
||||
(use-fixtures :each (clean-stub-fixture *compute*))
|
||||
|
||||
(deftest compute-service?-test
|
||||
|
@ -54,34 +63,64 @@ list, Alan Dipert and MeikelBrandmeyer."
|
|||
(is (compute-service? *compute*))
|
||||
(is (compute-service? (compute-service (compute-context *compute*)))))
|
||||
|
||||
(defn in-group [group] #(= (.getGroup %) group))
|
||||
(defn in-group? [group] #(= (.getGroup %) group))
|
||||
|
||||
(deftest nodes-test
|
||||
(is (empty? (nodes *compute*)))
|
||||
(is (create-node *compute* "fred" (build-template *compute* {} )))
|
||||
(is (= 1 (count (nodes *compute*))))
|
||||
(is (= 1 (count (nodes-in-group *compute* "fred"))))
|
||||
;; pass in a function that selects node metadata based on NodeMetadata field
|
||||
(is (= 1 (count (nodes-with-details-matching *compute* (in-group "fred")))))
|
||||
(is (= 1 (count (nodes-with-details-matching *compute* (in-group? "fred")))))
|
||||
;; or make your query inline
|
||||
(is (= 1 (count (nodes-with-details-matching *compute* #(= (.getGroup %) "fred")))))
|
||||
;; or get real fancy, and use the underlying Predicate object jclouds uses
|
||||
(is (= 1 (count (nodes-with-details-matching *compute*
|
||||
(reify com.google.common.base.Predicate
|
||||
(apply [this input] (= (.getGroup input) "fred")))))))
|
||||
(is (= 0 (count (nodes-with-details-matching *compute* (in-group "othergroup")))))
|
||||
(suspend-nodes-matching *compute* (in-group "fred"))
|
||||
(is (suspended? (first (nodes-with-details-matching *compute* (in-group "fred")))))
|
||||
(resume-nodes-matching *compute* (in-group "fred"))
|
||||
(is (= 0 (count (nodes-with-details-matching *compute* (in-group? "othergroup")))))
|
||||
(suspend-nodes-matching *compute* (in-group? "fred"))
|
||||
(is (suspended? (first (nodes-with-details-matching *compute* (in-group? "fred")))))
|
||||
(resume-nodes-matching *compute* (in-group? "fred"))
|
||||
(is (running? (first (nodes-in-group *compute* "fred"))))
|
||||
(reboot-nodes-matching *compute* (in-group "fred"))
|
||||
(reboot-nodes-matching *compute* (in-group? "fred"))
|
||||
(is (running? (first (nodes-in-group *compute* "fred"))))
|
||||
(is (create-nodes *compute* "fred" 2 (build-template *compute* {} )))
|
||||
(is (= 3 (count (nodes-in-group *compute* "fred"))))
|
||||
(is (= "fred" (group (first (nodes *compute*)))))
|
||||
(destroy-nodes-matching *compute* (in-group "fred"))
|
||||
(destroy-nodes-matching *compute* (in-group? "fred"))
|
||||
(is (terminated? (first (nodes-in-group *compute* "fred")))))
|
||||
|
||||
(defn localhost? [node]
|
||||
"Returns true if the localhost address is in the node's private ips"
|
||||
(seq? (some #(= (InetAddress/getLocalHost) %) (private-ips node))))
|
||||
|
||||
(deftest compound-predicate-test
|
||||
(is (create-node *compute* "my-group" (build-template *compute* {})))
|
||||
(is (= 0 (count (nodes-with-details-matching *compute* #(and (suspended? %) (not (localhost? %)))))))
|
||||
(is (= 0 (count (nodes-with-details-matching *compute* #(and (suspended? %) (localhost? %))))))
|
||||
(is (= 0 (count (nodes-with-details-matching *compute* #(and (running? %) (localhost? %))))))
|
||||
(is (= 1 (count (nodes-with-details-matching *compute* #(and (running? %) (not (localhost? %))))))))
|
||||
|
||||
(deftest run-script-on-nodes-matching-with-options-test
|
||||
(let [echo (Statements/exec "echo hello")
|
||||
script-options (.. (RunScriptOptions$Builder/overrideCredentialsWith (Credentials. "user" "password"))
|
||||
(runAsRoot false)
|
||||
(wrapInInitScript false))
|
||||
pred #(= (.getGroup %) "scriptednode")]
|
||||
(is (create-node *compute* "scriptednode" (build-template *compute* {})))
|
||||
(is (run-script-on-nodes-matching *compute* pred echo script-options))
|
||||
(is (thrown? NoSuchElementException
|
||||
(run-script-on-nodes-matching *compute* #(= (.getGroup %) "nonexistingnode") echo script-options)))))
|
||||
|
||||
(deftest run-script-on-node-with-options-test
|
||||
(let [echo (Statements/exec "echo hello")
|
||||
script-options (.. (RunScriptOptions$Builder/overrideCredentialsWith (Credentials. "user" "password"))
|
||||
(runAsRoot false)
|
||||
(wrapInInitScript false))
|
||||
test_node (create-node *compute* "scriptednode" (build-template *compute* {}))]
|
||||
(is (run-script-on-node *compute* (id test_node) echo script-options))
|
||||
(is (thrown? NoSuchElementException
|
||||
(run-script-on-node *compute* "nonexistingnode" echo script-options)))))
|
||||
|
||||
(deftest build-template-test
|
||||
(let [service (compute-service "stub" "user" "password")]
|
||||
(testing "nullary"
|
||||
|
|
|
@ -17,6 +17,16 @@
|
|||
; ====================================================================
|
||||
;
|
||||
|
||||
(ns org.jclouds.ssh-test
|
||||
(:require
|
||||
[clojure.contrib.logging :as logging])
|
||||
(:import
|
||||
org.jclouds.ssh.SshClient
|
||||
org.jclouds.domain.Credentials
|
||||
org.jclouds.io.Payload
|
||||
org.jclouds.net.IPSocket
|
||||
org.jclouds.compute.domain.ExecResponse))
|
||||
|
||||
(defn instantiate [impl-class & args]
|
||||
(let [constructor (first
|
||||
(filter
|
||||
|
@ -73,7 +83,12 @@
|
|||
(^org.jclouds.ssh.SshClient
|
||||
create
|
||||
[_ ^IPSocket socket ^String username ^bytes password-or-key]
|
||||
(factory-fn socket username password-or-key)))
|
||||
(factory-fn socket username password-or-key))
|
||||
(^org.jclouds.ssh.SshClient
|
||||
create
|
||||
[_ ^IPSocket socket ^Credentials credentials]
|
||||
(factory-fn socket (.identity credentials) (.credential credentials)))
|
||||
)
|
||||
|
||||
(deftype Module
|
||||
[factory binder]
|
||||
|
|
|
@ -30,6 +30,7 @@ import static com.google.common.collect.Maps.uniqueIndex;
|
|||
import static com.google.common.collect.Sets.filter;
|
||||
import static com.google.common.collect.Sets.newTreeSet;
|
||||
import static org.jclouds.compute.ComputeTestUtils.buildScript;
|
||||
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
|
||||
import static org.jclouds.compute.options.TemplateOptions.Builder.blockOnComplete;
|
||||
import static org.jclouds.compute.options.TemplateOptions.Builder.overrideCredentialsWith;
|
||||
import static org.jclouds.compute.predicates.NodePredicates.TERMINATED;
|
||||
|
@ -44,12 +45,12 @@ import java.io.FileNotFoundException;
|
|||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
@ -160,8 +161,8 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
if (context != null)
|
||||
context.close();
|
||||
Properties props = setupProperties();
|
||||
context = new ComputeServiceContextFactory(setupRestProperties()).createContext(provider,
|
||||
ImmutableSet.of(new Log4JLoggingModule(), getSshModule()), props);
|
||||
context = new ComputeServiceContextFactory(setupRestProperties()).createContext(provider, ImmutableSet.of(
|
||||
new Log4JLoggingModule(), getSshModule()), props);
|
||||
client = context.getComputeService();
|
||||
}
|
||||
|
||||
|
@ -182,7 +183,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
ComputeServiceContext context = null;
|
||||
try {
|
||||
context = new ComputeServiceContextFactory(setupRestProperties()).createContext(provider, "MOMMA", "MIA",
|
||||
ImmutableSet.<Module> of(new Log4JLoggingModule()));
|
||||
ImmutableSet.<Module> of(new Log4JLoggingModule()));
|
||||
context.getComputeService().listNodes();
|
||||
} catch (AuthorizationException e) {
|
||||
throw e;
|
||||
|
@ -207,7 +208,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
@Test(enabled = true, expectedExceptions = NoSuchElementException.class)
|
||||
public void testCorrectExceptionRunningNodesNotFound() throws Exception {
|
||||
client.runScriptOnNodesMatching(runningInGroup("zebras-are-awesome"), buildScript(new OperatingSystem.Builder()
|
||||
.family(OsFamily.UBUNTU).description("ffoo").build()));
|
||||
.family(OsFamily.UBUNTU).description("ffoo").build()));
|
||||
}
|
||||
|
||||
// since surefire and eclipse don't otherwise guarantee the order, we are
|
||||
|
@ -231,17 +232,22 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
OperatingSystem os = get(nodes, 0).getOperatingSystem();
|
||||
try {
|
||||
Map<? extends NodeMetadata, ExecResponse> responses = runScriptWithCreds(group, os, new Credentials(
|
||||
good.identity, "romeo"));
|
||||
good.identity, "romeo"));
|
||||
assert false : "shouldn't pass with a bad password\n" + responses;
|
||||
} catch (RunScriptOnNodesException e) {
|
||||
assert getRootCause(e).getMessage().contains("Auth fail") : e;
|
||||
}
|
||||
|
||||
for (Entry<? extends NodeMetadata, ExecResponse> response : client.runScriptOnNodesMatching(
|
||||
runningInGroup(group), Statements.exec("echo hello"),
|
||||
overrideCredentialsWith(good).wrapInInitScript(false).runAsRoot(false)).entrySet())
|
||||
runningInGroup(group), Statements.exec("echo hello"),
|
||||
overrideCredentialsWith(good).wrapInInitScript(false).runAsRoot(false)).entrySet())
|
||||
assert response.getValue().getOutput().trim().equals("hello") : response.getKey() + ": "
|
||||
+ response.getValue();
|
||||
+ response.getValue();
|
||||
|
||||
// test single-node execution
|
||||
ExecResponse response = client.runScriptOnNode(get(nodes, 0).getId(), "echo hello", wrapInInitScript(false)
|
||||
.runAsRoot(false));
|
||||
assert response.getOutput().trim().equals("hello") : get(nodes, 0).getId() + ": " + response;
|
||||
|
||||
runScriptWithCreds(group, os, good);
|
||||
|
||||
|
@ -298,7 +304,8 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
// template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(keyPair.get("public"))
|
||||
// .runScript(buildScript(template.getImage().getOperatingSystem()));
|
||||
template.getOptions().runScript(
|
||||
Statements.newStatementList(AdminAccess.standard(), buildScript(template.getImage().getOperatingSystem())));
|
||||
Statements.newStatementList(AdminAccess.standard(),
|
||||
buildScript(template.getImage().getOperatingSystem())));
|
||||
}
|
||||
|
||||
protected void checkImageIdMatchesTemplate(NodeMetadata node) {
|
||||
|
@ -309,8 +316,8 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
protected void checkOsMatchesTemplate(NodeMetadata node) {
|
||||
if (node.getOperatingSystem() != null)
|
||||
assert node.getOperatingSystem().getFamily().equals(template.getImage().getOperatingSystem().getFamily()) : String
|
||||
.format("expecting family %s but got %s", template.getImage().getOperatingSystem().getFamily(),
|
||||
node.getOperatingSystem());
|
||||
.format("expecting family %s but got %s", template.getImage().getOperatingSystem().getFamily(), node
|
||||
.getOperatingSystem());
|
||||
}
|
||||
|
||||
void assertLocationSameOrChild(Location test, Location expected) {
|
||||
|
@ -342,10 +349,10 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
|
||||
protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(final String group, OperatingSystem os,
|
||||
Credentials creds) throws RunScriptOnNodesException {
|
||||
Credentials creds) throws RunScriptOnNodesException {
|
||||
try {
|
||||
return client.runScriptOnNodesMatching(runningInGroup(group), buildScript(os), overrideCredentialsWith(creds)
|
||||
.nameTask("runScriptWithCreds"));
|
||||
.nameTask("runScriptWithCreds"));
|
||||
} catch (SshException e) {
|
||||
throw e;
|
||||
}
|
||||
|
@ -375,16 +382,16 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
|
||||
@Test(enabled = true, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
|
||||
public void testGet() throws Exception {
|
||||
Map<String, ? extends NodeMetadata> metadataMap = newLinkedHashMap(uniqueIndex(
|
||||
filter(client.listNodesDetailsMatching(all()), and(inGroup(group), not(TERMINATED))),
|
||||
new Function<NodeMetadata, String>() {
|
||||
Map<String, ? extends NodeMetadata> metadataMap = newLinkedHashMap(uniqueIndex(filter(client
|
||||
.listNodesDetailsMatching(all()), and(inGroup(group), not(TERMINATED))),
|
||||
new Function<NodeMetadata, String>() {
|
||||
|
||||
@Override
|
||||
public String apply(NodeMetadata from) {
|
||||
return from.getId();
|
||||
}
|
||||
@Override
|
||||
public String apply(NodeMetadata from) {
|
||||
return from.getId();
|
||||
}
|
||||
|
||||
}));
|
||||
}));
|
||||
for (NodeMetadata node : nodes) {
|
||||
metadataMap.remove(node.getId());
|
||||
NodeMetadata metadata = client.getNodeMetadata(node.getId());
|
||||
|
@ -403,7 +410,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
|
||||
protected void assertNodeZero(Collection<? extends NodeMetadata> metadataSet) {
|
||||
assert metadataSet.size() == 0 : String.format("nodes left in set: [%s] which didn't match set: [%s]",
|
||||
metadataSet, nodes);
|
||||
metadataSet, nodes);
|
||||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testGet")
|
||||
|
@ -491,12 +498,12 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
|
||||
template = client.templateBuilder().options(blockOnComplete(false).blockOnPort(8080, 600).inboundPorts(22, 8080))
|
||||
.build();
|
||||
.build();
|
||||
|
||||
// note this is a dependency on the template resolution
|
||||
template.getOptions().runScript(
|
||||
RunScriptData.createScriptInstallAndStartJBoss(keyPair.get("public"), template.getImage()
|
||||
.getOperatingSystem()));
|
||||
RunScriptData.createScriptInstallAndStartJBoss(keyPair.get("public"), template.getImage()
|
||||
.getOperatingSystem()));
|
||||
try {
|
||||
NodeMetadata node = getOnlyElement(client.createNodesInGroup(group, 1, template));
|
||||
|
||||
|
@ -530,26 +537,26 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
assert location != location.getParent() : location;
|
||||
assert location.getScope() != null : location;
|
||||
switch (location.getScope()) {
|
||||
case PROVIDER:
|
||||
assertProvider(location);
|
||||
break;
|
||||
case REGION:
|
||||
assertProvider(location.getParent());
|
||||
break;
|
||||
case ZONE:
|
||||
Location provider = location.getParent().getParent();
|
||||
// zone can be a direct descendant of provider
|
||||
if (provider == null)
|
||||
provider = location.getParent();
|
||||
assertProvider(provider);
|
||||
break;
|
||||
case HOST:
|
||||
Location provider2 = location.getParent().getParent().getParent();
|
||||
// zone can be a direct descendant of provider
|
||||
if (provider2 == null)
|
||||
provider2 = location.getParent().getParent();
|
||||
assertProvider(provider2);
|
||||
break;
|
||||
case PROVIDER:
|
||||
assertProvider(location);
|
||||
break;
|
||||
case REGION:
|
||||
assertProvider(location.getParent());
|
||||
break;
|
||||
case ZONE:
|
||||
Location provider = location.getParent().getParent();
|
||||
// zone can be a direct descendant of provider
|
||||
if (provider == null)
|
||||
provider = location.getParent();
|
||||
assertProvider(provider);
|
||||
break;
|
||||
case HOST:
|
||||
Location provider2 = location.getParent().getParent().getParent();
|
||||
// zone can be a direct descendant of provider
|
||||
if (provider2 == null)
|
||||
provider2 = location.getParent().getParent();
|
||||
assertProvider(provider2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -582,10 +589,10 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
|
||||
public void testListSizes() throws Exception {
|
||||
for (Hardware hardware : client.listHardwareProfiles()) {
|
||||
assert hardware.getProviderId() != null;
|
||||
assert getCores(hardware) > 0;
|
||||
assert hardware.getVolumes().size() >= 0;
|
||||
assert hardware.getRam() > 0;
|
||||
assert hardware.getProviderId() != null : hardware;
|
||||
assert getCores(hardware) > 0 : hardware;
|
||||
assert hardware.getVolumes().size() >= 0 : hardware;
|
||||
assert hardware.getRam() > 0 : hardware;
|
||||
assertEquals(hardware.getType(), ComputeType.HARDWARE);
|
||||
}
|
||||
}
|
||||
|
@ -637,7 +644,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
assertEquals(hello.getOutput().trim(), "hello");
|
||||
ExecResponse exec = ssh.exec("java -version");
|
||||
assert exec.getError().indexOf("1.6") != -1 || exec.getOutput().indexOf("1.6") != -1 : exec + "\n"
|
||||
+ ssh.exec("cat /tmp/bootstrap/stdout.log /tmp/bootstrap/stderr.log");
|
||||
+ ssh.exec("cat /tmp/bootstrap/stdout.log /tmp/bootstrap/stderr.log");
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
|
|
|
@ -167,7 +167,7 @@ public abstract class BaseTemplateBuilderLiveTest {
|
|||
Template defaultTemplate = context.getComputeService().templateBuilder().build();
|
||||
|
||||
Template template = context.getComputeService().templateBuilder().imageId(defaultTemplate.getImage().getId())
|
||||
.build();
|
||||
.locationId(defaultTemplate.getLocation().getId()).build();
|
||||
assertEquals(template.getImage(), defaultTemplate.getImage());
|
||||
}
|
||||
|
||||
|
|
|
@ -144,15 +144,20 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
|||
runScriptAndService(client1, 1);
|
||||
|
||||
expect(factory.create(new IPSocket("144.175.1.2", 22), new Credentials("root", "password2"))).andReturn(
|
||||
client2).times(3);
|
||||
client2).times(4);
|
||||
expect(factory.create(new IPSocket("144.175.1.2", 22), new Credentials("root", "romeo"))).andThrow(
|
||||
new SshException("Auth fail"));
|
||||
|
||||
// run script without backgrounding
|
||||
// run script without backgrounding (via predicate)
|
||||
client2.connect();
|
||||
expect(client2.exec("echo hello\n")).andReturn(new ExecResponse("hello\n", "", 0));
|
||||
client2.disconnect();
|
||||
|
||||
|
||||
// run script without backgrounding (via id)
|
||||
client2.connect();
|
||||
expect(client2.exec("echo hello\n")).andReturn(new ExecResponse("hello\n", "", 0));
|
||||
client2.disconnect();
|
||||
|
||||
client2.connect();
|
||||
try {
|
||||
runScript(client2, "runScriptWithCreds",
|
||||
|
|
43
core/pom.xml
43
core/pom.xml
|
@ -2,7 +2,7 @@
|
|||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2010 Cloud Conscious, LLC.
|
||||
Copyright (C) 2011 Cloud Conscious, LLC.
|
||||
<info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
|
@ -30,7 +30,7 @@
|
|||
</parent>
|
||||
<artifactId>jclouds-core</artifactId>
|
||||
<name>jclouds Components Core</name>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
<description>Core components to access jclouds services</description>
|
||||
|
||||
<scm>
|
||||
|
@ -105,7 +105,7 @@
|
|||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>1.6</version>
|
||||
<version>1.7.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
|
@ -119,6 +119,43 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.3.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<!--
|
||||
These files are excluded to avoid corrupting the classpath with ProviderMetadata implementation
|
||||
classes that should only be availble when running the core tests.
|
||||
-->
|
||||
<excludes>
|
||||
<exclude>META-INF/services/</exclude>
|
||||
<exclude>org/jclouds/providers/ProvidersTest.class</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||
<Export-Package>com.google.gson;-split-package:=merge-first,
|
||||
org.jclouds.*;version=${project.version}</Export-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>distribution</id>
|
||||
|
|
|
@ -23,11 +23,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* The gson project use package to control access to their objects. However,
|
||||
* this prevents us from doing valid work, like controling the json emitted on a
|
||||
* per-object basis. This is here to afford us to do this.
|
||||
* The gson project use package to control access to their objects. However, this prevents us from
|
||||
* doing valid work, like controling the json emitted on a per-object basis. This is here to afford
|
||||
* us to do this.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href="http://code.google.com/p/google-gson/issues/detail?id=326"/>
|
||||
*/
|
||||
public final class JsonLiteral extends JsonElement {
|
||||
private final CharSequence literal;
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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 com.google.gson;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.json.internal.ParseObjectFromElement;
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public class MapTypeAdapter implements JsonSerializer<Map>, JsonDeserializer<Map>, InstanceCreator<Map> {
|
||||
|
||||
public JsonElement serialize(Map src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject map = new JsonObject();
|
||||
Type childGenericType = null;
|
||||
if (typeOfSrc instanceof ParameterizedType) {
|
||||
childGenericType = new TypeInfoMap(typeOfSrc).getValueType();
|
||||
}
|
||||
|
||||
for (Map.Entry entry : (Set<Map.Entry>) src.entrySet()) {
|
||||
Object value = entry.getValue();
|
||||
|
||||
JsonElement valueElement;
|
||||
if (value == null) {
|
||||
valueElement = JsonNull.createJsonNull();
|
||||
} else {
|
||||
Type childType = (childGenericType == null) ? value.getClass() : childGenericType;
|
||||
valueElement = context.serialize(value, childType);
|
||||
}
|
||||
map.add(String.valueOf(entry.getKey()), valueElement);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
// Use ObjectConstructor to create instance instead of hard-coding a specific type.
|
||||
// This handles cases where users are using their own subclass of Map.
|
||||
Map<Object, Object> map = constructMapType(typeOfT, context);
|
||||
TypeInfoMap mapTypeInfo = new TypeInfoMap(typeOfT);
|
||||
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
|
||||
Object key = context.deserialize(new JsonPrimitive(entry.getKey()), mapTypeInfo.getKeyType());
|
||||
// START JCLOUDS PATCH
|
||||
Object value = null;
|
||||
if (mapTypeInfo.getValueType() == Object.class) {
|
||||
value = ParseObjectFromElement.SINGLETON.apply(entry.getValue());
|
||||
}
|
||||
if (value == null) {
|
||||
value = context.deserialize(entry.getValue(), mapTypeInfo.getValueType());
|
||||
}
|
||||
// END JCLOUDS PATCH
|
||||
map.put(key, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private Map constructMapType(Type mapType, JsonDeserializationContext context) {
|
||||
JsonDeserializationContextDefault contextImpl = (JsonDeserializationContextDefault) context;
|
||||
ObjectConstructor objectConstructor = contextImpl.getObjectConstructor();
|
||||
return (Map) objectConstructor.construct(mapType);
|
||||
}
|
||||
|
||||
public Map createInstance(Type type) {
|
||||
return new LinkedHashMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MapTypeAdapter.class.getSimpleName();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (C) 2011 Google Inc.
|
||||
*
|
||||
* 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 com.google.gson;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.json.internal.ParseObjectFromElement;
|
||||
|
||||
import com.google.gson.internal.$Gson$Types;
|
||||
|
||||
/**
|
||||
* Default serialization and deserialization of a map type. This implementation really only works
|
||||
* well with simple primitive types as the map key. If the key is not a simple primitive then the
|
||||
* object is {@code toString}ed and that value is used as its key.
|
||||
* <p/>
|
||||
* Patched depending on <a href="http://code.google.com/p/google-gson/issues/detail?id=325">this</a>
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public final class ObjectMapTypeAdapter extends BaseMapTypeAdapter {
|
||||
|
||||
public JsonElement serialize(Map src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject map = new JsonObject();
|
||||
Type childGenericType = null;
|
||||
if (typeOfSrc instanceof ParameterizedType) {
|
||||
Class<?> rawTypeOfSrc = $Gson$Types.getRawType(typeOfSrc);
|
||||
childGenericType = $Gson$Types.getMapKeyAndValueTypes(typeOfSrc, rawTypeOfSrc)[1];
|
||||
}
|
||||
|
||||
for (Map.Entry entry : (Set<Map.Entry>) src.entrySet()) {
|
||||
Object value = entry.getValue();
|
||||
|
||||
JsonElement valueElement;
|
||||
if (value == null) {
|
||||
valueElement = JsonNull.createJsonNull();
|
||||
} else {
|
||||
Type childType = (childGenericType == null)
|
||||
? value.getClass() : childGenericType;
|
||||
valueElement = serialize(context, value, childType);
|
||||
}
|
||||
map.add(String.valueOf(entry.getKey()), valueElement);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
// Use ObjectConstructor to create instance instead of hard-coding a specific type.
|
||||
// This handles cases where users are using their own subclass of Map.
|
||||
Map<Object, Object> map = constructMapType(typeOfT, context);
|
||||
Type[] keyAndValueTypes = $Gson$Types.getMapKeyAndValueTypes(typeOfT, $Gson$Types.getRawType(typeOfT));
|
||||
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
|
||||
Object key = context.deserialize(new JsonPrimitive(entry.getKey()), keyAndValueTypes[0]);
|
||||
// START JCLOUDS PATCH
|
||||
// http://code.google.com/p/google-gson/issues/detail?id=325
|
||||
Object value = null;
|
||||
if (keyAndValueTypes[1] == Object.class) {
|
||||
value = ParseObjectFromElement.SINGLETON.apply(entry.getValue());
|
||||
}
|
||||
if (value == null) {
|
||||
value = context.deserialize(entry.getValue(), keyAndValueTypes[1]);
|
||||
}
|
||||
// END JCLOUDS PATCH
|
||||
map.put(key, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MapTypeAdapter.class.getSimpleName();
|
||||
}
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
/**
|
||||
/*
|
||||
* Copyright (C) 2010 Google Inc.
|
||||
*
|
||||
* 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
|
||||
|
@ -14,8 +12,8 @@
|
|||
* 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 com.google.gson;
|
||||
|
||||
import com.google.gson.stream.JsonReader;
|
||||
|
@ -104,7 +102,8 @@ final class Streams {
|
|||
if (serializeNulls) {
|
||||
writer.nullValue();
|
||||
}
|
||||
//BEGIN JCLOUDS PATCH
|
||||
//BEGIN JCLOUDS PATCH
|
||||
// * @see <a href="http://code.google.com/p/google-gson/issues/detail?id=326"/>
|
||||
} else if (element instanceof JsonLiteral ) {
|
||||
writer.value(JsonLiteral.class.cast(element));
|
||||
//END JCLOUDS PATCH
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
/**
|
||||
/*
|
||||
* Copyright (C) 2010 Google Inc.
|
||||
*
|
||||
* 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
|
||||
* 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 com.google.gson.stream;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
@ -344,7 +342,7 @@ public final class JsonWriter implements Closeable {
|
|||
return this;
|
||||
}
|
||||
//BEGIN JCLOUDS PATCH
|
||||
|
||||
// * @see <a href="http://code.google.com/p/google-gson/issues/detail?id=326"/>
|
||||
/**
|
||||
* Writes {@code value} literally
|
||||
*
|
||||
|
@ -356,7 +354,6 @@ public final class JsonWriter implements Closeable {
|
|||
return this;
|
||||
}
|
||||
//END JCLOUDS PATCH
|
||||
|
||||
/**
|
||||
* Encodes {@code value}.
|
||||
*
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.jclouds.util.Patterns;
|
|||
* As String is final, using a different marker to imply this is a json object
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href="http://code.google.com/p/google-gson/issues/detail?id=326"/>
|
||||
*/
|
||||
public class JsonBall implements java.io.Serializable, Comparable<String>, CharSequence {
|
||||
|
||||
|
|
|
@ -16,13 +16,14 @@
|
|||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.ibmdev.functions;
|
||||
package org.jclouds.http.functions;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.ibmdev.domain.Instance;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
@ -31,16 +32,20 @@ import com.google.common.collect.Iterables;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class GetFirstInstanceInList implements Function<HttpResponse, Instance> {
|
||||
private ParseInstancesFromJson listParser;
|
||||
public class UnwrapOnlyJsonValueInSet<T> implements Function<HttpResponse, T> {
|
||||
|
||||
private final UnwrapOnlyJsonValue<Set<T>> json;
|
||||
|
||||
@Inject
|
||||
public GetFirstInstanceInList(ParseInstancesFromJson mapper) {
|
||||
this.listParser = mapper;
|
||||
UnwrapOnlyJsonValueInSet(UnwrapOnlyJsonValue<Set<T>> json) {
|
||||
this.json = json;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance apply(HttpResponse from) {
|
||||
return Iterables.getOnlyElement(listParser.apply(from));
|
||||
public T apply(HttpResponse arg0) {
|
||||
Set<T> set = json.apply(arg0);
|
||||
if (set == null || set.size() == 0)
|
||||
return null;
|
||||
return Iterables.getOnlyElement(set);
|
||||
}
|
||||
}
|
|
@ -16,34 +16,32 @@
|
|||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.ibmdev.functions;
|
||||
package org.jclouds.io;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
import org.jclouds.ibmdev.domain.Image;
|
||||
import org.jclouds.collect.InputSupplierMap;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.io.InputSupplier;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ParseImageFromJson implements Function<HttpResponse, Image> {
|
||||
|
||||
private final ParseJson<Image> json;
|
||||
|
||||
@Beta
|
||||
public class CopyInputStreamInputSupplierMap extends InputSupplierMap<String, InputStream> {
|
||||
@Inject
|
||||
ParseImageFromJson(ParseJson<Image> json) {
|
||||
this.json = json;
|
||||
public CopyInputStreamInputSupplierMap(Map<String, InputSupplier<InputStream>> toMap,
|
||||
CopyInputStreamIntoSupplier putFunction) {
|
||||
super(toMap, putFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image apply(HttpResponse arg0) {
|
||||
Image input = json.apply(arg0);
|
||||
ParseUtils.CLEAN_IMAGE.apply(input);
|
||||
return input;
|
||||
public CopyInputStreamInputSupplierMap(Map<String, InputSupplier<InputStream>> toMap) {
|
||||
super(toMap, new CopyInputStreamIntoSupplier());
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,6 +24,8 @@ import java.util.Enumeration;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
@ -36,12 +38,11 @@ import org.jclouds.json.internal.EnumTypeAdapterThatReturnsFromValue;
|
|||
import org.jclouds.json.internal.GsonWrapper;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.common.primitives.Bytes;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JcloudsGsonPackageAccessor;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
|
@ -50,7 +51,7 @@ import com.google.gson.JsonParseException;
|
|||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.google.gson.MapTypeAdapter;
|
||||
import com.google.gson.ObjectMapTypeAdapter;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
@ -68,12 +69,12 @@ public class GsonModule extends AbstractModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
Gson provideGson(JsonBallAdapter jsonAdapter, DateAdapter adapter, ByteListAdapter byteListAdapter,
|
||||
ByteArrayAdapter byteArrayAdapter, SerializePropertiesDefaults propertiesAdapter, JsonAdapterBindings bindings)
|
||||
throws ClassNotFoundException, Exception {
|
||||
ByteArrayAdapter byteArrayAdapter, SerializePropertiesDefaults propertiesAdapter,
|
||||
JsonAdapterBindings bindings) throws ClassNotFoundException, Exception {
|
||||
GsonBuilder builder = new GsonBuilder();
|
||||
JcloudsGsonPackageAccessor.registerTypeHierarchyAdapter(builder, Enum.class,
|
||||
new EnumTypeAdapterThatReturnsFromValue());
|
||||
JcloudsGsonPackageAccessor.registerTypeHierarchyAdapter(builder, Map.class, new MapTypeAdapter());
|
||||
Logger.getLogger("com.google.gson.ParameterizedTypeHandlerMap").setLevel(Level.OFF);
|
||||
builder.registerTypeHierarchyAdapter(Enum.class, new EnumTypeAdapterThatReturnsFromValue());
|
||||
builder.registerTypeHierarchyAdapter(Map.class, new ObjectMapTypeAdapter());
|
||||
builder.registerTypeAdapter(JsonBall.class, jsonAdapter);
|
||||
builder.registerTypeAdapter(Date.class, adapter);
|
||||
builder.registerTypeAdapter(Properties.class, propertiesAdapter);
|
||||
|
@ -86,6 +87,7 @@ public class GsonModule extends AbstractModule {
|
|||
return builder.create();
|
||||
}
|
||||
|
||||
// http://code.google.com/p/google-gson/issues/detail?id=326
|
||||
@ImplementedBy(JsonBallAdapterImpl.class)
|
||||
public static interface JsonBallAdapter extends JsonSerializer<JsonBall>, JsonDeserializer<JsonBall> {
|
||||
|
||||
|
@ -99,7 +101,7 @@ public class GsonModule extends AbstractModule {
|
|||
}
|
||||
|
||||
public JsonBall deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
throws JsonParseException {
|
||||
return new JsonBall(json.toString());
|
||||
}
|
||||
|
||||
|
@ -125,7 +127,7 @@ public class GsonModule extends AbstractModule {
|
|||
|
||||
@Override
|
||||
public List<Byte> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
throws JsonParseException {
|
||||
return Bytes.asList(CryptoStreams.hex(json.getAsString()));
|
||||
}
|
||||
|
||||
|
@ -141,7 +143,7 @@ public class GsonModule extends AbstractModule {
|
|||
|
||||
@Override
|
||||
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
throws JsonParseException {
|
||||
return CryptoStreams.hex(json.getAsString());
|
||||
}
|
||||
|
||||
|
@ -165,7 +167,7 @@ public class GsonModule extends AbstractModule {
|
|||
}
|
||||
|
||||
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
throws JsonParseException {
|
||||
String toParse = json.getAsJsonPrimitive().getAsString();
|
||||
try {
|
||||
return dateService.iso8601DateParse(toParse);
|
||||
|
@ -212,7 +214,7 @@ public class GsonModule extends AbstractModule {
|
|||
}
|
||||
|
||||
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
throws JsonParseException {
|
||||
String toParse = json.getAsJsonPrimitive().getAsString();
|
||||
Date toReturn = dateService.cDateParse(toParse);
|
||||
return toReturn;
|
||||
|
@ -228,7 +230,7 @@ public class GsonModule extends AbstractModule {
|
|||
}
|
||||
|
||||
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
throws JsonParseException {
|
||||
long toParse = json.getAsJsonPrimitive().getAsLong();
|
||||
if (toParse == -1)
|
||||
return null;
|
||||
|
|
|
@ -27,7 +27,7 @@ import com.google.gson.JsonObject;
|
|||
|
||||
/**
|
||||
* Exposes the JsonObject as a map so that we can use gauva apis on it.
|
||||
*
|
||||
* http://code.google.com/p/google-gson/issues/detail?id=325
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum JsonObjectAsMap implements Function<JsonObject, Map<String, JsonElement>> {
|
||||
|
|
|
@ -24,12 +24,11 @@ import com.google.common.collect.Lists;
|
|||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.MapTypeAdapter;
|
||||
|
||||
/**
|
||||
* This is a class that helps the default {@link MapTypeAdapter} make a sane object graph when the
|
||||
* value is set to {@code Object}
|
||||
*
|
||||
* http://code.google.com/p/google-gson/issues/detail?id=325
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum ParseObjectFromElement implements Function<JsonElement, Object> {
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
/**
|
||||
*
|
||||
* 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.providers;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* The BaseProviderMetadata class is an abstraction of {@link ProviderMetadata} to be extended by
|
||||
* those implementing ProviderMetadata.
|
||||
*
|
||||
* (Note: This class must be abstract to allow {@link java.util.ServiceLoader} to work properly.
|
||||
*
|
||||
* @author Jeremy Whitlock <jwhitlock@apache.org>
|
||||
*/
|
||||
public abstract class BaseProviderMetadata implements ProviderMetadata {
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
URI console = getConsole();
|
||||
URI homepage = getHomepage();
|
||||
URI docs = getApiDocumentation();
|
||||
String id = getId();
|
||||
String name = getName();
|
||||
String identityName = getIdentityName();
|
||||
String credentialName = getCredentialName();
|
||||
String type = getType();
|
||||
Set<String> linkedServices = getLinkedServices();
|
||||
|
||||
result = prime * result + ((console == null) ? 0 : console.hashCode());
|
||||
result = prime * result + ((homepage == null) ? 0 : homepage.hashCode());
|
||||
result = prime * result + ((docs == null) ? 0 : docs.hashCode());
|
||||
result = prime * result + ((id == null) ? 0 : id.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((identityName == null) ? 0 : identityName.hashCode());
|
||||
result = prime * result + ((credentialName == null) ? 0 : credentialName.hashCode());
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
result = prime * result + ((linkedServices == null) ? 0 : linkedServices.hashCode());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
URI tConsole = getConsole();
|
||||
URI tHomepage = getHomepage();
|
||||
URI tDocs = getApiDocumentation();
|
||||
String tId = getId();
|
||||
String tName = getName();
|
||||
String tIdentityName = getIdentityName();
|
||||
String tCredentialName = getCredentialName();
|
||||
String tType = getType();
|
||||
Set<String> tLinkedServices = getLinkedServices();
|
||||
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
|
||||
ProviderMetadata other = (ProviderMetadata) obj;
|
||||
URI oConsole = other.getConsole();
|
||||
URI oHomepage = other.getHomepage();
|
||||
URI oDocs = other.getApiDocumentation();
|
||||
String oId = other.getId();
|
||||
String oName = other.getName();
|
||||
String oIdentityName = other.getIdentityName();
|
||||
String oCredentialName = other.getCredentialName();
|
||||
String oType = other.getType();
|
||||
Set<String> oLinkedServices = other.getLinkedServices();
|
||||
|
||||
if (tConsole == null) {
|
||||
if (oConsole != null)
|
||||
return false;
|
||||
} else if (!tConsole.equals(oConsole))
|
||||
return false;
|
||||
if (tDocs == null) {
|
||||
if (oDocs != null)
|
||||
return false;
|
||||
} else if (!tDocs.equals(oDocs))
|
||||
return false;
|
||||
if (tHomepage == null) {
|
||||
if (oHomepage != null)
|
||||
return false;
|
||||
} else if (!tHomepage.equals(oHomepage))
|
||||
return false;
|
||||
if (tId == null) {
|
||||
if (oId != null)
|
||||
return false;
|
||||
} else if (!tId.equals(oId))
|
||||
return false;
|
||||
if (tName == null) {
|
||||
if (oName != null)
|
||||
return false;
|
||||
} else if (!tName.equals(oName))
|
||||
return false;
|
||||
if (tIdentityName == null) {
|
||||
if (oIdentityName != null)
|
||||
return false;
|
||||
} else if (!tIdentityName.equals(oIdentityName))
|
||||
return false;
|
||||
if (tCredentialName == null) {
|
||||
if (oCredentialName != null)
|
||||
return false;
|
||||
} else if (!tCredentialName.equals(oCredentialName))
|
||||
return false;
|
||||
if (tType == null) {
|
||||
if (oType != null)
|
||||
return false;
|
||||
} else if (!tType.equals(oType))
|
||||
return false;
|
||||
if (tLinkedServices == null) {
|
||||
if (oLinkedServices != null)
|
||||
return false;
|
||||
} else if (!tLinkedServices.equals(oLinkedServices))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[id=" + getId() + ", type=" + getType() + ", name=" + getName() + ", identityName=" + getIdentityName()
|
||||
+ ", credentialName=" + getCredentialName() + ", homePage=" + getHomepage() + ", console="
|
||||
+ getConsole() + ", apiDocs=" + getApiDocumentation() + ", linkedServices=" + getLinkedServices() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getLinkedServices() {
|
||||
return ImmutableSet.of(getId());
|
||||
}
|
||||
}
|
|
@ -19,51 +19,78 @@
|
|||
package org.jclouds.providers;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* The ProviderMetadata interface allows jclouds to provide a plugin framework
|
||||
* for gathering cloud provider metadata.
|
||||
*
|
||||
* The ProviderMetadata interface allows jclouds to provide a plugin framework for gathering cloud
|
||||
* provider metadata.
|
||||
*
|
||||
* @author Jeremy Whitlock <jwhitlock@apache.org>
|
||||
*/
|
||||
public interface ProviderMetadata {
|
||||
|
||||
public static final String BLOBSTORE_TYPE = "blobstore";
|
||||
public static final String COMPUTE_TYPE = "compute";
|
||||
public static final String LOADBALANCER_TYPE = "loadbalancer";
|
||||
public static final String TABLE_TYPE = "table";
|
||||
public static final String QUEUE_TYPE = "queue";
|
||||
|
||||
/**
|
||||
* Returns an identifier unique to the provider.
|
||||
*
|
||||
* @return the provider's unique identifier
|
||||
*/
|
||||
public String getId();
|
||||
/**
|
||||
*
|
||||
* @return the provider's unique identifier
|
||||
*/
|
||||
public String getId();
|
||||
|
||||
/**
|
||||
* Returns the provider type.
|
||||
*
|
||||
* @return the provider's type
|
||||
*/
|
||||
public String getType();
|
||||
/**
|
||||
*
|
||||
* @return the provider's type
|
||||
*/
|
||||
public String getType();
|
||||
|
||||
/**
|
||||
* Returns the name of the provider.
|
||||
*
|
||||
* @return the name (display name) of the provider
|
||||
*/
|
||||
public String getName();
|
||||
/**
|
||||
*
|
||||
* @return the name (display name) of the provider
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* Returns the URI to the provider's homepage.
|
||||
*
|
||||
* @return the url for the provider's homepage
|
||||
*/
|
||||
public URI getHomepage();
|
||||
/**
|
||||
*
|
||||
* @return the name (display name) of an identity on this provider (ex. user, email, account,
|
||||
* apikey)
|
||||
*/
|
||||
public String getIdentityName();
|
||||
|
||||
/**
|
||||
* Returns the URI to the provider's console.
|
||||
*
|
||||
* @return the url for the provider's console
|
||||
*/
|
||||
public URI getConsole();
|
||||
/**
|
||||
*
|
||||
* @return the name (display name) of a credential on this provider, or null if there is none
|
||||
* (ex. password, secret, rsaKey)
|
||||
*/
|
||||
@Nullable
|
||||
public String getCredentialName();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the url for the provider's homepage
|
||||
*/
|
||||
public URI getHomepage();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the url for the provider's console
|
||||
*/
|
||||
public URI getConsole();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the url for the API documentation related to this service
|
||||
*/
|
||||
public URI getApiDocumentation();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return all known services linked to the same account on this provider
|
||||
*/
|
||||
public Set<String> getLinkedServices();
|
||||
}
|
|
@ -26,15 +26,14 @@ import java.util.ServiceLoader;
|
|||
|
||||
/**
|
||||
* The Providers class provides static methods for accessing providers.
|
||||
*
|
||||
*
|
||||
* @author Jeremy Whitlock <jwhitlock@apache.org>
|
||||
*/
|
||||
public class Providers {
|
||||
|
||||
/**
|
||||
* Returns the providers located on the classpath via
|
||||
* {@link java.util.ServiceLoader}.
|
||||
*
|
||||
* Returns the providers located on the classpath via {@link java.util.ServiceLoader}.
|
||||
*
|
||||
* @return all available providers loaded from classpath via ServiceLoader
|
||||
*/
|
||||
private static Iterable<ProviderMetadata> fromServiceLoader() {
|
||||
|
@ -43,7 +42,7 @@ public class Providers {
|
|||
|
||||
/**
|
||||
* Returns all available providers.
|
||||
*
|
||||
*
|
||||
* @return all available providers
|
||||
*/
|
||||
public static Iterable<ProviderMetadata> all() {
|
||||
|
@ -52,24 +51,23 @@ public class Providers {
|
|||
|
||||
/**
|
||||
* Returns the first provider with the provided id
|
||||
*
|
||||
*
|
||||
* @param id
|
||||
* the id of the provider to return
|
||||
*
|
||||
*
|
||||
* @return the provider with the given id
|
||||
*
|
||||
*
|
||||
* @throws NoSuchElementException
|
||||
* whenever there are no providers with the provided id
|
||||
* whenever there are no providers with the provided id
|
||||
*/
|
||||
public static ProviderMetadata withId(String id)
|
||||
throws NoSuchElementException {
|
||||
public static ProviderMetadata withId(String id) throws NoSuchElementException {
|
||||
return find(all(), ProviderPredicates.id(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the providers that are of type
|
||||
* {@link org.jclouds.providers.ProviderMetadata#BLOBSTORE_TYPE}.
|
||||
*
|
||||
*
|
||||
* @return the blobstore providers
|
||||
*/
|
||||
public static Iterable<ProviderMetadata> allBlobStore() {
|
||||
|
@ -79,19 +77,49 @@ public class Providers {
|
|||
/**
|
||||
* Returns the providers that are of type
|
||||
* {@link org.jclouds.providers.ProviderMetadata#COMPUTE_TYPE}.
|
||||
*
|
||||
*
|
||||
* @return the compute service providers
|
||||
*/
|
||||
public static Iterable<ProviderMetadata> allCompute() {
|
||||
return filter(all(), ProviderPredicates.type(ProviderMetadata.COMPUTE_TYPE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the providers that are of type
|
||||
* {@link org.jclouds.providers.ProviderMetadata#QUEUE_TYPE}.
|
||||
*
|
||||
* @return the queue service providers
|
||||
*/
|
||||
public static Iterable<ProviderMetadata> allQueue() {
|
||||
return filter(all(), ProviderPredicates.type(ProviderMetadata.QUEUE_TYPE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the providers that are of type
|
||||
* {@link org.jclouds.providers.ProviderMetadata#TABLE_TYPE}.
|
||||
*
|
||||
* @return the table service providers
|
||||
*/
|
||||
public static Iterable<ProviderMetadata> allTable() {
|
||||
return filter(all(), ProviderPredicates.type(ProviderMetadata.TABLE_TYPE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the providers that are of type
|
||||
* {@link org.jclouds.providers.ProviderMetadata#LOADBALANCER_TYPE}.
|
||||
*
|
||||
* @return the load balancer service providers
|
||||
*/
|
||||
public static Iterable<ProviderMetadata> allLoadBalancer() {
|
||||
return filter(all(), ProviderPredicates.type(ProviderMetadata.LOADBALANCER_TYPE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the providers that are of the provided type.
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
* the type to providers to return
|
||||
*
|
||||
*
|
||||
* @return the providers of the provided type
|
||||
*/
|
||||
public static Iterable<ProviderMetadata> ofType(String type) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -82,6 +82,7 @@ import org.jclouds.http.functions.ReturnInputStream;
|
|||
import org.jclouds.http.functions.ReturnStringIf2xx;
|
||||
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValueInSet;
|
||||
import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue;
|
||||
import org.jclouds.http.functions.UnwrapOnlyNestedJsonValueInSet;
|
||||
import org.jclouds.http.functions.ParseSax.HandlerWithResult;
|
||||
|
@ -743,34 +744,7 @@ public class RestAnnotationProcessor<T> {
|
|||
|| TypeLiteral.get(method.getGenericReturnType()).equals(futureHttpResponseLiteral)) {
|
||||
return Key.get((Class) IdentityFunction.class);
|
||||
} else if (getAcceptHeadersOrNull(method).contains(MediaType.APPLICATION_JSON)) {
|
||||
Type returnVal;
|
||||
if (method.getReturnType().getTypeParameters().length == 0) {
|
||||
returnVal = method.getReturnType();
|
||||
} else if (method.getReturnType().equals(ListenableFuture.class)) {
|
||||
ParameterizedType futureType = ((ParameterizedType) method.getGenericReturnType());
|
||||
returnVal = futureType.getActualTypeArguments()[0];
|
||||
if (returnVal instanceof WildcardType)
|
||||
returnVal = WildcardType.class.cast(returnVal).getUpperBounds()[0];
|
||||
} else {
|
||||
returnVal = method.getGenericReturnType();
|
||||
}
|
||||
ParameterizedType parserType;
|
||||
if (method.isAnnotationPresent(Unwrap.class)) {
|
||||
int depth = method.getAnnotation(Unwrap.class).depth();
|
||||
Class edgeCollection = method.getAnnotation(Unwrap.class).edgeCollection();
|
||||
if (depth == 1 && edgeCollection == Map.class)
|
||||
parserType = Types.newParameterizedType(UnwrapOnlyJsonValue.class, returnVal);
|
||||
else if (depth == 2 && edgeCollection == Map.class)
|
||||
parserType = Types.newParameterizedType(UnwrapOnlyNestedJsonValue.class, returnVal);
|
||||
else if (depth == 3 && edgeCollection == Set.class)
|
||||
parserType = Types.newParameterizedType(UnwrapOnlyNestedJsonValueInSet.class, returnVal);
|
||||
else
|
||||
throw new IllegalStateException(String.format(
|
||||
"depth(%d) edgeCollection(%s) not yet supported for @Unwrap", depth, edgeCollection));
|
||||
} else {
|
||||
parserType = Types.newParameterizedType(ParseJson.class, returnVal);
|
||||
}
|
||||
return (Key<? extends Function<HttpResponse, ?>>) Key.get(parserType);
|
||||
return getJsonParserKeyForMethod(method);
|
||||
} else if (method.getReturnType().equals(String.class)
|
||||
|| TypeLiteral.get(method.getGenericReturnType()).equals(futureStringLiteral)) {
|
||||
return Key.get(ReturnStringIf2xx.class);
|
||||
|
@ -784,6 +758,49 @@ public class RestAnnotationProcessor<T> {
|
|||
return Key.get(annotation.value());
|
||||
}
|
||||
|
||||
public static Key<? extends Function<HttpResponse, ?>> getJsonParserKeyForMethod(Method method) {
|
||||
Type returnVal = getReturnTypeForMethod(method);
|
||||
return getJsonParserKeyForMethodAnType(method, returnVal);
|
||||
}
|
||||
|
||||
public static Type getReturnTypeForMethod(Method method) {
|
||||
Type returnVal;
|
||||
if (method.getReturnType().getTypeParameters().length == 0) {
|
||||
returnVal = method.getReturnType();
|
||||
} else if (method.getReturnType().equals(ListenableFuture.class)) {
|
||||
ParameterizedType futureType = ((ParameterizedType) method.getGenericReturnType());
|
||||
returnVal = futureType.getActualTypeArguments()[0];
|
||||
if (returnVal instanceof WildcardType)
|
||||
returnVal = WildcardType.class.cast(returnVal).getUpperBounds()[0];
|
||||
} else {
|
||||
returnVal = method.getGenericReturnType();
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
@SuppressWarnings( { "unchecked", "rawtypes" })
|
||||
public static Key<? extends Function<HttpResponse, ?>> getJsonParserKeyForMethodAnType(Method method, Type returnVal) {
|
||||
ParameterizedType parserType;
|
||||
if (method.isAnnotationPresent(Unwrap.class)) {
|
||||
int depth = method.getAnnotation(Unwrap.class).depth();
|
||||
Class edgeCollection = method.getAnnotation(Unwrap.class).edgeCollection();
|
||||
if (depth == 1 && edgeCollection == Map.class)
|
||||
parserType = Types.newParameterizedType(UnwrapOnlyJsonValue.class, returnVal);
|
||||
else if (depth == 2 && edgeCollection == Map.class)
|
||||
parserType = Types.newParameterizedType(UnwrapOnlyNestedJsonValue.class, returnVal);
|
||||
else if (depth == 2 && edgeCollection == Set.class)
|
||||
parserType = Types.newParameterizedType(UnwrapOnlyJsonValueInSet.class, returnVal);
|
||||
else if (depth == 3 && edgeCollection == Set.class)
|
||||
parserType = Types.newParameterizedType(UnwrapOnlyNestedJsonValueInSet.class, returnVal);
|
||||
else
|
||||
throw new IllegalStateException(String.format("depth(%d) edgeCollection(%s) not yet supported for @Unwrap",
|
||||
depth, edgeCollection));
|
||||
} else {
|
||||
parserType = Types.newParameterizedType(ParseJson.class, returnVal);
|
||||
}
|
||||
return (Key<? extends Function<HttpResponse, ?>>) Key.get(parserType);
|
||||
}
|
||||
|
||||
public static Class<? extends HandlerWithResult<?>> getSaxResponseParserClassOrNull(Method method) {
|
||||
XMLResponseParser annotation = method.getAnnotation(XMLResponseParser.class);
|
||||
if (annotation != null) {
|
||||
|
|
|
@ -126,8 +126,8 @@ openhosting-east1.contextbuilder=org.jclouds.openhosting.OpenHostingEast1Context
|
|||
cloudsigma-zrh.propertiesbuilder=org.jclouds.cloudsigma.CloudSigmaZurichPropertiesBuilder
|
||||
cloudsigma-zrh.contextbuilder=org.jclouds.cloudsigma.CloudSigmaContextBuilder
|
||||
|
||||
ibmdev.propertiesbuilder=org.jclouds.ibmdev.IBMDeveloperCloudPropertiesBuilder
|
||||
ibmdev.contextbuilder=org.jclouds.ibmdev.IBMDeveloperCloudContextBuilder
|
||||
ibm-smartcloud.propertiesbuilder=org.jclouds.ibm.smartcloud.IBMSmartCloudPropertiesBuilder
|
||||
ibm-smartcloud.contextbuilder=org.jclouds.ibm.smartcloud.IBMSmartCloudContextBuilder
|
||||
|
||||
stub.contextbuilder=org.jclouds.compute.stub.StubComputeServiceContextBuilder
|
||||
# example of where to change your endpoint
|
||||
|
|
|
@ -20,18 +20,24 @@ package org.jclouds.json;
|
|||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.util.Types;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -39,22 +45,41 @@ import com.google.inject.util.Types;
|
|||
*/
|
||||
public abstract class BaseParserTest<T, G> {
|
||||
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
||||
@Qualifier
|
||||
public @interface Nested {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Function<HttpResponse, T> parser(Injector i) {
|
||||
try {
|
||||
return (Function<HttpResponse, T>) i.getInstance(RestAnnotationProcessor.getJsonParserKeyForMethod(getClass()
|
||||
.getMethod("expected")));
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
T expects = expected();
|
||||
|
||||
Function<HttpResponse, T> parser = getParser(getInjector());
|
||||
T response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(getClass()
|
||||
.getResourceAsStream(resource()))));
|
||||
Function<HttpResponse, T> parser = parser(injector());
|
||||
T response = parser.apply(new HttpResponse(200, "ok", payload()));
|
||||
compare(expects, response);
|
||||
}
|
||||
|
||||
protected Payload payload() {
|
||||
return Payloads.newInputStreamPayload(getClass().getResourceAsStream(resource()));
|
||||
}
|
||||
|
||||
public void compare(T expects, T response) {
|
||||
assertEquals(response.toString(), expects.toString());
|
||||
}
|
||||
|
||||
protected Injector getInjector() {
|
||||
protected Injector injector() {
|
||||
return Guice.createInjector(new GsonModule() {
|
||||
|
||||
@Override
|
||||
|
@ -67,15 +92,9 @@ public abstract class BaseParserTest<T, G> {
|
|||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Function<HttpResponse, T> getParser(Injector i) {
|
||||
return (Function<HttpResponse, T>) i.getInstance(Key.get(TypeLiteral.get(
|
||||
Types.newParameterizedType(UnwrapOnlyNestedJsonValue.class, type())).getType()));
|
||||
protected String resource() {
|
||||
throw new IllegalStateException("please define resource such as \"/testaddresses.json\"");
|
||||
}
|
||||
|
||||
public abstract Class<G> type();
|
||||
|
||||
public abstract String resource();
|
||||
|
||||
public abstract T expected();
|
||||
}
|
||||
|
|
|
@ -22,15 +22,7 @@ import static org.testng.Assert.assertEquals;
|
|||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.util.Types;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -38,15 +30,6 @@ import com.google.inject.util.Types;
|
|||
*/
|
||||
public abstract class BaseSetParserTest<T> extends BaseParserTest<Set<T>, T> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
// crazy stuff due to type erasure
|
||||
@Override
|
||||
protected Function<HttpResponse, Set<T>> getParser(Injector i) {
|
||||
return (Function<HttpResponse, Set<T>>) i.getInstance(Key.get(TypeLiteral.get(
|
||||
Types.newParameterizedType(UnwrapOnlyNestedJsonValue.class, Types
|
||||
.newParameterizedType(Set.class, type()))).getType()));
|
||||
}
|
||||
|
||||
public void compare(Set<T> expects, Set<T> response) {
|
||||
assertEquals(ImmutableSortedSet.copyOf(response).toString(), ImmutableSortedSet.copyOf(expects).toString());
|
||||
}
|
||||
|
|
|
@ -37,6 +37,52 @@ import com.google.inject.TypeLiteral;
|
|||
public class JsonTest {
|
||||
private Json json = Guice.createInjector(new GsonModule()).getInstance(Json.class);
|
||||
|
||||
private static class ObjectNoDefaultConstructor {
|
||||
private final String stringValue;
|
||||
private final int intValue;
|
||||
|
||||
public ObjectNoDefaultConstructor(String stringValue, int intValue) {
|
||||
this.stringValue = stringValue;
|
||||
this.intValue = intValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + intValue;
|
||||
result = prime * result + ((stringValue == null) ? 0 : stringValue.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ObjectNoDefaultConstructor other = (ObjectNoDefaultConstructor) obj;
|
||||
if (intValue != other.intValue)
|
||||
return false;
|
||||
if (stringValue == null) {
|
||||
if (other.stringValue != null)
|
||||
return false;
|
||||
} else if (!stringValue.equals(other.stringValue))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void testObjectNoDefaultConstructor() {
|
||||
ObjectNoDefaultConstructor obj = new ObjectNoDefaultConstructor("foo", 1);
|
||||
assertEquals(json.toJson(obj), "{\"stringValue\":\"foo\",\"intValue\":1}");
|
||||
ObjectNoDefaultConstructor obj2 = json.fromJson(json.toJson(obj), ObjectNoDefaultConstructor.class);
|
||||
assertEquals(obj2, obj);
|
||||
assertEquals(json.toJson(obj2), json.toJson(obj));
|
||||
}
|
||||
|
||||
private static class EnumInside {
|
||||
private static enum Test {
|
||||
FOO, BAR;
|
||||
|
@ -66,7 +112,7 @@ public class JsonTest {
|
|||
map.put("map", ImmutableMap.of("key", "value"));
|
||||
map.put("list", ImmutableList.of("key", "value"));
|
||||
assertEquals(json.toJson(map),
|
||||
"{\"string\":\"string\",\"map\":{\"key\":\"value\"},\"list\":[\"key\",\"value\"],\"boolean\":true,\"number\":1}");
|
||||
"{\"string\":\"string\",\"map\":{\"key\":\"value\"},\"list\":[\"key\",\"value\"],\"boolean\":true,\"number\":1}");
|
||||
Map<String, Object> map2 = json.fromJson(json.toJson(map), new TypeLiteral<Map<String, Object>>() {
|
||||
}.getType());
|
||||
assertEquals(map2, map);
|
||||
|
@ -121,12 +167,12 @@ public class JsonTest {
|
|||
|
||||
public void testDeserializeEnumWithParser() {
|
||||
assertEquals(json.fromJson("{enumValue : \"FOO\"}", EnumInsideWithParser.class).enumValue,
|
||||
EnumInsideWithParser.Test.FOO);
|
||||
EnumInsideWithParser.Test.FOO);
|
||||
}
|
||||
|
||||
public void testDeserializeEnumWithParserAndBadValue() {
|
||||
assertEquals(json.fromJson("{enumValue : \"sd\"}", EnumInsideWithParser.class).enumValue,
|
||||
EnumInsideWithParser.Test.UNRECOGNIZED);
|
||||
EnumInsideWithParser.Test.UNRECOGNIZED);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
*
|
||||
* 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.providers;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jeremy Whitlock <jwhitlock@apache.org>
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public abstract class BaseProviderMetadataTest {
|
||||
protected Set<String> allTypes = ImmutableSet.of(ProviderMetadata.BLOBSTORE_TYPE, ProviderMetadata.COMPUTE_TYPE,
|
||||
ProviderMetadata.LOADBALANCER_TYPE, ProviderMetadata.QUEUE_TYPE, ProviderMetadata.TABLE_TYPE);
|
||||
|
||||
private final ProviderMetadata toTest;
|
||||
private final String expectedType;
|
||||
|
||||
public BaseProviderMetadataTest(ProviderMetadata toTest, String expectedType) {
|
||||
this.toTest = toTest;
|
||||
this.expectedType = expectedType;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithId() {
|
||||
ProviderMetadata providerMetadata = Providers.withId(toTest.getId());
|
||||
|
||||
assertEquals(toTest, providerMetadata);
|
||||
assert providerMetadata.getLinkedServices().contains(toTest.getId());
|
||||
}
|
||||
|
||||
// it is ok to have multiple services in the same classpath (ex. ec2 vs elb)
|
||||
@Test
|
||||
public void testOfTypeContains() {
|
||||
ImmutableSet<ProviderMetadata> ofType = ImmutableSet.copyOf(Providers.ofType(expectedType));
|
||||
assert ofType.contains(toTest) : String.format("%s not found in %s", toTest, ofType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllContains() {
|
||||
ImmutableSet<ProviderMetadata> all = ImmutableSet.copyOf(Providers.all());
|
||||
assert all.contains(toTest) : String.format("%s not found in %s", toTest, all);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInRestProperties() {
|
||||
Iterable<String> providers = org.jclouds.rest.Providers.getSupportedProviders();
|
||||
assert Iterables.contains(providers, toTest.getId()) : providers;
|
||||
}
|
||||
}
|
|
@ -21,14 +21,14 @@ package org.jclouds.providers;
|
|||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Implementation of {@ link org.jclouds.types.ProviderMetadata} for testing.
|
||||
*
|
||||
* Implementation of @ link org.jclouds.types.ProviderMetadata} for testing.
|
||||
*
|
||||
* @author Jeremy Whitlock <jwhitlock@apache.org>
|
||||
*/
|
||||
public class JcloudsTestBlobStoreProviderMetadata implements ProviderMetadata {
|
||||
public class JcloudsTestBlobStoreProviderMetadata extends BaseProviderMetadata {
|
||||
|
||||
/**
|
||||
* {@ see org.jclouds.types.ProviderMetadata#getId()}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getId() {
|
||||
|
@ -36,7 +36,7 @@ public class JcloudsTestBlobStoreProviderMetadata implements ProviderMetadata {
|
|||
}
|
||||
|
||||
/**
|
||||
* {@ see org.jclouds.types.ProviderMetadata#getType()}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getType() {
|
||||
|
@ -44,7 +44,7 @@ public class JcloudsTestBlobStoreProviderMetadata implements ProviderMetadata {
|
|||
}
|
||||
|
||||
/**
|
||||
* {@ see org.jclouds.types.ProviderMetadata#getName()}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
|
@ -52,7 +52,23 @@ public class JcloudsTestBlobStoreProviderMetadata implements ProviderMetadata {
|
|||
}
|
||||
|
||||
/**
|
||||
* {@ see org.jclouds.types.ProviderMetadata#getHomepage()}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getCredentialName() {
|
||||
return "user";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getIdentityName() {
|
||||
return "password";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public URI getHomepage() {
|
||||
|
@ -60,11 +76,19 @@ public class JcloudsTestBlobStoreProviderMetadata implements ProviderMetadata {
|
|||
}
|
||||
|
||||
/**
|
||||
* {@ see org.jclouds.types.ProviderMetadata#getConsole()}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public URI getConsole() {
|
||||
return URI.create("http://jclouds.org/console");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public URI getApiDocumentation() {
|
||||
return URI.create("http://jclouds.org/documentation");
|
||||
}
|
||||
|
||||
}
|
|
@ -21,11 +21,11 @@ package org.jclouds.providers;
|
|||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Implementation of {@ link org.jclouds.types.ProviderMetadata} for testing.
|
||||
*
|
||||
* Implementation of @ link org.jclouds.types.ProviderMetadata} for testing.
|
||||
*
|
||||
* @author Jeremy Whitlock <jwhitlock@apache.org>
|
||||
*/
|
||||
public class JcloudsTestComputeProviderMetadata implements ProviderMetadata {
|
||||
public class JcloudsTestComputeProviderMetadata extends BaseProviderMetadata {
|
||||
|
||||
/**
|
||||
* {@ see org.jclouds.types.ProviderMetadata#getId()}
|
||||
|
@ -51,6 +51,22 @@ public class JcloudsTestComputeProviderMetadata implements ProviderMetadata {
|
|||
return "Test Compute Provider";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getCredentialName() {
|
||||
return "user";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getIdentityName() {
|
||||
return "password";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@ see org.jclouds.types.ProviderMetadata#getHomepage()}
|
||||
*/
|
||||
|
@ -67,4 +83,12 @@ public class JcloudsTestComputeProviderMetadata implements ProviderMetadata {
|
|||
return URI.create("http://jclouds.org/console");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public URI getApiDocumentation() {
|
||||
return URI.create("http://jclouds.org/documentation");
|
||||
}
|
||||
|
||||
}
|
|
@ -33,10 +33,13 @@ import org.testng.annotations.Test;
|
|||
@Test( groups = "unit" )
|
||||
public class ProvidersTest {
|
||||
|
||||
private final ProviderMetadata testBlobstoreProvider = new JcloudsTestBlobStoreProviderMetadata();
|
||||
private final ProviderMetadata testComputeProvider = new JcloudsTestComputeProviderMetadata();
|
||||
|
||||
@Test
|
||||
public void testWithId() {
|
||||
ProviderMetadata providerMetadata;
|
||||
|
||||
|
||||
try {
|
||||
providerMetadata = Providers.withId("fake-id");
|
||||
fail("Looking for a provider with an id that doesn't exist should " +
|
||||
|
@ -45,9 +48,9 @@ public class ProvidersTest {
|
|||
; // Expected
|
||||
}
|
||||
|
||||
providerMetadata = Providers.withId("test-blobstore-provider");
|
||||
providerMetadata = Providers.withId(testBlobstoreProvider.getId());
|
||||
|
||||
assertEquals("Test Blobstore Provider", providerMetadata.getName());
|
||||
assertEquals(testBlobstoreProvider, providerMetadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -55,21 +58,13 @@ public class ProvidersTest {
|
|||
Iterable<ProviderMetadata> providersMetadata = Providers.ofType(ProviderMetadata.BLOBSTORE_TYPE);
|
||||
|
||||
for (ProviderMetadata providerMetadata : providersMetadata) {
|
||||
assertEquals("Test Blobstore Provider", providerMetadata.getName());
|
||||
assertEquals("test-blobstore-provider", providerMetadata.getId());
|
||||
assertEquals(ProviderMetadata.BLOBSTORE_TYPE, providerMetadata.getType());
|
||||
assertEquals("http://jclouds.org", providerMetadata.getHomepage().toString());
|
||||
assertEquals("http://jclouds.org/console", providerMetadata.getConsole().toString());
|
||||
assertEquals(testBlobstoreProvider, providerMetadata);
|
||||
}
|
||||
|
||||
providersMetadata = Providers.ofType(ProviderMetadata.COMPUTE_TYPE);
|
||||
|
||||
for (ProviderMetadata providerMetadata : providersMetadata) {
|
||||
assertEquals("Test Compute Provider", providerMetadata.getName());
|
||||
assertEquals("test-compute-provider", providerMetadata.getId());
|
||||
assertEquals(ProviderMetadata.COMPUTE_TYPE, providerMetadata.getType());
|
||||
assertEquals("http://jclouds.org", providerMetadata.getHomepage().toString());
|
||||
assertEquals("http://jclouds.org/console", providerMetadata.getConsole().toString());
|
||||
assertEquals(testComputeProvider, providerMetadata);
|
||||
}
|
||||
|
||||
providersMetadata = Providers.ofType("fake-type");
|
||||
|
@ -83,16 +78,9 @@ public class ProvidersTest {
|
|||
|
||||
for (ProviderMetadata providerMetadata : providersMetadata) {
|
||||
if (providerMetadata.getName().equals("Test Blobstore Provider")) {
|
||||
assertEquals("test-blobstore-provider", providerMetadata.getId());
|
||||
assertEquals(ProviderMetadata.BLOBSTORE_TYPE, providerMetadata.getType());
|
||||
assertEquals("http://jclouds.org", providerMetadata.getHomepage().toString());
|
||||
assertEquals("http://jclouds.org/console", providerMetadata.getConsole().toString());
|
||||
assertEquals(testBlobstoreProvider, providerMetadata);
|
||||
} else {
|
||||
assertEquals("Test Compute Provider", providerMetadata.getName());
|
||||
assertEquals("test-compute-provider", providerMetadata.getId());
|
||||
assertEquals(ProviderMetadata.COMPUTE_TYPE, providerMetadata.getType());
|
||||
assertEquals("http://jclouds.org", providerMetadata.getHomepage().toString());
|
||||
assertEquals("http://jclouds.org/console", providerMetadata.getConsole().toString());
|
||||
assertEquals(testComputeProvider, providerMetadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ import org.jclouds.http.functions.ReturnInputStream;
|
|||
import org.jclouds.http.functions.ReturnStringIf2xx;
|
||||
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValueInSet;
|
||||
import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue;
|
||||
import org.jclouds.http.functions.UnwrapOnlyNestedJsonValueInSet;
|
||||
import org.jclouds.http.internal.PayloadEnclosingImpl;
|
||||
|
@ -833,7 +834,13 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
@Unwrap(depth = 2)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
ListenableFuture<Long> testUnwrapDepth2Long();
|
||||
|
||||
|
||||
@GET
|
||||
@Path("/")
|
||||
@Unwrap(depth = 2, edgeCollection = Set.class)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
ListenableFuture<String> testUnwrapDepth2Set();
|
||||
|
||||
@GET
|
||||
@Path("/")
|
||||
@Unwrap(depth = 3, edgeCollection = Set.class)
|
||||
|
@ -1033,6 +1040,23 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
.<String> of());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testUnwrapDepth2Set() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = TestPut.class.getMethod("testUnwrapDepth2Set");
|
||||
HttpRequest request = factory(TestPut.class).createRequest(method);
|
||||
|
||||
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValueInSet.class);
|
||||
// now test that it works!
|
||||
|
||||
Function<HttpResponse, Map<String, String>> parser = (Function<HttpResponse, Map<String, String>>) RestAnnotationProcessor
|
||||
.createResponseParser(parserFactory, injector, method, request);
|
||||
|
||||
assertEquals(parser.apply(new HttpResponse(200, "ok",
|
||||
newStringPayload("{\"runit\":[\"0.7.0\"]}"))), "0.7.0");
|
||||
|
||||
assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{\"runit\":[]}"))), null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testUnwrapDepth2Long() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = TestPut.class.getMethod("testUnwrapDepth2Long");
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -32,7 +32,7 @@
|
|||
<groupId>org.jclouds.driver</groupId>
|
||||
<artifactId>jclouds-apachehc</artifactId>
|
||||
<name>jclouds Apache Http Components Client</name>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
<description>Apache HttpComponents client</description>
|
||||
|
||||
<!-- bootstrapping: need to fetch the project POM -->
|
||||
|
@ -72,4 +72,20 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<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.http.apachehc.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -33,6 +33,7 @@
|
|||
<artifactId>jclouds-bouncycastle</artifactId>
|
||||
<name>jclouds bouncycastle EncryptionService Module</name>
|
||||
<description>jclouds bouncycastle EncryptionService Module</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<!-- bootstrapping: need to fetch the project POM -->
|
||||
<repositories>
|
||||
|
@ -65,4 +66,21 @@
|
|||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<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.encryption.bouncycastle.*;version="${project.version}"</Export-Package>
|
||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue