merged latest

This commit is contained in:
Adrian Cole 2012-09-16 23:53:55 -07:00
commit 3be0f27b4b
1196 changed files with 81971 additions and 14668 deletions

View File

@ -1,136 +0,0 @@
Overview:
jclouds allows provisioning and control of cloud resources, including blobstore
and compute, from Java and Clojure. Our API gives allows developers to use
both portable abstractions and cloud-specific features. We test support of 30
cloud providers and cloud software stacks, including Amazon, Azure, GoGrid,
Ninefold, OpenStack, and vCloud. jclouds is licensed under the Apache License,
Version 2.0
our current version is 1.4.2
our next maintenance version is 1.4.2-SNAPSHOT
our dev version is 1.5.0-SNAPSHOT
check out our examples site! https://github.com/jclouds/jclouds-examples
our compute api supports: aws-ec2, gogrid, cloudservers-us, stub (in-memory), deltacloud,
cloudservers-uk, vcloud (generic), ec2 (generic), byon, nova,
trmk-ecloud, trmk-vcloudexpress, eucalyptus (generic)
cloudsigma-zrh, elasticstack(generic), go2cloud-jhb1, cloudsigma-lvs,
bluelock-vcloud-zone01, stratogen-vcloud-mycloud, rimuhosting,
slicehost, eucalyptus-partnercloud-ec2, elastichosts-lon-p (Peer 1),
elastichosts-sat-p (Peer 1), elastichosts-lon-b (BlueSquare),
openhosting-east1, serverlove-z1-man, skalicloud-sdg-my,
greenhousedata-element-vcloud, softlayer, cloudsigma (generic),
cloudstack (generic), ninefold-compute, openstack-nov (keystone),
hpcloud-compute, trystack-nova, openstack-nova-ec2,
rackspace-cloudservers-us (next gen), rackspace-cloudservers-uk (next gen)
* note * the pom dependency org.jclouds/jclouds-allcompute gives you access to
to all of these providers
our blobstore api supports: aws-s3, cloudfiles-us, cloudfiles-uk, filesystem,
azureblob, atmos (generic), synaptic-storage, hpcloud-objectstorage,
cloudonestorage, walrus(generic), ninefold-storage,
eucalyptus-partnercloud-s3, swift (generic), transient (in-mem)
* note * the pom dependency org.jclouds/jclouds-allblobstore gives you access to
to all of these providers
our loadbalancer api supports: cloudloadbalancers-us
* note * the pom dependency org.jclouds/jclouds-allloadbalancer gives you access to
to all of these providers
we also have aws-cloudwatch support.
we also have support for: ibmdev, mezeo, nirvanix, boxdotnet, openstack nova, scality ring,
hosteurope-storage, tiscali-storage, scaleup-storage, googlestorage,
azurequeue, simpledb, as well as a async-http-client
driver in the sandbox
If you want access to all jclouds components, include the maven dependency org.jclouds/jclouds-all
BlobStore Example (Java):
// init
context = new BlobStoreContextFactory().createContext(
"aws-s3",
accesskeyid,
secretaccesskey);
blobStore = context.getBlobStore();
// create container
blobStore.createContainerInLocation(null, "mycontainer");
// add blob
blob = blobStore.blobBuilder("test").payload("testdata").build();
blobStore.putBlob("mycontainer", blob);
BlobStore Example (Clojure):
(use 'org.jclouds.blobstore2)
(def *blobstore* (blobstore "azureblob" account encodedkey))
(create-container *blobstore* "mycontainer")
(put-blob *blobstore* "mycontainer" (blob "test" :payload "testdata"))
Compute Example (Java):
// init
context = new ComputeServiceContextFactory().createContext(
"aws-ec2",
accesskeyid,
secretaccesskey,
ImmutableSet.of(new Log4JLoggingModule(),
new SshjSshClientModule()));
client = context.getComputeService();
// define the requirements of your node
template = client.templateBuilder().osFamily(UBUNTU).smallest().build();
// setup a boot user which is the same as your login
template.getOptions().runScript(AdminAccess.standard());
// these nodes will be accessible via ssh when the call returns
nodes = client.createNodesInGroup("mycluster", 2, template);
// you can now run ad-hoc commands on the nodes based on predicates
responses = client.runScriptOnNodesMatching(inGroup("mycluster"), "uptime",
wrapInInitScript(false));
Compute Example (Clojure):
(use 'org.jclouds.compute2)
; create a compute service using sshj and log4j extensions
(def compute
(*compute* "trmk`-ecloud" "user" "password" :sshj :log4j))
; launch a couple nodes with the default operating system, installing your user.
(create-nodes *compute* "mycluster" 2
(TemplateOptions$Builder/runScript (AdminAccess/standard)))
; run a command on that group
(run-script-on-nodes-matching *compute* (in-group? "mycluster") "uptime"
(RunScriptOptions$Builder/wrapInInitScript false))
Downloads:
* release notes: http://www.jclouds.org/documentation/releasenotes/1.3
* installation guide: http://www.jclouds.org/documentation/userguide/installation-guide
* maven repo: http://repo2.maven.org/maven2 (maven central - the default repository)
* snapshot repo: https://oss.sonatype.org/content/repositories/snapshots
Links:
* project page: http://jclouds.org/
* documentation: http://www.jclouds.org/documentation/index
* javadocs (1.1.0): http://jclouds.rimuhosting.com/apidocs/
* javadocs (1.0-SNAPSHOT): http://jclouds.rimuhosting.com/apidocs-SNAPSHOT/
* community: http://www.jclouds.org/documentation/reference/apps-that-use-jclouds
* user group: http://groups.google.com/group/jclouds
* dev group: http://groups.google.com/group/jclouds-dev
* twitter: http://twitter.com/jclouds
## License
Copyright (C) 2009-2012 jclouds, Inc.
Licensed under the Apache License, Version 2.0

View File

@ -40,6 +40,11 @@
<artifactId>aws-cloudwatch</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.provider</groupId>
<artifactId>aws-sqs</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-allloadbalancer</artifactId>

View File

@ -67,11 +67,21 @@ public class AtmosBlobRequestSigner implements BlobRequestSigner {
return cleanRequest(processor.createRequest(getMethod, getPath(container, name)));
}
@Override
public HttpRequest signGetBlob(String container, String name, long timeInSeconds) {
throw new UnsupportedOperationException();
}
@Override
public HttpRequest signPutBlob(String container, Blob blob) {
return cleanRequest(processor.createRequest(createMethod, container, blobToObject.apply(blob)));
}
@Override
public HttpRequest signPutBlob(String container, Blob blob, long timeInSeconds) {
throw new UnsupportedOperationException();
}
@Override
public HttpRequest signRemoveBlob(String container, String name) {
return cleanRequest(processor.createRequest(deleteMethod, getPath(container, name)));

View File

@ -19,10 +19,12 @@
package org.jclouds.cloudfiles;
import java.net.URI;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.HeaderParam;
@ -33,6 +35,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.blobstore.functions.ReturnNullOnContainerNotFound;
import org.jclouds.cloudfiles.binders.BindIterableToHeadersWithPurgeCDNObjectEmail;
import org.jclouds.cloudfiles.domain.ContainerCDNMetadata;
import org.jclouds.cloudfiles.functions.ParseCdnUriFromHeaders;
import org.jclouds.cloudfiles.functions.ParseContainerCDNMetadataFromHeaders;
@ -41,6 +44,7 @@ import org.jclouds.cloudfiles.reference.CloudFilesHeaders;
import org.jclouds.openstack.filters.AuthenticateRequest;
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
import org.jclouds.openstack.swift.Storage;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.Headers;
@ -57,7 +61,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* All commands return a ListenableFuture of the result from Cloud Files. Any exceptions incurred
* during processing will be backend in an {@link ExecutionException} as documented in
* {@link ListenableFuture#get()}.
*
*
* @see CloudFilesClient
* @see <a href="http://www.rackspacecloud.com/cf-devguide-20090812.pdf" />
* @author Adrian Cole
@ -77,9 +81,6 @@ public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient {
@Endpoint(CDNManagement.class)
ListenableFuture<? extends Set<ContainerCDNMetadata>> listCDNContainers(ListCdnContainerOptions... options);
// TODO: Container name is not included in CDN HEAD response headers, so we
// cannot populate it
// here.
/**
* @see CloudFilesClient#getCDNMetadata
*/
@ -90,6 +91,18 @@ public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient {
@Endpoint(CDNManagement.class)
ListenableFuture<ContainerCDNMetadata> getCDNMetadata(@PathParam("container") String container);
/**
* @see CloudFilesClient#enableCDN(String, long, boolean);
*/
@PUT
@Path("/{container}")
@Headers(keys = CloudFilesHeaders.CDN_ENABLED, values = "True")
@ResponseParser(ParseCdnUriFromHeaders.class)
@Endpoint(CDNManagement.class)
ListenableFuture<URI> enableCDN(@PathParam("container") String container,
@HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl,
@HeaderParam(CloudFilesHeaders.CDN_LOG_RETENTION) boolean logRetention);
/**
* @see CloudFilesClient#enableCDN(String, long);
*/
@ -99,7 +112,7 @@ public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient {
@ResponseParser(ParseCdnUriFromHeaders.class)
@Endpoint(CDNManagement.class)
ListenableFuture<URI> enableCDN(@PathParam("container") String container,
@HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl);
@HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl);
/**
* @see CloudFilesClient#enableCDN(String)
@ -112,14 +125,35 @@ public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient {
ListenableFuture<URI> enableCDN(@PathParam("container") String container);
/**
* @see CloudFilesClient#updateCDN
* @see CloudFilesClient#updateCDN(long, boolean)
*/
@POST
@Path("/{container}")
@ResponseParser(ParseCdnUriFromHeaders.class)
@Endpoint(CDNManagement.class)
ListenableFuture<URI> updateCDN(@PathParam("container") String container,
@HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl);
@HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl,
@HeaderParam(CloudFilesHeaders.CDN_LOG_RETENTION) boolean logRetention);
/**
* @see CloudFilesClient#updateCDN(boolean)
*/
@POST
@Path("/{container}")
@ResponseParser(ParseCdnUriFromHeaders.class)
@Endpoint(CDNManagement.class)
ListenableFuture<URI> updateCDN(@PathParam("container") String container,
@HeaderParam(CloudFilesHeaders.CDN_LOG_RETENTION) boolean logRetention);
/**
* @see CloudFilesClient#updateCDN(long)
*/
@POST
@Path("/{container}")
@ResponseParser(ParseCdnUriFromHeaders.class)
@Endpoint(CDNManagement.class)
ListenableFuture<URI> updateCDN(@PathParam("container") String container,
@HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl);
/**
* @see CloudFilesClient#disableCDN
@ -130,4 +164,41 @@ public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient {
@Endpoint(CDNManagement.class)
ListenableFuture<Boolean> disableCDN(@PathParam("container") String container);
/**
* @see CloudFilesClient#purgeCDNObject(String, String, List)
*/
@DELETE
@Path("/{container}/{object}")
@Headers(keys = CloudFilesHeaders.CDN_CONTAINER_PURGE_OBJECT_EMAIL, values = "{email}")
@Endpoint(CDNManagement.class)
ListenableFuture<Boolean> purgeCDNObject(@PathParam("container") String container,
@PathParam("object") String object,
@BinderParam(BindIterableToHeadersWithPurgeCDNObjectEmail.class) Iterable<String> emails);
/**
* @see CloudFilesClient#purgeCDNObject(String, String)
*/
@DELETE
@Path("/{container}/{object}")
@Endpoint(CDNManagement.class)
ListenableFuture<Boolean> purgeCDNObject(@PathParam("container") String container,
@PathParam("object") String object);
/**
* @see CloudFilesClient#setCDNStaticWebsiteIndex
*/
@POST
@Path("/{container}")
@Headers(keys = CloudFilesHeaders.CDN_WEBSITE_INDEX, values = "{index}")
ListenableFuture<Boolean> setCDNStaticWebsiteIndex(@PathParam("container") String container,
@PathParam("index") String index);
/**
* @see CloudFilesClient#setCDNStaticWebsiteError
*/
@POST
@Path("/{container}")
@Headers(keys = CloudFilesHeaders.CDN_WEBSITE_ERROR, values = "{error}")
ListenableFuture<Boolean> setCDNStaticWebsiteError(@PathParam("container") String container,
@PathParam("error") String error);
}

View File

@ -34,22 +34,75 @@ import org.jclouds.openstack.swift.CommonSwiftClient;
* <p/>
* All commands return a Future of the result from Cloud Files. Any exceptions incurred during
* processing will be backend in an {@link ExecutionException} as documented in {@link Future#get()}.
*
* @see <a href="http://www.rackspacecloud.com/cf-devguide-20090812.pdf" />
*
* @author Adrian Cole
* @see <a href="http://www.rackspacecloud.com/cf-devguide-20090812.pdf" />
*/
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
public interface CloudFilesClient extends CommonSwiftClient {
/**
* See http://docs.rackspace.com/files/api/v1/cf-devguide/content/List_CDN-Enabled_Containers-d1e2414.html
*/
Set<ContainerCDNMetadata> listCDNContainers(ListCdnContainerOptions... options);
/**
* See http://docs.rackspace.com/files/api/v1/cf-devguide/content/List_CDN-Enabled_Container_Metadata-d1e2711.html
*/
ContainerCDNMetadata getCDNMetadata(String container);
/**
* See http://docs.rackspace.com/files/api/v1/cf-devguide/content/CDN-Enabled_Container-d1e2665.html
*/
URI enableCDN(String container, long ttl, boolean logRetention);
/**
* See http://docs.rackspace.com/files/api/v1/cf-devguide/content/CDN-Enabled_Container-d1e2665.html
*/
URI enableCDN(String container, long ttl);
/**
* See http://docs.rackspace.com/files/api/v1/cf-devguide/content/CDN-Enabled_Container-d1e2665.html
*/
URI enableCDN(String container);
/**
* See http://docs.rackspace.com/files/api/v1/cf-devguide/content/Update_CDN-Enabled_Container_Metadata-d1e2787.html
*/
URI updateCDN(String container, long ttl, boolean logRetention);
/**
* See http://docs.rackspace.com/files/api/v1/cf-devguide/content/Update_CDN-Enabled_Container_Metadata-d1e2787.html
*/
URI updateCDN(String container, boolean logRetention);
/**
* See http://docs.rackspace.com/files/api/v1/cf-devguide/content/Update_CDN-Enabled_Container_Metadata-d1e2787.html
*/
URI updateCDN(String container, long ttl);
/**
* See http://docs.rackspace.com/files/api/v1/cf-devguide/content/CDN-Enabled_Container-d1e2665.html
*/
boolean disableCDN(String container);
/**
* See http://docs.rackspace.com/files/api/v1/cf-devguide/content/Purge_CDN-Enabled_Objects-d1e3858.html
*/
boolean purgeCDNObject(String container, String object, Iterable<String> emails);
/**
* See http://docs.rackspace.com/files/api/v1/cf-devguide/content/Purge_CDN-Enabled_Objects-d1e3858.html
*/
boolean purgeCDNObject(String container, String object);
/**
* http://docs.rackspace.com/files/api/v1/cf-devguide/content/Create_Static_Website-dle4000.html
*/
boolean setCDNStaticWebsiteIndex(String container, String index);
/*
* http://docs.rackspace.com/files/api/v1/cf-devguide/content/Set_Error_Pages_for_Static_Website-dle4005.html
*/
boolean setCDNStaticWebsiteError(String container, String error);
}

View File

@ -0,0 +1,53 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudfiles.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.List;
import javax.inject.Singleton;
import org.jclouds.cloudfiles.reference.CloudFilesHeaders;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMultimap;
/**
* @author Everett Toews
*/
@Singleton
public class BindIterableToHeadersWithPurgeCDNObjectEmail implements Binder {
@SuppressWarnings("unchecked")
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
checkArgument(checkNotNull(input, "input") instanceof Iterable<?>, "this binder is only valid for Iterable!");
checkNotNull(request, "request");
Iterable<String> emails = (Iterable<String>) input;
String emailCSV = Joiner.on(", ").join((List<String>) emails);
ImmutableMultimap<String, String> headers =
ImmutableMultimap.<String, String> of(CloudFilesHeaders.CDN_CONTAINER_PURGE_OBJECT_EMAIL, emailCSV);
return (R) request.toBuilder().replaceHeaders(headers).build();
}
}

View File

@ -23,12 +23,16 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Singleton;
import org.jclouds.blobstore.BlobRequestSigner;
import org.jclouds.cloudfiles.CloudFilesClient;
import org.jclouds.openstack.swift.TemporaryUrlKey;
import org.jclouds.cloudfiles.blobstore.CloudFilesAsyncBlobStore;
import org.jclouds.cloudfiles.blobstore.CloudFilesBlobStore;
import org.jclouds.cloudfiles.blobstore.functions.CloudFilesObjectToBlobMetadata;
import org.jclouds.cloudfiles.domain.ContainerCDNMetadata;
import org.jclouds.date.TimeStamp;
import org.jclouds.openstack.swift.blobstore.SwiftAsyncBlobStore;
import org.jclouds.openstack.swift.blobstore.SwiftBlobRequestSigner;
import org.jclouds.openstack.swift.blobstore.SwiftBlobStore;
import org.jclouds.openstack.swift.blobstore.config.SwiftBlobStoreContextModule;
import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlobMetadata;
@ -39,7 +43,6 @@ import com.google.common.cache.LoadingCache;
import com.google.inject.Provides;
/**
*
* @author Adrian Cole
*/
public class CloudFilesBlobStoreContextModule extends SwiftBlobStoreContextModule {
@ -67,5 +70,6 @@ public class CloudFilesBlobStoreContextModule extends SwiftBlobStoreContextModul
bind(SwiftBlobStore.class).to(CloudFilesBlobStore.class);
bind(SwiftAsyncBlobStore.class).to(CloudFilesAsyncBlobStore.class);
bind(ObjectToBlobMetadata.class).to(CloudFilesObjectToBlobMetadata.class);
bind(BlobRequestSigner.class).to(SwiftBlobRequestSigner.class);
}
}

View File

@ -29,17 +29,22 @@ public class ContainerCDNMetadata implements Comparable<ContainerCDNMetadata> {
private String name;
private boolean cdn_enabled;
private boolean log_retention;
private long ttl;
private URI cdn_uri;
private URI cdn_ssl_uri;
private URI cdn_streaming_uri;
private String referrer_acl;
private String useragent_acl;
private boolean log_retention;
public ContainerCDNMetadata(String name, boolean cdnEnabled, long ttl, URI cdnUri) {
public ContainerCDNMetadata(String name, boolean cdnEnabled, boolean logRetention, long ttl, URI cdnUri, URI cdnSslUri, URI cdnStreamingUri) {
this.name = name;
this.cdn_enabled = cdnEnabled;
this.log_retention = logRetention;
this.ttl = ttl;
this.cdn_uri = cdnUri;
this.cdn_ssl_uri = cdnSslUri;
this.cdn_streaming_uri = cdnStreamingUri;
}
public ContainerCDNMetadata() {
@ -53,16 +58,36 @@ public class ContainerCDNMetadata implements Comparable<ContainerCDNMetadata> {
return name;
}
public URI getCDNUri() {
return cdn_uri;
public boolean isCDNEnabled() {
return cdn_enabled;
}
public boolean isLogRetention() {
return log_retention;
}
public long getTTL() {
return ttl;
}
public boolean isCDNEnabled() {
return cdn_enabled;
public URI getCDNUri() {
return cdn_uri;
}
public URI getCDNSslUri() {
return cdn_ssl_uri;
}
public URI getCDNStreamingUri() {
return cdn_streaming_uri;
}
public String getReferrerACL() {
return referrer_acl;
}
public String getUseragentACL() {
return useragent_acl;
}
public int compareTo(ContainerCDNMetadata o) {
@ -87,31 +112,21 @@ public class ContainerCDNMetadata implements Comparable<ContainerCDNMetadata> {
return false;
if (getClass() != obj.getClass())
return false;
ContainerCDNMetadata other = (ContainerCDNMetadata) obj;
if (cdn_uri == null) {
if (other.cdn_uri != null)
return false;
} else if (!cdn_uri.equals(other.cdn_uri))
return false;
return true;
}
public String getReferrerACL() {
return referrer_acl;
}
public String getUseragentACL() {
return useragent_acl;
}
public boolean isLogRetention() {
return log_retention;
}
@Override
public String toString() {
return String.format(
"[name=%s, cdn_uri=%s, cdn_enabled=%s, log_retention=%s, referrer_acl=%s, ttl=%s, useragent_acl=%s]",
name, cdn_uri, cdn_enabled, log_retention, referrer_acl, ttl, useragent_acl);
"[name=%s, cdn_enabled=%s, log_retention=%s, ttl=%s, cdn_uri=%s, cdn_ssl_uri=%s, cdn_streaming_uri=%s, referrer_acl=%s, useragent_acl=%s]",
name, cdn_enabled, log_retention, ttl, cdn_uri, cdn_ssl_uri, cdn_streaming_uri, referrer_acl, useragent_acl);
}
}

View File

@ -45,18 +45,26 @@ public class ParseContainerCDNMetadataFromHeaders implements
* parses the http response headers to create a new {@link ContainerCDNMetadata} object.
*/
public ContainerCDNMetadata apply(final HttpResponse from) {
String cdnUri = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_URI),
CloudFilesHeaders.CDN_URI);
String cdnTTL = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_TTL),
CloudFilesHeaders.CDN_TTL);
String cdnEnabled = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_ENABLED),
CloudFilesHeaders.CDN_ENABLED);
String cdnEnabled = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_ENABLED), CloudFilesHeaders.CDN_ENABLED);
String cdnLogRetention = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_LOG_RETENTION), CloudFilesHeaders.CDN_LOG_RETENTION);
String cdnTTL = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_TTL), CloudFilesHeaders.CDN_TTL);
String cdnUri = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_URI), CloudFilesHeaders.CDN_URI);
String cdnSslUri = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_SSL_URI), CloudFilesHeaders.CDN_SSL_URI);
String cdnStreamingUri = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_STREAMING_URI), CloudFilesHeaders.CDN_STREAMING_URI);
if (cdnUri == null) {
// CDN is not, and has never, been enabled for this container.
return null;
} else {
return new ContainerCDNMetadata(request.getEndpoint().getPath(), Boolean
.parseBoolean(cdnEnabled), Long.parseLong(cdnTTL), URI.create(cdnUri));
}
else {
return new ContainerCDNMetadata(
request.getEndpoint().getPath(),
Boolean.parseBoolean(cdnEnabled),
Boolean.parseBoolean(cdnLogRetention),
Long.parseLong(cdnTTL),
URI.create(cdnUri),
URI.create(cdnSslUri),
URI.create(cdnStreamingUri));
}
}

View File

@ -31,8 +31,15 @@ import org.jclouds.openstack.swift.reference.SwiftHeaders;
public interface CloudFilesHeaders extends SwiftHeaders {
public static final String CDN_ENABLED = "X-CDN-Enabled";
public static final String CDN_REFERRER_ACL = "X-Referrer-ACL ";
public static final String CDN_LOG_RETENTION = "X-Log-Retention";
public static final String CDN_TTL = "X-TTL";
public static final String CDN_URI = "X-CDN-URI";
public static final String CDN_SSL_URI = "X-Cdn-Ssl-Uri";
public static final String CDN_STREAMING_URI = "X-Cdn-Streaming-Uri";
public static final String CDN_REFERRER_ACL = "X-Referrer-ACL ";
public static final String CDN_USER_AGENT_ACL = "X-User-Agent-ACL";
public static final String CDN_CONTAINER_PURGE_OBJECT_EMAIL = "X-Purge-Email";
public static final String CDN_WEBSITE_INDEX = "X-Container-Meta-Web-Index";
public static final String CDN_WEBSITE_ERROR = "X-Container-Meta-Web-Error";
}

View File

@ -18,7 +18,16 @@
*/
package org.jclouds.cloudfiles;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.net.URI;
import org.jclouds.blobstore.ContainerNotFoundException;
import org.jclouds.cloudfiles.domain.ContainerCDNMetadata;
import org.jclouds.cloudfiles.internal.BaseCloudFilesRestClientExpectTest;
import org.jclouds.cloudfiles.reference.CloudFilesHeaders;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.testng.annotations.Test;
@ -30,7 +39,8 @@ import org.testng.annotations.Test;
@Test(groups = "unit", testName = "CloudFilesClientExpectTest")
public class CloudFilesClientExpectTest extends BaseCloudFilesRestClientExpectTest {
public void deleteContainerReturnsTrueOn200And404() {
@Test
public void testDeleteContainerReturnsTrueOn200And404() {
HttpRequest deleteContainer = HttpRequest
.builder()
@ -50,7 +60,194 @@ public class CloudFilesClientExpectTest extends BaseCloudFilesRestClientExpectTe
CloudFilesClient clientWhenContainerDoesntExist = requestsSendResponses(initialAuth, responseWithAuth, deleteContainer,
containerNotFound);
assert clientWhenContainerDoesntExist.deleteContainerIfEmpty("container");
}
@Test
public void testGetCDNMetadataWhenResponseIs2xxReturnsContainerCDNMetadata() {
HttpRequest cdnContainerRequest = HttpRequest.builder()
.method("HEAD")
.endpoint("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container")
.addHeader("X-Auth-Token", authToken)
.build();
HttpResponse cdnContainerResponse = HttpResponse.builder()
.addHeader(CloudFilesHeaders.CDN_ENABLED, "True")
.addHeader(CloudFilesHeaders.CDN_LOG_RETENTION, "True")
.addHeader(CloudFilesHeaders.CDN_TTL, "259200")
.addHeader(CloudFilesHeaders.CDN_URI, "http://546406d62bf471d7435d-36c33e76d676c80251b3c13ecb603b67.r19.cf1.rackcdn.com")
.addHeader(CloudFilesHeaders.CDN_SSL_URI, "https://e9f6fe92d217dc013369-36c33e76d676c80251b3c13ecb603b67.ssl.cf1.rackcdn.com")
.addHeader(CloudFilesHeaders.CDN_STREAMING_URI, "http://0e79346bc0a2564dcc5e-36c33e76d676c80251b3c13ecb603b67.r19.stream.cf1.rackcdn.com")
.statusCode(204)
.build();
CloudFilesClient cdnContainerClient = requestsSendResponses(
initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse);
ContainerCDNMetadata containerCDNMetadata = cdnContainerClient.getCDNMetadata("container");
assertTrue(containerCDNMetadata.isCDNEnabled());
assertTrue(containerCDNMetadata.isLogRetention());
assertEquals(containerCDNMetadata.getTTL(), 259200);
assertEquals(containerCDNMetadata.getCDNUri().toString(), "http://546406d62bf471d7435d-36c33e76d676c80251b3c13ecb603b67.r19.cf1.rackcdn.com");
assertEquals(containerCDNMetadata.getCDNSslUri().toString(), "https://e9f6fe92d217dc013369-36c33e76d676c80251b3c13ecb603b67.ssl.cf1.rackcdn.com");
assertEquals(containerCDNMetadata.getCDNStreamingUri().toString(), "http://0e79346bc0a2564dcc5e-36c33e76d676c80251b3c13ecb603b67.r19.stream.cf1.rackcdn.com");
}
@Test
public void testGetCDNMetadataWhenResponseIs404ReturnsNull() {
HttpRequest cdnContainerRequest = HttpRequest.builder()
.method("HEAD")
.endpoint("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container")
.addHeader("X-Auth-Token", authToken)
.build();
HttpResponse cdnContainerResponse = HttpResponse.builder()
.statusCode(404)
.build();
CloudFilesClient cdnContainerClient = requestsSendResponses(
initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse);
assertNull(cdnContainerClient.getCDNMetadata("container"));
}
@Test
public void testUpdateCDNMetadataWhenResponseIs2xxReturnsURI() {
HttpRequest cdnContainerRequest = HttpRequest.builder()
.method("POST")
.endpoint("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container")
.addHeader(CloudFilesHeaders.CDN_LOG_RETENTION, "true")
.addHeader(CloudFilesHeaders.CDN_TTL, "259200")
.addHeader("X-Auth-Token", authToken)
.build();
HttpResponse cdnContainerResponse = HttpResponse.builder()
.addHeader(CloudFilesHeaders.CDN_ENABLED, "True")
.addHeader(CloudFilesHeaders.CDN_LOG_RETENTION, "True")
.addHeader(CloudFilesHeaders.CDN_TTL, "259200")
.addHeader(CloudFilesHeaders.CDN_URI, "http://546406d62bf471d7435d-36c33e76d676c80251b3c13ecb603b67.r19.cf1.rackcdn.com")
.addHeader(CloudFilesHeaders.CDN_SSL_URI, "https://e9f6fe92d217dc013369-36c33e76d676c80251b3c13ecb603b67.ssl.cf1.rackcdn.com")
.addHeader(CloudFilesHeaders.CDN_STREAMING_URI, "http://0e79346bc0a2564dcc5e-36c33e76d676c80251b3c13ecb603b67.r19.stream.cf1.rackcdn.com")
.statusCode(204)
.build();
CloudFilesClient cdnContainerClient = requestsSendResponses(
initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse);
URI cdnURI = cdnContainerClient.updateCDN("container", 259200, true);
assertEquals(cdnURI.toString(), "http://546406d62bf471d7435d-36c33e76d676c80251b3c13ecb603b67.r19.cf1.rackcdn.com");
}
@Test(expectedExceptions = ContainerNotFoundException.class)
public void testUpdateCDNMetadataWhenResponseIs404ThrowsException() {
HttpRequest cdnContainerRequest = HttpRequest.builder()
.method("POST")
.endpoint("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container")
.addHeader(CloudFilesHeaders.CDN_LOG_RETENTION, "true")
.addHeader(CloudFilesHeaders.CDN_TTL, "259200")
.addHeader("X-Auth-Token", authToken)
.build();
HttpResponse cdnContainerResponse = HttpResponse.builder()
.statusCode(404)
.build();
CloudFilesClient cdnContainerClient = requestsSendResponses(
initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse);
cdnContainerClient.updateCDN("container", 259200, true);
}
@Test
public void testPurgeCDNObjectWhenResponseIs2xxReturnsTrue() {
HttpRequest cdnContainerRequest = HttpRequest.builder()
.method("DELETE")
.endpoint("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container/foo.txt")
.addHeader("X-Auth-Token", authToken)
.build();
HttpResponse cdnContainerResponse = HttpResponse.builder()
.statusCode(204)
.build();
CloudFilesClient cdnContainerClient = requestsSendResponses(
initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse);
assertTrue(cdnContainerClient.purgeCDNObject("container", "foo.txt"));
}
@Test
public void testSetCDNStaticWebsiteIndexWhenResponseIs2xxReturnsTrue() {
HttpRequest cdnContainerRequest = HttpRequest.builder()
.method("POST")
.endpoint("https://storage101.lon3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container")
.addHeader(CloudFilesHeaders.CDN_WEBSITE_INDEX, "index.html")
.addHeader("X-Auth-Token", authToken)
.build();
HttpResponse cdnContainerResponse = HttpResponse.builder()
.statusCode(204)
.build();
CloudFilesClient cdnContainerClient = requestsSendResponses(
initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse);
assertTrue(cdnContainerClient.setCDNStaticWebsiteIndex("container", "index.html"));
}
@Test(expectedExceptions = ContainerNotFoundException.class)
public void testSetCDNStaticWebsiteIndexWhenResponseIs404ThrowsException() {
HttpRequest cdnContainerRequest = HttpRequest.builder()
.method("POST")
.endpoint("https://storage101.lon3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container")
.addHeader(CloudFilesHeaders.CDN_WEBSITE_INDEX, "index.html")
.addHeader("X-Auth-Token", authToken)
.build();
HttpResponse cdnContainerResponse = HttpResponse.builder()
.statusCode(404)
.build();
CloudFilesClient cdnContainerClient = requestsSendResponses(
initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse);
cdnContainerClient.setCDNStaticWebsiteIndex("container", "index.html");
}
@Test
public void testSetCDNStaticWebsiteErrorWhenResponseIs2xxReturnsTrue() {
HttpRequest cdnContainerRequest = HttpRequest.builder()
.method("POST")
.endpoint("https://storage101.lon3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container")
.addHeader(CloudFilesHeaders.CDN_WEBSITE_ERROR, "error.html")
.addHeader("X-Auth-Token", authToken)
.build();
HttpResponse cdnContainerResponse = HttpResponse.builder()
.statusCode(204)
.build();
CloudFilesClient cdnContainerClient = requestsSendResponses(
initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse);
assertTrue(cdnContainerClient.setCDNStaticWebsiteError("container", "error.html"));
}
@Test(expectedExceptions = ContainerNotFoundException.class)
public void testSetCDNStaticWebsiteErrorWhenResponseIs404ThrowsException() {
HttpRequest cdnContainerRequest = HttpRequest.builder()
.method("POST")
.endpoint("https://storage101.lon3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container")
.addHeader(CloudFilesHeaders.CDN_WEBSITE_ERROR, "error.html")
.addHeader("X-Auth-Token", authToken)
.build();
HttpResponse cdnContainerResponse = HttpResponse.builder()
.statusCode(404)
.build();
CloudFilesClient cdnContainerClient = requestsSendResponses(
initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse);
cdnContainerClient.setCDNStaticWebsiteError("container", "error.html");
}
}

View File

@ -27,6 +27,7 @@ import java.util.Set;
import org.jclouds.cloudfiles.domain.ContainerCDNMetadata;
import org.jclouds.cloudfiles.options.ListCdnContainerOptions;
import org.jclouds.openstack.swift.CommonSwiftClientLiveTest;
import org.jclouds.openstack.swift.domain.ContainerMetadata;
import org.jclouds.openstack.swift.domain.SwiftObject;
import org.testng.annotations.Test;
@ -80,16 +81,23 @@ public class CloudFilesClientLiveTest extends CommonSwiftClientLiveTest<CloudFil
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
assertTrue(cdnMetadata.isCDNEnabled());
assertEquals(cdnMetadata.getCDNUri(), cdnUri);
// Test static website metadata
getApi().setCDNStaticWebsiteIndex(containerNameWithCDN, "index.html");
getApi().setCDNStaticWebsiteError(containerNameWithCDN, "error.html");
ContainerMetadata containerMetadata = getApi().getContainerMetadata(containerNameWithCDN);
assertEquals(containerMetadata.getMetadata().get("web-index"), "index.html");
assertEquals(containerMetadata.getMetadata().get("web-error"), "error.html");
cdnMetadata = getApi().getCDNMetadata(containerNameWithoutCDN);
assert cdnMetadata == null || !cdnMetadata.isCDNEnabled() : containerNameWithoutCDN
+ " should not have metadata";
assert getApi().getCDNMetadata("DoesNotExist") == null;
// List CDN metadata for containers, and ensure all CDN info is
// available for enabled
// container
@ -97,9 +105,16 @@ public class CloudFilesClientLiveTest extends CommonSwiftClientLiveTest<CloudFil
assertTrue(cdnMetadataList.size() >= 1);
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
final boolean cdnEnabled = cdnMetadata.isCDNEnabled();
final boolean logRetention = cdnMetadata.isLogRetention();
final long initialTTL = cdnMetadata.getTTL();
assertTrue(cdnMetadataList.contains(new ContainerCDNMetadata(containerNameWithCDN, true, initialTTL, cdnUri)));
final URI cdnSslUri = cdnMetadata.getCDNSslUri();
final URI cdnStreamingUri = cdnMetadata.getCDNStreamingUri();
assertTrue(cdnMetadataList.contains(new ContainerCDNMetadata(
containerNameWithCDN, cdnEnabled, logRetention, initialTTL, cdnUri, cdnSslUri, cdnStreamingUri)));
// Test listing with options
cdnMetadataList = getApi().listCDNContainers(ListCdnContainerOptions.Builder.enabledOnly());
assertTrue(Iterables.all(cdnMetadataList, new Predicate<ContainerCDNMetadata>() {
@ -113,10 +128,9 @@ public class CloudFilesClientLiveTest extends CommonSwiftClientLiveTest<CloudFil
containerNameWithCDN.substring(0, containerNameWithCDN.length() - 1)).maxResults(1));
assertEquals(cdnMetadataList.size(), 1);
// Enable CDN with PUT for the same container, this time with a custom
// TTL
// Enable CDN with PUT for the same container, this time with a custom TTL and Log Retention
long ttl = 4000;
getApi().enableCDN(containerNameWithCDN, ttl);
getApi().enableCDN(containerNameWithCDN, ttl, true);
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
@ -126,7 +140,7 @@ public class CloudFilesClientLiveTest extends CommonSwiftClientLiveTest<CloudFil
// Check POST by updating TTL settings
ttl = minimumTTL;
getApi().updateCDN(containerNameWithCDN, minimumTTL);
getApi().updateCDN(containerNameWithCDN, minimumTTL, false);
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
assertTrue(cdnMetadata.isCDNEnabled());
@ -135,9 +149,15 @@ public class CloudFilesClientLiveTest extends CommonSwiftClientLiveTest<CloudFil
// Confirm that minimum allowed value for TTL is 3600, lower values are
// ignored.
getApi().updateCDN(containerNameWithCDN, 3599L);
getApi().updateCDN(containerNameWithCDN, 3599L, false);
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
assertEquals(cdnMetadata.getTTL(), 3599L);
// Test purging an object from a CDN container
SwiftObject swiftObject = newSwiftObject("hello", "hello.txt");
getApi().putObject(containerNameWithCDN, swiftObject);
assertTrue(getApi().purgeCDNObject(containerNameWithCDN, swiftObject.getInfo().getName()));
// Disable CDN with POST
assertTrue(getApi().disableCDN(containerNameWithCDN));

View File

@ -0,0 +1,76 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudfiles.binders;
import static org.testng.Assert.assertEquals;
import java.util.List;
import org.jclouds.cloudfiles.reference.CloudFilesHeaders;
import org.jclouds.http.HttpRequest;
import org.jclouds.openstack.swift.CommonSwiftClientTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
/**
* Tests behavior of {@code BindIterableToHeadersWithPurgeCDNObjectEmail}
*
* @author Everett Toews
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "BindIterableToHeadersWithPurgeCDNObjectEmailTest")
public class BindIterableToHeadersWithPurgeCDNObjectEmailTest extends CommonSwiftClientTest {
@Test
public void testEmailBind() {
List<String> emails = ImmutableList.of("foo@bar.com", "bar@foo.com");
HttpRequest request = HttpRequest.builder().method("DELETE").endpoint("http://localhost").build();
BindIterableToHeadersWithPurgeCDNObjectEmail binder =
injector.getInstance(BindIterableToHeadersWithPurgeCDNObjectEmail.class);
HttpRequest actualRequest = binder.bindToRequest(request, emails);
HttpRequest expectedRequest = HttpRequest.builder()
.method("DELETE")
.endpoint("http://localhost")
.addHeader(CloudFilesHeaders.CDN_CONTAINER_PURGE_OBJECT_EMAIL, "foo@bar.com, bar@foo.com")
.build();
assertEquals(actualRequest, expectedRequest);
}
@Test(expectedExceptions = NullPointerException.class)
public void testNullListIsBad() {
HttpRequest request = HttpRequest.builder().method("DELETE").endpoint("http://localhost").build();
BindIterableToHeadersWithPurgeCDNObjectEmail binder =
injector.getInstance(BindIterableToHeadersWithPurgeCDNObjectEmail.class);
binder.bindToRequest(request, null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testNullRequestIsBad() {
List<String> emails = ImmutableList.of("foo@bar.com", "bar@foo.com");
BindIterableToHeadersWithPurgeCDNObjectEmail binder =
injector.getInstance(BindIterableToHeadersWithPurgeCDNObjectEmail.class);
binder.bindToRequest(null, emails);
}
}

View File

@ -19,15 +19,36 @@
package org.jclouds.cloudfiles.blobstore.integration;
import org.jclouds.openstack.swift.blobstore.integration.SwiftBlobLiveTest;
import org.jclouds.openstack.swift.extensions.TemporaryUrlKeyApi;
import org.testng.annotations.Test;
import java.util.UUID;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
/**
*
* @author Adrian Cole
*/
@Test(groups = { "live" })
@Test(groups = {"live"})
public class CloudFilesBlobLiveTest extends SwiftBlobLiveTest {
public CloudFilesBlobLiveTest(){
public CloudFilesBlobLiveTest() {
provider = "cloudfiles";
}
public void testGetAndSetTemporaryUrlKey() {
TemporaryUrlKeyApi client = view.utils().injector().getInstance(TemporaryUrlKeyApi.class);
String currentSecretKey = client.getTemporaryUrlKey();
assertNotNull(currentSecretKey);
try {
String testKey = UUID.randomUUID().toString();
client.setTemporaryUrlKey(testKey);
assertEquals(client.getTemporaryUrlKey(), testKey);
} finally {
client.setTemporaryUrlKey(currentSecretKey);
}
}
}

View File

@ -22,12 +22,11 @@ import org.jclouds.openstack.swift.blobstore.integration.SwiftBlobSignerLiveTest
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = { "live" })
@Test(groups = {"live"})
public class CloudFilesBlobSignerLiveTest extends SwiftBlobSignerLiveTest {
public CloudFilesBlobSignerLiveTest(){
public CloudFilesBlobSignerLiveTest() {
provider = "cloudfiles";
}
}

View File

@ -51,12 +51,32 @@ public class ParseContainerCDNMetadataListFromJsonResponseTest {
InputStream is = getClass().getResourceAsStream("/test_list_cdn.json");
Set<ContainerCDNMetadata> expects = ImmutableSortedSet.of(
new ContainerCDNMetadata("adriancole-blobstore.testCDNOperationsContainerWithCDN", false, 3600, URI
.create("http://c0354712.cdn.cloudfiles.rackspacecloud.com")), new ContainerCDNMetadata(
"adriancole-blobstore5", true, 28800, URI.create("http://c0404671.cdn.cloudfiles.rackspacecloud.com")),
new ContainerCDNMetadata("adriancole-cfcdnint.testCDNOperationsContainerWithCDN", false, 3600, URI
.create("http://c0320431.cdn.cloudfiles.rackspacecloud.com")));
new ContainerCDNMetadata(
"adriancole-blobstore.testCDNOperationsContainerWithCDN",
false,
false,
3600,
URI.create("http://c0354712.cdn.cloudfiles.rackspacecloud.com"),
URI.create("https://c0354712.cdn.ssl.cloudfiles.rackspacecloud.com"),
URI.create("http://c0354712.cdn.stream.cloudfiles.rackspacecloud.com")),
new ContainerCDNMetadata(
"adriancole-blobstore5",
true,
false,
28800,
URI.create("http://c0404671.cdn.cloudfiles.rackspacecloud.com"),
URI.create("https://c0404671.cdn.ssl.cloudfiles.rackspacecloud.com"),
URI.create("http://c0404671.cdn.stream.cloudfiles.rackspacecloud.com")),
new ContainerCDNMetadata(
"adriancole-cfcdnint.testCDNOperationsContainerWithCDN",
false,
false,
3600,
URI.create("http://c0320431.cdn.cloudfiles.rackspacecloud.com"),
URI.create("https://c0320431.cdn.ssl.cloudfiles.rackspacecloud.com"),
URI.create("http://c0320431.cdn.stream.cloudfiles.rackspacecloud.com"))
);
ParseJson<SortedSet<ContainerCDNMetadata>> parser = i.getInstance(Key
.get(new TypeLiteral<ParseJson<SortedSet<ContainerCDNMetadata>>>() {
}));

View File

@ -1,5 +1,35 @@
[
{"name":"adriancole-blobstore.testCDNOperationsContainerWithCDN","cdn_enabled":"false","ttl":3600,"cdn_uri":"http://c0354712.cdn.cloudfiles.rackspacecloud.com","referrer_acl":"","useragent_acl":"", "log_retention":"false"},
{"name":"adriancole-blobstore5","cdn_enabled":"true","ttl":28800,"cdn_uri":"http://c0404671.cdn.cloudfiles.rackspacecloud.com","referrer_acl":"","useragent_acl":"", "log_retention":"false"},
{"name":"adriancole-cfcdnint.testCDNOperationsContainerWithCDN","cdn_enabled":"false","ttl":3600,"cdn_uri":"http://c0320431.cdn.cloudfiles.rackspacecloud.com","referrer_acl":"","useragent_acl":"", "log_retention":"false"}
{
"name":"adriancole-blobstore.testCDNOperationsContainerWithCDN",
"cdn_enabled":"false",
"log_retention":"false",
"ttl":3600,
"cdn_uri":"http://c0354712.cdn.cloudfiles.rackspacecloud.com",
"cdn_ssl_uri":"https://c0354712.cdn.ssl.cloudfiles.rackspacecloud.com",
"cdn_streaming_uri":"http://c0354712.cdn.stream.cloudfiles.rackspacecloud.com",
"referrer_acl":"",
"useragent_acl":""
},
{
"name":"adriancole-blobstore5",
"cdn_enabled":"true",
"log_retention":"false",
"ttl":28800,
"cdn_uri":"http://c0404671.cdn.cloudfiles.rackspacecloud.com",
"cdn_ssl_uri":"https://c0404671.cdn.ssl.cloudfiles.rackspacecloud.com",
"cdn_streaming_uri":"http://c0404671.cdn.stream.cloudfiles.rackspacecloud.com",
"referrer_acl":"",
"useragent_acl":""
},
{
"name":"adriancole-cfcdnint.testCDNOperationsContainerWithCDN",
"cdn_enabled":"false",
"log_retention":"false",
"ttl":3600,
"cdn_uri":"http://c0320431.cdn.cloudfiles.rackspacecloud.com",
"cdn_ssl_uri":"https://c0320431.cdn.ssl.cloudfiles.rackspacecloud.com",
"cdn_streaming_uri":"http://c0320431.cdn.stream.cloudfiles.rackspacecloud.com",
"referrer_acl":"",
"useragent_acl":""
}
]

View File

@ -25,12 +25,13 @@ import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
/**
* @author Adrian Cole
*/
@Test(groups = "live")
@Test(groups = "live", testName = "CloudSigmaComputeServiceLiveTest")
public class CloudSigmaComputeServiceLiveTest extends BaseComputeServiceLiveTest {
public CloudSigmaComputeServiceLiveTest() {
@ -46,14 +47,21 @@ public class CloudSigmaComputeServiceLiveTest extends BaseComputeServiceLiveTest
@Override
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
"node userMetadata did not match %s %s", userMetadata, node);
"node userMetadata did not match %s %s", userMetadata, node);
}
// cloudsigma does not support tags
@Override
protected void checkTagsInNodeEquals(final NodeMetadata node, final ImmutableSet<String> tags) {
assert node.getTags().equals(ImmutableSet.<String> of()) : String.format("node tags did not match %s %s", tags,
node);
}
protected void checkResponseEqualsHostname(ExecResponse execResponse, NodeMetadata node1) {
// hostname is not predictable based on node metadata
assert execResponse.getOutput().trim().equals("ubuntu");
}
@Override
public void testOptionToNotBlock() {
// start call has to block until we have a pool of reserved pre-cloned drives.

View File

@ -23,6 +23,7 @@ import java.util.Properties;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.cloudstack.compute.config.CloudStackComputeServiceContextModule;
import org.jclouds.cloudstack.config.CloudStackParserModule;
import org.jclouds.cloudstack.config.CloudStackRestClientModule;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.internal.BaseRestApiMetadata;
@ -91,7 +92,10 @@ public class CloudStackApiMetadata extends BaseRestApiMetadata {
.version("2.2")
.view(TypeToken.of(CloudStackContext.class))
.defaultProperties(CloudStackApiMetadata.defaultProperties())
.defaultModules(ImmutableSet.<Class<? extends Module>>of(CloudStackRestClientModule.class, CloudStackComputeServiceContextModule.class));
.defaultModules(ImmutableSet.<Class<? extends Module>> builder()
.add(CloudStackParserModule.class)
.add(CloudStackRestClientModule.class)
.add(CloudStackComputeServiceContextModule.class).build());
}
@Override

View File

@ -0,0 +1,115 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.config;
import java.io.IOException;
import java.util.Date;
import javax.inject.Inject;
import org.jclouds.date.DateService;
import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.json.internal.IgnoreNullIterableTypeAdapterFactory;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableSet;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.google.inject.AbstractModule;
/**
* @author Adrian Cole
*/
public class CloudStackParserModule extends AbstractModule {
@Override
protected void configure() {
bind(DateAdapter.class).to(CloudStackDateAdapter.class);
bind(IgnoreNullIterableTypeAdapterFactory.class).to(CommaDelimitedOKIgnoreNullIterableTypeAdapterFactory.class);
}
/**
* Data adapter for the date formats used by CloudStack.
*
* Essentially this is a workaround for the CloudStack getUsage() API call returning a corrupted
* form of ISO-8601 dates, which have an unexpected pair of apostrophes, like
* 2011-12-12'T'00:00:00+00:00
*
* @author Richard Downer
*/
public static class CloudStackDateAdapter extends Iso8601DateAdapter {
@Inject
private CloudStackDateAdapter(DateService dateService) {
super(dateService);
}
public Date read(JsonReader reader) throws IOException {
return parseDate(reader.nextString().replaceAll("'T'", "T"));
}
}
/**
* Handles types that were previously strings and now arrays (ex. tags)
*
* @author Adrian Cole
*/
public static class CommaDelimitedOKIgnoreNullIterableTypeAdapterFactory extends IgnoreNullIterableTypeAdapterFactory {
@Override
protected <E> TypeAdapter<Iterable<E>> newIterableAdapter(final TypeAdapter<E> elementAdapter) {
return new TypeAdapter<Iterable<E>>() {
public void write(JsonWriter out, Iterable<E> value) throws IOException {
out.beginArray();
for (E element : value) {
elementAdapter.write(out, element);
}
out.endArray();
}
@SuppressWarnings("unchecked")
public Iterable<E> read(JsonReader in) throws IOException {
// HACK as cloudstack changed a field from String to Set!
if (in.peek() == JsonToken.STRING) {
String val = Strings.emptyToNull(in.nextString());
return (Iterable<E>) (val != null ? Splitter.on(',').split(val) : ImmutableSet.of());
} else {
Builder<E> builder = ImmutableList.<E> builder();
in.beginArray();
while (in.hasNext()) {
E element = elementAdapter.read(in);
if (element != null)
builder.add(element);
}
in.endArray();
return builder.build();
}
}
}.nullSafe();
}
}
}

View File

@ -33,7 +33,86 @@ import org.jclouds.cloudstack.CloudStackDomainClient;
import org.jclouds.cloudstack.CloudStackGlobalAsyncClient;
import org.jclouds.cloudstack.CloudStackGlobalClient;
import org.jclouds.cloudstack.domain.LoginResponse;
import org.jclouds.cloudstack.features.*;
import org.jclouds.cloudstack.features.AccountAsyncClient;
import org.jclouds.cloudstack.features.AccountClient;
import org.jclouds.cloudstack.features.AddressAsyncClient;
import org.jclouds.cloudstack.features.AddressClient;
import org.jclouds.cloudstack.features.AsyncJobAsyncClient;
import org.jclouds.cloudstack.features.AsyncJobClient;
import org.jclouds.cloudstack.features.ConfigurationAsyncClient;
import org.jclouds.cloudstack.features.ConfigurationClient;
import org.jclouds.cloudstack.features.DomainAccountAsyncClient;
import org.jclouds.cloudstack.features.DomainAccountClient;
import org.jclouds.cloudstack.features.DomainDomainAsyncClient;
import org.jclouds.cloudstack.features.DomainDomainClient;
import org.jclouds.cloudstack.features.DomainLimitAsyncClient;
import org.jclouds.cloudstack.features.DomainLimitClient;
import org.jclouds.cloudstack.features.DomainUserAsyncClient;
import org.jclouds.cloudstack.features.DomainUserClient;
import org.jclouds.cloudstack.features.EventAsyncClient;
import org.jclouds.cloudstack.features.EventClient;
import org.jclouds.cloudstack.features.FirewallAsyncClient;
import org.jclouds.cloudstack.features.FirewallClient;
import org.jclouds.cloudstack.features.GlobalAccountAsyncClient;
import org.jclouds.cloudstack.features.GlobalAccountClient;
import org.jclouds.cloudstack.features.GlobalAlertAsyncClient;
import org.jclouds.cloudstack.features.GlobalAlertClient;
import org.jclouds.cloudstack.features.GlobalCapacityAsyncClient;
import org.jclouds.cloudstack.features.GlobalCapacityClient;
import org.jclouds.cloudstack.features.GlobalConfigurationAsyncClient;
import org.jclouds.cloudstack.features.GlobalConfigurationClient;
import org.jclouds.cloudstack.features.GlobalDomainAsyncClient;
import org.jclouds.cloudstack.features.GlobalDomainClient;
import org.jclouds.cloudstack.features.GlobalHostAsyncClient;
import org.jclouds.cloudstack.features.GlobalHostClient;
import org.jclouds.cloudstack.features.GlobalOfferingAsyncClient;
import org.jclouds.cloudstack.features.GlobalOfferingClient;
import org.jclouds.cloudstack.features.GlobalPodAsyncClient;
import org.jclouds.cloudstack.features.GlobalPodClient;
import org.jclouds.cloudstack.features.GlobalStoragePoolAsyncClient;
import org.jclouds.cloudstack.features.GlobalStoragePoolClient;
import org.jclouds.cloudstack.features.GlobalUsageAsyncClient;
import org.jclouds.cloudstack.features.GlobalUsageClient;
import org.jclouds.cloudstack.features.GlobalUserAsyncClient;
import org.jclouds.cloudstack.features.GlobalUserClient;
import org.jclouds.cloudstack.features.GlobalVlanAsyncClient;
import org.jclouds.cloudstack.features.GlobalVlanClient;
import org.jclouds.cloudstack.features.GlobalZoneAsyncClient;
import org.jclouds.cloudstack.features.GlobalZoneClient;
import org.jclouds.cloudstack.features.GuestOSAsyncClient;
import org.jclouds.cloudstack.features.GuestOSClient;
import org.jclouds.cloudstack.features.HypervisorAsyncClient;
import org.jclouds.cloudstack.features.HypervisorClient;
import org.jclouds.cloudstack.features.ISOAsyncClient;
import org.jclouds.cloudstack.features.ISOClient;
import org.jclouds.cloudstack.features.LimitAsyncClient;
import org.jclouds.cloudstack.features.LimitClient;
import org.jclouds.cloudstack.features.LoadBalancerAsyncClient;
import org.jclouds.cloudstack.features.LoadBalancerClient;
import org.jclouds.cloudstack.features.NATAsyncClient;
import org.jclouds.cloudstack.features.NATClient;
import org.jclouds.cloudstack.features.NetworkAsyncClient;
import org.jclouds.cloudstack.features.NetworkClient;
import org.jclouds.cloudstack.features.OfferingAsyncClient;
import org.jclouds.cloudstack.features.OfferingClient;
import org.jclouds.cloudstack.features.SSHKeyPairAsyncClient;
import org.jclouds.cloudstack.features.SSHKeyPairClient;
import org.jclouds.cloudstack.features.SecurityGroupAsyncClient;
import org.jclouds.cloudstack.features.SecurityGroupClient;
import org.jclouds.cloudstack.features.SessionAsyncClient;
import org.jclouds.cloudstack.features.SessionClient;
import org.jclouds.cloudstack.features.SnapshotAsyncClient;
import org.jclouds.cloudstack.features.SnapshotClient;
import org.jclouds.cloudstack.features.TemplateAsyncClient;
import org.jclouds.cloudstack.features.TemplateClient;
import org.jclouds.cloudstack.features.VMGroupAsyncClient;
import org.jclouds.cloudstack.features.VMGroupClient;
import org.jclouds.cloudstack.features.VirtualMachineAsyncClient;
import org.jclouds.cloudstack.features.VirtualMachineClient;
import org.jclouds.cloudstack.features.VolumeAsyncClient;
import org.jclouds.cloudstack.features.VolumeClient;
import org.jclouds.cloudstack.features.ZoneAsyncClient;
import org.jclouds.cloudstack.features.ZoneClient;
import org.jclouds.cloudstack.filters.AddSessionKeyAndJSessionIdToRequest;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.filters.QuerySigner;
@ -47,7 +126,6 @@ import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.location.Provider;
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstZone;
@ -147,7 +225,6 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
@Override
protected void configure() {
bind(DateAdapter.class).to(CloudStackDateAdapter.class);
bind(new TypeLiteral<RestContext<CloudStackDomainClient, CloudStackDomainAsyncClient>>() {
}).to(new TypeLiteral<RestContextImpl<CloudStackDomainClient, CloudStackDomainAsyncClient>>() {
});

View File

@ -22,11 +22,13 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import java.util.Date;
import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ImmutableSet;
/**
* Class DiskOffering
@ -54,7 +56,7 @@ public class DiskOffering implements Comparable<DiskOffering> {
protected String domainId;
protected int diskSize;
protected boolean customized;
protected String tags;
protected ImmutableSet.Builder<String> tags = ImmutableSet.<String>builder();
/**
* @see DiskOffering#getId()
@ -123,13 +125,21 @@ public class DiskOffering implements Comparable<DiskOffering> {
/**
* @see DiskOffering#getTags()
*/
public T tags(String tags) {
this.tags = tags;
public T tags(Iterable<String> tags) {
this.tags = ImmutableSet.<String>builder().addAll(tags);
return self();
}
/**
* @see DiskOffering#getTags()
*/
public T tag(String tag) {
this.tags.add(tag);
return self();
}
public DiskOffering build() {
return new DiskOffering(id, name, displayText, created, domain, domainId, diskSize, customized, tags);
return new DiskOffering(id, name, displayText, created, domain, domainId, diskSize, customized, tags.build());
}
public T fromDiskOffering(DiskOffering in) {
@ -161,14 +171,14 @@ public class DiskOffering implements Comparable<DiskOffering> {
private final String domainId;
private final int diskSize;
private final boolean customized;
private final String tags;
private final Set<String> tags;
@ConstructorProperties({
"id", "name", "displaytext", "created", "domain", "domainid", "disksize", "iscustomized", "tags"
})
protected DiskOffering(String id, @Nullable String name, @Nullable String displayText, @Nullable Date created,
@Nullable String domain, @Nullable String domainId, int diskSize, boolean customized,
@Nullable String tags) {
@Nullable Iterable<String> tags) {
this.id = checkNotNull(id, "id");
this.name = name;
this.displayText = displayText;
@ -177,7 +187,7 @@ public class DiskOffering implements Comparable<DiskOffering> {
this.domainId = domainId;
this.diskSize = diskSize;
this.customized = customized;
this.tags = tags;
this.tags = tags != null ? ImmutableSet.copyOf(tags) : ImmutableSet.<String> of();
}
/**
@ -244,8 +254,7 @@ public class DiskOffering implements Comparable<DiskOffering> {
/**
* @return the tags for the disk offering
*/
@Nullable
public String getTags() {
public Set<String> getTags() {
return this.tags;
}

View File

@ -24,11 +24,13 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import java.util.Date;
import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ImmutableSet;
/**
* Represents a host issued by Cloudstack
@ -149,7 +151,7 @@ public class Host implements Comparable<Host> {
protected long diskSizeTotal;
protected String events;
protected boolean hasEnoughCapacity;
protected String hostTags;
protected ImmutableSet.Builder<String> tags = ImmutableSet.<String>builder();
protected String hypervisor;
protected String ipAddress;
protected boolean localStorageActive;
@ -319,13 +321,21 @@ public class Host implements Comparable<Host> {
}
/**
* @see Host#getHostTags()
* @see Host#getTags()
*/
public T hostTags(String hostTags) {
this.hostTags = hostTags;
public T tags(Iterable<String> tags) {
this.tags = ImmutableSet.<String>builder().addAll(tags);
return self();
}
/**
* @see Host#getTags()
*/
public T tag(String tag) {
this.tags.add(tag);
return self();
}
/**
* @see Host#getHypervisor()
*/
@ -512,7 +522,7 @@ public class Host implements Comparable<Host> {
public Host build() {
return new Host(id, allocationState, averageLoad, capabilities, clusterId, clusterName, clusterType, cpuAllocated, cpuNumber, cpuSpeed, cpuUsed, cpuWithOverProvisioning, created, disconnected, diskSizeAllocated, diskSizeTotal, events, hasEnoughCapacity, hostTags, hypervisor, ipAddress, localStorageActive, jobId, jobStatus, lastPinged, managementServerId, memoryAllocated, memoryTotal, memoryUsed, name, networkKbsRead, networkKbsWrite, osCategoryId, osCategoryName, podId, podName, removed, state, type, version, zoneId, zoneName);
return new Host(id, allocationState, averageLoad, capabilities, clusterId, clusterName, clusterType, cpuAllocated, cpuNumber, cpuSpeed, cpuUsed, cpuWithOverProvisioning, created, disconnected, diskSizeAllocated, diskSizeTotal, events, hasEnoughCapacity, tags.build(), hypervisor, ipAddress, localStorageActive, jobId, jobStatus, lastPinged, managementServerId, memoryAllocated, memoryTotal, memoryUsed, name, networkKbsRead, networkKbsWrite, osCategoryId, osCategoryName, podId, podName, removed, state, type, version, zoneId, zoneName);
}
public T fromHost(Host in) {
@ -535,7 +545,7 @@ public class Host implements Comparable<Host> {
.diskSizeTotal(in.getDiskSizeTotal())
.events(in.getEvents())
.hasEnoughCapacity(in.isHasEnoughCapacity())
.hostTags(in.getHostTags())
.tags(in.getTags())
.hypervisor(in.getHypervisor())
.ipAddress(in.getIpAddress())
.localStorageActive(in.isLocalStorageActive())
@ -587,7 +597,7 @@ public class Host implements Comparable<Host> {
private final long diskSizeTotal;
private final String events;
private final boolean hasEnoughCapacity;
private final String hostTags;
private final Set<String> tags;
private final String hypervisor;
private final String ipAddress;
private final boolean localStorageActive;
@ -619,7 +629,7 @@ public class Host implements Comparable<Host> {
@Nullable String clusterId, @Nullable String clusterName, @Nullable Host.ClusterType clusterType,
@Nullable String cpuAllocated, int cpuNumber, int cpuSpeed, @Nullable String cpuUsed,
float cpuWithOverProvisioning, @Nullable Date created, @Nullable Date disconnected, long diskSizeAllocated,
long diskSizeTotal, @Nullable String events, boolean hasEnoughCapacity, @Nullable String hostTags,
long diskSizeTotal, @Nullable String events, boolean hasEnoughCapacity, @Nullable Iterable<String> tags,
@Nullable String hypervisor, @Nullable String ipAddress, boolean localStorageActive, @Nullable String jobId,
@Nullable AsyncJob.Status jobStatus, @Nullable Date lastPinged, @Nullable String managementServerId,
long memoryAllocated, long memoryTotal, long memoryUsed, @Nullable String name, long networkKbsRead, long networkKbsWrite,
@ -644,7 +654,7 @@ public class Host implements Comparable<Host> {
this.diskSizeTotal = diskSizeTotal;
this.events = events;
this.hasEnoughCapacity = hasEnoughCapacity;
this.hostTags = hostTags;
this.tags = tags != null ? ImmutableSet.copyOf(tags) : ImmutableSet.<String> of();
this.hypervisor = hypervisor;
this.ipAddress = ipAddress;
this.localStorageActive = localStorageActive;
@ -752,11 +762,14 @@ public class Host implements Comparable<Host> {
return this.hasEnoughCapacity;
}
@Nullable
public String getHostTags() {
return this.hostTags;
/**
* @return the tags for the host
*/
public Set<String> getTags() {
return this.tags;
}
@Nullable
public String getHypervisor() {
return this.hypervisor;
@ -868,7 +881,7 @@ public class Host implements Comparable<Host> {
@Override
public int hashCode() {
return Objects.hashCode(id, allocationState, averageLoad, capabilities, clusterId, clusterName, clusterType, cpuAllocated, cpuNumber, cpuSpeed, cpuUsed, cpuWithOverProvisioning, created, disconnected, diskSizeAllocated, diskSizeTotal, events, hasEnoughCapacity, hostTags, hypervisor, ipAddress, localStorageActive, jobId, jobStatus, lastPinged, managementServerId, memoryAllocated, memoryTotal, memoryUsed, name, networkKbsRead, networkKbsWrite, osCategoryId, osCategoryName, podId, podName, removed, state, type, version, zoneId, zoneName);
return Objects.hashCode(id, allocationState, averageLoad, capabilities, clusterId, clusterName, clusterType, cpuAllocated, cpuNumber, cpuSpeed, cpuUsed, cpuWithOverProvisioning, created, disconnected, diskSizeAllocated, diskSizeTotal, events, hasEnoughCapacity, tags, hypervisor, ipAddress, localStorageActive, jobId, jobStatus, lastPinged, managementServerId, memoryAllocated, memoryTotal, memoryUsed, name, networkKbsRead, networkKbsWrite, osCategoryId, osCategoryName, podId, podName, removed, state, type, version, zoneId, zoneName);
}
@Override
@ -894,7 +907,7 @@ public class Host implements Comparable<Host> {
&& Objects.equal(this.diskSizeTotal, that.diskSizeTotal)
&& Objects.equal(this.events, that.events)
&& Objects.equal(this.hasEnoughCapacity, that.hasEnoughCapacity)
&& Objects.equal(this.hostTags, that.hostTags)
&& Objects.equal(this.tags, that.tags)
&& Objects.equal(this.hypervisor, that.hypervisor)
&& Objects.equal(this.ipAddress, that.ipAddress)
&& Objects.equal(this.localStorageActive, that.localStorageActive)
@ -928,7 +941,7 @@ public class Host implements Comparable<Host> {
.add("cpuSpeed", cpuSpeed).add("cpuUsed", cpuUsed).add("cpuWithOverProvisioning", cpuWithOverProvisioning)
.add("created", created).add("disconnected", disconnected).add("diskSizeAllocated", diskSizeAllocated)
.add("diskSizeTotal", diskSizeTotal).add("events", events).add("hasEnoughCapacity", hasEnoughCapacity)
.add("hostTags", hostTags).add("hypervisor", hypervisor).add("ipAddress", ipAddress)
.add("tags", tags).add("hypervisor", hypervisor).add("ipAddress", ipAddress)
.add("localStorageActive", localStorageActive).add("jobId", jobId).add("jobStatus", jobStatus)
.add("lastPinged", lastPinged).add("managementServerId", managementServerId).add("memoryAllocated", memoryAllocated)
.add("memoryTotal", memoryTotal).add("memoryUsed", memoryUsed).add("name", name).add("networkKbsRead", networkKbsRead)

View File

@ -30,6 +30,7 @@ import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
/**
@ -78,7 +79,7 @@ public class Network {
protected String VLAN;
protected TrafficType trafficType;
protected String zoneId;
protected String tags;
protected ImmutableSet.Builder<String> tags = ImmutableSet.<String>builder();
protected boolean securityGroupEnabled;
protected Set<? extends NetworkService> services = ImmutableSortedSet.of();
@ -302,10 +303,19 @@ public class Network {
/**
* @see Network#getTags()
*/
public T tags(String tags) {
this.tags = tags;
public T tags(Iterable<String> tags) {
this.tags = ImmutableSet.<String>builder().addAll(tags);
return self();
}
/**
* @see Network#getTags()
*/
public T tag(String tag) {
this.tags.add(tag);
return self();
}
/**
* @see Network#isSecurityGroupEnabled()
@ -324,7 +334,7 @@ public class Network {
}
public Network build() {
return new Network(id, account, broadcastDomainType, broadcastURI, displayText, DNS1, DNS2, domain, domainId, endIP, gateway, isDefault, isShared, isSystem, netmask, networkDomain, networkOfferingAvailability, networkOfferingDisplayText, networkOfferingId, networkOfferingName, related, startIP, name, state, guestIPType, VLAN, trafficType, zoneId, tags, securityGroupEnabled, services);
return new Network(id, account, broadcastDomainType, broadcastURI, displayText, DNS1, DNS2, domain, domainId, endIP, gateway, isDefault, isShared, isSystem, netmask, networkDomain, networkOfferingAvailability, networkOfferingDisplayText, networkOfferingId, networkOfferingName, related, startIP, name, state, guestIPType, VLAN, trafficType, zoneId, tags.build(), securityGroupEnabled, services);
}
public T fromNetwork(Network in) {
@ -397,7 +407,7 @@ public class Network {
private final String VLAN;
private final TrafficType trafficType;
private final String zoneId;
private final String tags;
private final Set<String> tags;
private final boolean securityGroupEnabled;
private final Set<? extends NetworkService> services;
@ -411,7 +421,7 @@ public class Network {
@Nullable String networkOfferingDisplayText, @Nullable String networkOfferingId, @Nullable String networkOfferingName,
@Nullable String related, @Nullable String startIP, @Nullable String name, @Nullable String state,
@Nullable GuestIPType guestIPType, @Nullable String VLAN, @Nullable TrafficType trafficType,
@Nullable String zoneId, @Nullable String tags, boolean securityGroupEnabled, Set<? extends NetworkService> services) {
@Nullable String zoneId, @Nullable Iterable<String> tags, boolean securityGroupEnabled, Set<? extends NetworkService> services) {
this.id = checkNotNull(id, "id");
this.account = account;
this.broadcastDomainType = broadcastDomainType;
@ -440,7 +450,7 @@ public class Network {
this.VLAN = VLAN;
this.trafficType = trafficType;
this.zoneId = zoneId;
this.tags = tags;
this.tags = tags != null ? ImmutableSet.copyOf(tags) : ImmutableSet.<String> of();
this.securityGroupEnabled = securityGroupEnabled;
this.services = ImmutableSortedSet.copyOf(services);
}
@ -660,8 +670,7 @@ public class Network {
/**
* @return the tags for the Network
*/
@Nullable
public String getTags() {
public Set<String> getTags() {
return this.tags;
}

View File

@ -22,11 +22,13 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import java.util.Date;
import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ImmutableSet;
/**
* Class NetworkOffering
@ -57,7 +59,7 @@ public class NetworkOffering implements Comparable<NetworkOffering> {
protected TrafficType trafficType;
protected GuestIPType guestIPType;
protected int networkRate;
protected String tags;
protected ImmutableSet.Builder<String> tags = ImmutableSet.<String>builder();
/**
* @see NetworkOffering#getId()
@ -146,17 +148,26 @@ public class NetworkOffering implements Comparable<NetworkOffering> {
this.networkRate = networkRate;
return self();
}
/**
* @see NetworkOffering#getTags()
*/
public T tags(String tags) {
this.tags = tags;
public T tags(Iterable<String> tags) {
this.tags = ImmutableSet.<String>builder().addAll(tags);
return self();
}
/**
* @see NetworkOffering#getTags()
*/
public T tag(String tag) {
this.tags.add(tag);
return self();
}
public NetworkOffering build() {
return new NetworkOffering(id, name, displayText, created, availability, maxConnections, isDefault, supportsVLAN, trafficType, guestIPType, networkRate, tags);
return new NetworkOffering(id, name, displayText, created, availability, maxConnections, isDefault, supportsVLAN, trafficType, guestIPType, networkRate, tags.build());
}
public T fromNetworkOffering(NetworkOffering in) {
@ -194,12 +205,12 @@ public class NetworkOffering implements Comparable<NetworkOffering> {
private final TrafficType trafficType;
private final GuestIPType guestIPType;
private final int networkRate;
private final String tags;
private final Set<String> tags;
@ConstructorProperties({
"id", "name", "displaytext", "created", "availability", "maxconnections", "isdefault", "specifyvlan", "traffictype", "guestiptype", "networkrate", "tags"
})
protected NetworkOffering(String id, @Nullable String name, @Nullable String displayText, @Nullable Date created, @Nullable NetworkOfferingAvailabilityType availability, @Nullable Integer maxConnections, boolean isDefault, boolean supportsVLAN, @Nullable TrafficType trafficType, @Nullable GuestIPType guestIPType, int networkRate, @Nullable String tags) {
protected NetworkOffering(String id, @Nullable String name, @Nullable String displayText, @Nullable Date created, @Nullable NetworkOfferingAvailabilityType availability, @Nullable Integer maxConnections, boolean isDefault, boolean supportsVLAN, @Nullable TrafficType trafficType, @Nullable GuestIPType guestIPType, int networkRate, @Nullable Iterable<String> tags) {
this.id = checkNotNull(id, "id");
this.name = name;
this.displayText = displayText;
@ -211,7 +222,7 @@ public class NetworkOffering implements Comparable<NetworkOffering> {
this.trafficType = trafficType;
this.guestIPType = guestIPType;
this.networkRate = networkRate;
this.tags = tags;
this.tags = tags != null ? ImmutableSet.copyOf(tags) : ImmutableSet.<String> of();
}
/**
@ -302,8 +313,7 @@ public class NetworkOffering implements Comparable<NetworkOffering> {
/**
* @return the tags for the network offering
*/
@Nullable
public String getTags() {
public Set<String> getTags() {
return this.tags;
}

View File

@ -26,11 +26,8 @@ import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
/**
@ -63,12 +60,11 @@ public class ServiceOffering implements Comparable<ServiceOffering> {
protected boolean haSupport;
protected StorageType storageType;
protected boolean defaultUse;
protected String hostTags;
protected boolean systemOffering;
protected boolean cpuUseLimited;
protected long networkRate;
protected boolean systemVmType;
private Set<String> tags = ImmutableSet.of();
protected ImmutableSet.Builder<String> tags = ImmutableSet.<String>builder();
/**
* @see ServiceOffering#getId()
@ -161,11 +157,19 @@ public class ServiceOffering implements Comparable<ServiceOffering> {
/**
* @see ServiceOffering#getTags()
*/
public T tags(Set<String> tags) {
this.tags = ImmutableSet.copyOf(checkNotNull(tags, "tags"));
public T tags(Iterable<String> tags) {
this.tags = ImmutableSet.<String>builder().addAll(tags);
return self();
}
/**
* @see ServiceOffering#getTags()
*/
public T tag(String tag) {
this.tags.add(tag);
return self();
}
/**
* @see ServiceOffering#isDefaultUse()
*/
@ -174,14 +178,6 @@ public class ServiceOffering implements Comparable<ServiceOffering> {
return self();
}
/**
* @see ServiceOffering#getHostTags()
*/
public T hostTags(String hostTags) {
this.hostTags = hostTags;
return self();
}
/**
* @see ServiceOffering#isSystemOffering()
*/
@ -216,7 +212,7 @@ public class ServiceOffering implements Comparable<ServiceOffering> {
public ServiceOffering build() {
return new ServiceOffering(id, name, displayText, created, domain, domainId, cpuNumber, cpuSpeed, memory, haSupport, storageType,
Joiner.on(",").join(tags), defaultUse, hostTags, systemOffering, cpuUseLimited, networkRate, systemVmType);
tags.build(), defaultUse, systemOffering, cpuUseLimited, networkRate, systemVmType);
}
public T fromServiceOffering(ServiceOffering in) {
@ -234,7 +230,6 @@ public class ServiceOffering implements Comparable<ServiceOffering> {
.storageType(in.getStorageType())
.tags(in.getTags())
.defaultUse(in.isDefaultUse())
.hostTags(in.getHostTags())
.systemOffering(in.isSystemOffering())
.cpuUseLimited(in.isCpuUseLimited())
.networkRate(in.getNetworkRate())
@ -262,19 +257,18 @@ public class ServiceOffering implements Comparable<ServiceOffering> {
private final StorageType storageType;
private final Set<String> tags;
private final boolean defaultUse;
private final String hostTags;
private final boolean systemOffering;
private final boolean cpuUseLimited;
private final long networkRate;
private final boolean systemVmType;
@ConstructorProperties({
"id", "name", "displaytext", "created", "domain", "domainid", "cpunumber", "cpuspeed", "memory", "offerha", "storagetype", "tags", "defaultuse", "hosttags", "issystem", "limitcpuuse", "networkrate", "systemvmtype"
"id", "name", "displaytext", "created", "domain", "domainid", "cpunumber", "cpuspeed", "memory", "offerha", "storagetype", "tags", "defaultuse", "issystem", "limitcpuuse", "networkrate", "systemvmtype"
})
protected ServiceOffering(String id, @Nullable String name, @Nullable String displayText, @Nullable Date created,
@Nullable String domain, @Nullable String domainId, int cpuNumber, int cpuSpeed, int memory,
boolean haSupport, @Nullable StorageType storageType, @Nullable String tags, boolean defaultUse,
@Nullable String hostTags, boolean systemOffering, boolean cpuUseLimited, long networkRate, boolean systemVmType) {
boolean haSupport, @Nullable StorageType storageType, @Nullable Iterable<String> tags, boolean defaultUse,
boolean systemOffering, boolean cpuUseLimited, long networkRate, boolean systemVmType) {
this.id = checkNotNull(id, "id");
this.name = name;
this.displayText = displayText;
@ -286,10 +280,8 @@ public class ServiceOffering implements Comparable<ServiceOffering> {
this.memory = memory;
this.haSupport = haSupport;
this.storageType = storageType;
this.tags = !(Strings.emptyToNull(tags) == null) ? ImmutableSet.copyOf(Splitter.on(',').split(tags))
: ImmutableSet.<String> of();
this.tags = tags != null ? ImmutableSet.copyOf(tags) : ImmutableSet.<String> of();
this.defaultUse = defaultUse;
this.hostTags = hostTags;
this.systemOffering = systemOffering;
this.cpuUseLimited = cpuUseLimited;
this.networkRate = networkRate;
@ -389,14 +381,6 @@ public class ServiceOffering implements Comparable<ServiceOffering> {
return this.defaultUse;
}
/**
* @return the host tag for the service offering
*/
@Nullable
public String getHostTags() {
return this.hostTags;
}
/**
* @return whether this is a system vm offering
*/
@ -427,7 +411,7 @@ public class ServiceOffering implements Comparable<ServiceOffering> {
@Override
public int hashCode() {
return Objects.hashCode(id, name, displayText, created, domain, domainId, cpuNumber, cpuSpeed, memory, haSupport, storageType, tags, defaultUse, hostTags, systemOffering, cpuUseLimited, networkRate, systemVmType);
return Objects.hashCode(id, name, displayText, created, domain, domainId, cpuNumber, cpuSpeed, memory, haSupport, storageType, tags, defaultUse, systemOffering, cpuUseLimited, networkRate, systemVmType);
}
@Override
@ -448,7 +432,6 @@ public class ServiceOffering implements Comparable<ServiceOffering> {
&& Objects.equal(this.storageType, that.storageType)
&& Objects.equal(this.getTags(), that.getTags())
&& Objects.equal(this.defaultUse, that.defaultUse)
&& Objects.equal(this.hostTags, that.hostTags)
&& Objects.equal(this.systemOffering, that.systemOffering)
&& Objects.equal(this.cpuUseLimited, that.cpuUseLimited)
&& Objects.equal(this.networkRate, that.networkRate)
@ -460,7 +443,7 @@ public class ServiceOffering implements Comparable<ServiceOffering> {
.add("id", id).add("name", name).add("displayText", displayText).add("created", created).add("domain", domain)
.add("domainId", domainId).add("cpuNumber", cpuNumber).add("cpuSpeed", cpuSpeed).add("memory", memory)
.add("haSupport", haSupport).add("storageType", storageType).add("tags", getTags()).add("defaultUse", defaultUse)
.add("hostTags", hostTags).add("systemOffering", systemOffering).add("cpuUseLimited", cpuUseLimited)
.add("systemOffering", systemOffering).add("cpuUseLimited", cpuUseLimited)
.add("networkRate", networkRate).add("systemVmType", systemVmType);
}

View File

@ -22,12 +22,14 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import java.util.Date;
import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.CaseFormat;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ImmutableSet;
/**
* Represents a storage pool in CloudStack
@ -102,7 +104,7 @@ public class StoragePool implements Comparable<StoragePool> {
protected String id;
protected String name;
protected String path;
protected String tags;
protected ImmutableSet.Builder<String> tags = ImmutableSet.<String>builder();
protected StoragePool.State state;
protected StoragePool.Type type;
protected String zoneId;
@ -143,10 +145,18 @@ public class StoragePool implements Comparable<StoragePool> {
}
/**
* @see StoragePool#getTags()
* @see DiskOffering#getTags()
*/
public T tags(String tags) {
this.tags = tags;
public T tags(Iterable<String> tags) {
this.tags = ImmutableSet.<String>builder().addAll(tags);
return self();
}
/**
* @see DiskOffering#getTags()
*/
public T tag(String tag) {
this.tags.add(tag);
return self();
}
@ -263,7 +273,7 @@ public class StoragePool implements Comparable<StoragePool> {
}
public StoragePool build() {
return new StoragePool(id, name, path, tags, state, type, zoneId, zoneName, podId, podName, clusterId, clusterName, created, diskSizeAllocated, diskSizeTotal, ipAddress, jobId, jobStatus);
return new StoragePool(id, name, path, tags.build(), state, type, zoneId, zoneName, podId, podName, clusterId, clusterName, created, diskSizeAllocated, diskSizeTotal, ipAddress, jobId, jobStatus);
}
public T fromStoragePool(StoragePool in) {
@ -299,7 +309,7 @@ public class StoragePool implements Comparable<StoragePool> {
private final String id;
private final String name;
private final String path;
private final String tags;
private final Set<String> tags;
private final StoragePool.State state;
private final StoragePool.Type type;
private final String zoneId;
@ -318,11 +328,15 @@ public class StoragePool implements Comparable<StoragePool> {
@ConstructorProperties({
"id", "name", "path", "tags", "state", "type", "zoneid", "zonename", "podid", "podname", "clusterid", "clustername", "created", "disksizeallocated", "disksizetotal", "ipaddress", "jobid", "jobstatus"
})
protected StoragePool(String id, @Nullable String name, @Nullable String path, @Nullable String tags, @Nullable StoragePool.State state, @Nullable StoragePool.Type type, @Nullable String zoneId, @Nullable String zoneName, @Nullable String podId, @Nullable String podName, @Nullable String clusterId, @Nullable String clusterName, @Nullable Date created, long diskSizeAllocated, long diskSizeTotal, @Nullable String ipAddress, @Nullable String jobId, @Nullable String jobStatus) {
protected StoragePool(String id, @Nullable String name, @Nullable String path, @Nullable Iterable<String> tags,
@Nullable StoragePool.State state, @Nullable StoragePool.Type type, @Nullable String zoneId,
@Nullable String zoneName, @Nullable String podId, @Nullable String podName, @Nullable String clusterId,
@Nullable String clusterName, @Nullable Date created, long diskSizeAllocated, long diskSizeTotal,
@Nullable String ipAddress, @Nullable String jobId, @Nullable String jobStatus) {
this.id = checkNotNull(id, "id");
this.name = name;
this.path = path;
this.tags = tags;
this.tags = tags != null ? ImmutableSet.copyOf(tags) : ImmutableSet.<String> of();
this.state = state;
this.type = type;
this.zoneId = zoneId;
@ -353,8 +367,7 @@ public class StoragePool implements Comparable<StoragePool> {
return this.path;
}
@Nullable
public String getTags() {
public Set<String> getTags() {
return this.tags;
}

View File

@ -65,7 +65,7 @@ public class GlobalHostClientExpectTest extends BaseCloudStackRestClientExpectTe
Date lastPinged = makeDate(1970, Calendar.JANUARY, 16, 0, 54, 43, "GMT+02:00");
Date created = makeDate(2011, Calendar.NOVEMBER, 26, 23, 28, 36, "GMT+02:00");
Host host1 = Host.builder().id("1").name("cs2-xevsrv.alucloud.local").state(Host.State.UP).type(Host.Type.ROUTING).ipAddress("10.26.26.107").zoneId("1").zoneName("Dev Zone 1").podId("1").podName("Dev Pod 1").version("2.2.12.20110928142833").hypervisor("XenServer").cpuNumber(24).cpuSpeed(2266).cpuAllocated("2.76%").cpuUsed("0.1%").cpuWithOverProvisioning(54384.0F).networkKbsRead(4443).networkKbsWrite(15048).memoryTotal(100549733760L).memoryAllocated(3623878656L).memoryUsed(3623878656L).capabilities("xen-3.0-x86_64 , xen-3.0-x86_32p , hvm-3.0-x86_32 , hvm-3.0-x86_32p , hvm-3.0-x86_64").lastPinged(lastPinged).managementServerId("223098941760041").clusterId("1").clusterName("Xen Clust 1").clusterType(Host.ClusterType.CLOUD_MANAGED).localStorageActive(false).created(created).events("PrepareUnmanaged; HypervisorVersionChanged; ManagementServerDown; PingTimeout; AgentDisconnected; MaintenanceRequested; HostDown; AgentConnected; StartAgentRebalance; ShutdownRequested; Ping").hostTags("").hasEnoughCapacity(false).allocationState(AllocationState.ENABLED).build();
Host host1 = Host.builder().id("1").name("cs2-xevsrv.alucloud.local").state(Host.State.UP).type(Host.Type.ROUTING).ipAddress("10.26.26.107").zoneId("1").zoneName("Dev Zone 1").podId("1").podName("Dev Pod 1").version("2.2.12.20110928142833").hypervisor("XenServer").cpuNumber(24).cpuSpeed(2266).cpuAllocated("2.76%").cpuUsed("0.1%").cpuWithOverProvisioning(54384.0F).networkKbsRead(4443).networkKbsWrite(15048).memoryTotal(100549733760L).memoryAllocated(3623878656L).memoryUsed(3623878656L).capabilities("xen-3.0-x86_64 , xen-3.0-x86_32p , hvm-3.0-x86_32 , hvm-3.0-x86_32p , hvm-3.0-x86_64").lastPinged(lastPinged).managementServerId("223098941760041").clusterId("1").clusterName("Xen Clust 1").clusterType(Host.ClusterType.CLOUD_MANAGED).localStorageActive(false).created(created).events("PrepareUnmanaged; HypervisorVersionChanged; ManagementServerDown; PingTimeout; AgentDisconnected; MaintenanceRequested; HostDown; AgentConnected; StartAgentRebalance; ShutdownRequested; Ping").hasEnoughCapacity(false).allocationState(AllocationState.ENABLED).build();
Date disconnected = makeDate(2011, Calendar.NOVEMBER, 26, 23, 33, 38, "GMT+02:00");
lastPinged = makeDate(1970, Calendar.JANUARY, 16, 0, 42, 30, "GMT+02:00");
@ -109,7 +109,7 @@ public class GlobalHostClientExpectTest extends BaseCloudStackRestClientExpectTe
Date lastPinged = makeDate(1970, Calendar.JANUARY, 16, 0, 54, 43, "GMT+02:00");
Date created = makeDate(2011, Calendar.NOVEMBER, 26, 23, 28, 36, "GMT+02:00");
Host expected = Host.builder().id("1").name("cs2-xevsrv.alucloud.local").state(Host.State.UP).type(Host.Type.ROUTING).ipAddress("10.26.26.107").zoneId("1").zoneName("Dev Zone 1").podId("1").podName("Dev Pod 1").version("2.2.12.20110928142833").hypervisor("XenServer").cpuNumber(24).cpuSpeed(2266).cpuAllocated("2.76%").cpuUsed("0.1%").cpuWithOverProvisioning(54384.0F).networkKbsRead(4443).networkKbsWrite(15048).memoryTotal(100549733760L).memoryAllocated(3623878656L).memoryUsed(3623878656L).capabilities("xen-3.0-x86_64 , xen-3.0-x86_32p , hvm-3.0-x86_32 , hvm-3.0-x86_32p , hvm-3.0-x86_64").lastPinged(lastPinged).managementServerId("223098941760041").clusterId("1").clusterName("Xen Clust 1").clusterType(Host.ClusterType.CLOUD_MANAGED).localStorageActive(false).created(created).events("PrepareUnmanaged; HypervisorVersionChanged; ManagementServerDown; PingTimeout; AgentDisconnected; MaintenanceRequested; HostDown; AgentConnected; StartAgentRebalance; ShutdownRequested; Ping").hostTags("").hasEnoughCapacity(false).allocationState(AllocationState.ENABLED).build();
Host expected = Host.builder().id("1").name("cs2-xevsrv.alucloud.local").state(Host.State.UP).type(Host.Type.ROUTING).ipAddress("10.26.26.107").zoneId("1").zoneName("Dev Zone 1").podId("1").podName("Dev Pod 1").version("2.2.12.20110928142833").hypervisor("XenServer").cpuNumber(24).cpuSpeed(2266).cpuAllocated("2.76%").cpuUsed("0.1%").cpuWithOverProvisioning(54384.0F).networkKbsRead(4443).networkKbsWrite(15048).memoryTotal(100549733760L).memoryAllocated(3623878656L).memoryUsed(3623878656L).capabilities("xen-3.0-x86_64 , xen-3.0-x86_32p , hvm-3.0-x86_32 , hvm-3.0-x86_32p , hvm-3.0-x86_64").lastPinged(lastPinged).managementServerId("223098941760041").clusterId("1").clusterName("Xen Clust 1").clusterType(Host.ClusterType.CLOUD_MANAGED).localStorageActive(false).created(created).events("PrepareUnmanaged; HypervisorVersionChanged; ManagementServerDown; PingTimeout; AgentDisconnected; MaintenanceRequested; HostDown; AgentConnected; StartAgentRebalance; ShutdownRequested; Ping").hasEnoughCapacity(false).allocationState(AllocationState.ENABLED).build();
Host actual = requestSendsResponse(request, response).addHost("1", "http://example.com", "XenServer", "fred", "sekrit",
AddHostOptions.Builder.hostTags(Collections.<String>emptySet()).allocationState(AllocationState.ENABLED).clusterId("1").clusterName("Xen Clust 1").podId("1"));
@ -129,7 +129,7 @@ public class GlobalHostClientExpectTest extends BaseCloudStackRestClientExpectTe
Date lastPinged = makeDate(1970, Calendar.JANUARY, 16, 0, 54, 43, "GMT+02:00");
Date created = makeDate(2011, Calendar.NOVEMBER, 26, 23, 28, 36, "GMT+02:00");
Host expected = Host.builder().id("1").name("cs2-xevsrv.alucloud.local").state(Host.State.UP).type(Host.Type.ROUTING).ipAddress("10.26.26.107").zoneId("1").zoneName("Dev Zone 1").podId("1").podName("Dev Pod 1").version("2.2.12.20110928142833").hypervisor("XenServer").cpuNumber(24).cpuSpeed(2266).cpuAllocated("2.76%").cpuUsed("0.1%").cpuWithOverProvisioning(54384.0F).networkKbsRead(4443).networkKbsWrite(15048).memoryTotal(100549733760L).memoryAllocated(3623878656L).memoryUsed(3623878656L).capabilities("xen-3.0-x86_64 , xen-3.0-x86_32p , hvm-3.0-x86_32 , hvm-3.0-x86_32p , hvm-3.0-x86_64").lastPinged(lastPinged).managementServerId("223098941760041").clusterId("1").clusterName("Xen Clust 1").clusterType(Host.ClusterType.CLOUD_MANAGED).localStorageActive(false).created(created).events("PrepareUnmanaged; HypervisorVersionChanged; ManagementServerDown; PingTimeout; AgentDisconnected; MaintenanceRequested; HostDown; AgentConnected; StartAgentRebalance; ShutdownRequested; Ping").hostTags("").hasEnoughCapacity(false).allocationState(AllocationState.ENABLED).build();
Host expected = Host.builder().id("1").name("cs2-xevsrv.alucloud.local").state(Host.State.UP).type(Host.Type.ROUTING).ipAddress("10.26.26.107").zoneId("1").zoneName("Dev Zone 1").podId("1").podName("Dev Pod 1").version("2.2.12.20110928142833").hypervisor("XenServer").cpuNumber(24).cpuSpeed(2266).cpuAllocated("2.76%").cpuUsed("0.1%").cpuWithOverProvisioning(54384.0F).networkKbsRead(4443).networkKbsWrite(15048).memoryTotal(100549733760L).memoryAllocated(3623878656L).memoryUsed(3623878656L).capabilities("xen-3.0-x86_64 , xen-3.0-x86_32p , hvm-3.0-x86_32 , hvm-3.0-x86_32p , hvm-3.0-x86_64").lastPinged(lastPinged).managementServerId("223098941760041").clusterId("1").clusterName("Xen Clust 1").clusterType(Host.ClusterType.CLOUD_MANAGED).localStorageActive(false).created(created).events("PrepareUnmanaged; HypervisorVersionChanged; ManagementServerDown; PingTimeout; AgentDisconnected; MaintenanceRequested; HostDown; AgentConnected; StartAgentRebalance; ShutdownRequested; Ping").hasEnoughCapacity(false).allocationState(AllocationState.ENABLED).build();
Host actual = requestSendsResponse(request, response).updateHost("1", UpdateHostOptions.Builder.allocationState(AllocationState.ENABLED).hostTags(Collections.<String>emptySet()).osCategoryId("5"));

View File

@ -22,17 +22,16 @@ import static org.testng.Assert.assertEquals;
import java.util.Set;
import org.jclouds.cloudstack.config.CloudStackParserModule;
import org.jclouds.cloudstack.domain.AllocationState;
import org.jclouds.cloudstack.domain.Host;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.json.BaseParserTest;
import org.jclouds.json.BaseSetParserTest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.inject.Guice;
import com.google.inject.Injector;
@ -48,16 +47,7 @@ public class ListHostsResponseTest extends BaseParserTest<Set<Host>, Set<Host>>
@Override
protected Injector injector() {
return Guice.createInjector(new GsonModule() {
@Override
protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
super.configure();
}
});
return Guice.createInjector(new GsonModule(), new CloudStackParserModule());
}
@Override
@ -102,7 +92,6 @@ public class ListHostsResponseTest extends BaseParserTest<Set<Host>, Set<Host>>
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-11-26T23:28:36+0200"))
.events("PrepareUnmanaged; HypervisorVersionChanged; ManagementServerDown; PingTimeout; " +
"AgentDisconnected; MaintenanceRequested; HostDown; AgentConnected; StartAgentRebalance; ShutdownRequested; Ping")
.hostTags("")
.hasEnoughCapacity(false)
.allocationState(AllocationState.ENABLED).build(),

View File

@ -23,18 +23,22 @@ import java.util.Date;
import java.util.Set;
import java.util.TimeZone;
import org.jclouds.cloudstack.config.CloudStackParserModule;
import org.jclouds.cloudstack.domain.StoragePool;
import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
*
* @author Richard Downer
*/
@Test(groups = "unit")
@Test(groups = "unit", testName = "ListStoragePoolsResponseTest")
public class ListStoragePoolsResponseTest extends BaseItemParserTest<Set<StoragePool>> {
@Override
@ -54,7 +58,16 @@ public class ListStoragePoolsResponseTest extends BaseItemParserTest<Set<Storage
c.set(Calendar.SECOND, 6);
Date created = c.getTime();
StoragePool storagePool = StoragePool.builder().id("201").zoneId("1").zoneName("Dev Zone 1").podId("1").podName("Dev Pod 1").name("NFS Pri 1").ipAddress("10.26.26.165").path("/mnt/nfs/cs_pri").created(created).type(StoragePool.Type.NETWORK_FILESYSTEM).clusterId("1").clusterName("Xen Clust 1").diskSizeTotal(898356445184L).diskSizeAllocated(18276679680L).tags("").state(StoragePool.State.UP).build();
StoragePool storagePool = StoragePool.builder().id("201").zoneId("1").zoneName("Dev Zone 1").podId("1")
.podName("Dev Pod 1").name("NFS Pri 1").ipAddress("10.26.26.165").path("/mnt/nfs/cs_pri")
.created(created).type(StoragePool.Type.NETWORK_FILESYSTEM).clusterId("1").clusterName("Xen Clust 1")
.diskSizeTotal(898356445184L).diskSizeAllocated(18276679680L).tag("tag1").state(StoragePool.State.UP)
.build();
return ImmutableSet.of(storagePool);
}
@Override
protected Injector injector() {
return Guice.createInjector(new GsonModule(), new CloudStackParserModule());
}
}

View File

@ -23,7 +23,7 @@ import java.util.Date;
import java.util.Set;
import java.util.TimeZone;
import org.jclouds.cloudstack.config.CloudStackDateAdapter;
import org.jclouds.cloudstack.config.CloudStackParserModule;
import org.jclouds.cloudstack.domain.UsageRecord;
import org.jclouds.json.BaseSetParserTest;
import org.jclouds.json.config.GsonModule;
@ -69,17 +69,10 @@ public class ListUsageRecordsResponseTest extends BaseSetParserTest<UsageRecord>
.templateId("0").id("203").startDate(start).endDate(end).build());
}
@Override
protected Injector injector() {
return Guice.createInjector(new GsonModule() {
@Override
protected void configure() {
bind(DateAdapter.class).to(CloudStackDateAdapter.class);
super.configure();
}
});
return Guice.createInjector(new GsonModule(), new CloudStackParserModule());
}
}

View File

@ -1 +1 @@
{ "liststoragepoolsresponse" : { "count":1 ,"storagepool" : [ {"id":201,"zoneid":1,"zonename":"Dev Zone 1","podid":1,"podname":"Dev Pod 1","name":"NFS Pri 1","ipaddress":"10.26.26.165","path":"/mnt/nfs/cs_pri","created":"2011-11-26T23:33:06+0200","type":"NetworkFilesystem","clusterid":1,"clustername":"Xen Clust 1","disksizetotal":898356445184,"disksizeallocated":18276679680,"tags":"","state":"Up"} ] } }
{ "liststoragepoolsresponse" : { "count":1 ,"storagepool" : [ {"id":201,"zoneid":1,"zonename":"Dev Zone 1","podid":1,"podname":"Dev Pod 1","name":"NFS Pri 1","ipaddress":"10.26.26.165","path":"/mnt/nfs/cs_pri","created":"2011-11-26T23:33:06+0200","type":"NetworkFilesystem","clusterid":1,"clustername":"Xen Clust 1","disksizetotal":898356445184,"disksizeallocated":18276679680,"tags":"tag1","state":"Up"} ] } }

View File

@ -93,8 +93,10 @@ public class MetricDataBinder implements org.jclouds.rest.Binder {
formParameters.put("MetricData.member." + metricDatumIndex + ".Unit",
String.valueOf(metricDatum.getUnit()));
formParameters.put("MetricData.member." + metricDatumIndex + ".Value",
String.valueOf(metricDatum.getValue()));
if (metricDatum.getValue().isPresent()) {
formParameters.put("MetricData.member." + metricDatumIndex + ".Value",
String.valueOf(metricDatum.getValue().get()));
}
metricDatumIndex++;
}

View File

@ -18,12 +18,12 @@
*/
package org.jclouds.cloudwatch.domain;
import java.util.Set;
import java.util.Iterator;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.collect.ForwardingSet;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableSet;
/**
@ -33,12 +33,12 @@ import com.google.common.collect.ImmutableSet;
*
* @author Jeremy Whitlock
*/
public class GetMetricStatisticsResponse extends ForwardingSet<Datapoint> {
public class GetMetricStatisticsResponse extends FluentIterable<Datapoint> {
private final Set<Datapoint> datapoints;
private final Iterable<Datapoint> datapoints;
private final String label;
public GetMetricStatisticsResponse(@Nullable Set<Datapoint> datapoints, String label) {
public GetMetricStatisticsResponse(@Nullable Iterable<Datapoint> datapoints, String label) {
// Default to an empty set
if (datapoints == null) {
this.datapoints = ImmutableSet.<Datapoint>of();
@ -90,8 +90,8 @@ public class GetMetricStatisticsResponse extends ForwardingSet<Datapoint> {
}
@Override
protected Set<Datapoint> delegate() {
return datapoints;
public Iterator<Datapoint> iterator() {
return datapoints.iterator();
}
}

View File

@ -25,14 +25,16 @@ import java.util.Date;
import java.util.Set;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
/**
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_MetricDatum.html" />
*
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_MetricDatum.html"
* />
*
* @author Jeremy Whitlock
*/
public class MetricDatum {
@ -42,17 +44,17 @@ public class MetricDatum {
private final Optional<StatisticValues> statisticValues;
private final Optional<Date> timestamp;
private final Unit unit;
private final double value;
private final Optional<Double> value;
/**
* Private constructor to enforce using {@link Builder}.
*/
protected MetricDatum(Set<Dimension> dimensions, String metricName, StatisticValues statisticValues, Date timestamp,
Unit unit, double value) {
this.dimensions = ImmutableSet.<Dimension>copyOf(checkNotNull(dimensions, "dimensions"));
protected MetricDatum(Iterable<Dimension> dimensions, String metricName, Optional<StatisticValues> statisticValues,
Optional<Date> timestamp, Unit unit, Optional<Double> value) {
this.dimensions = ImmutableSet.<Dimension> copyOf(checkNotNull(dimensions, "dimensions"));
this.metricName = checkNotNull(metricName, "metricName");
this.statisticValues = Optional.fromNullable(statisticValues);
this.timestamp = Optional.fromNullable(timestamp);
this.statisticValues = checkNotNull(statisticValues, "statisticValues");
this.timestamp = checkNotNull(timestamp, "timestamp");
this.unit = checkNotNull(unit, "unit");
this.value = checkNotNull(value, "value");
}
@ -95,13 +97,13 @@ public class MetricDatum {
/**
* return the actual value of the metric
*/
public double getValue() {
public Optional<Double> getValue() {
return value;
}
/**
* Returns a new builder. The generated builder is equivalent to the builder
* created by the {@link Builder} constructor.
* Returns a new builder. The generated builder is equivalent to the builder created by the
* {@link Builder} constructor.
*/
public static Builder builder() {
return new Builder();
@ -110,36 +112,39 @@ public class MetricDatum {
public static class Builder {
// this builder is set to be additive on dimension calls, so make this mutable
private Set<Dimension> dimensions = Sets.newLinkedHashSet();
private ImmutableList.Builder<Dimension> dimensions = ImmutableList.<Dimension> builder();
private String metricName;
private StatisticValues statisticValues;
private Date timestamp;
private Optional<StatisticValues> statisticValues = Optional.absent();
private Optional<Date> timestamp = Optional.absent();
private Unit unit = Unit.NONE;
private double value;
private Optional<Double> value = Optional.absent();
/**
* Creates a new builder. The returned builder is equivalent to the builder
* generated by {@link org.jclouds.cloudwatch.domain.MetricDatum#builder}.
* Creates a new builder. The returned builder is equivalent to the builder generated by
* {@link org.jclouds.cloudwatch.domain.MetricDatum#builder}.
*/
public Builder() {}
public Builder() {
}
/**
* A list of dimensions describing qualities of the metric.
*
* @param dimensions the dimensions describing the qualities of the metric
*
*
* @param dimensions
* the dimensions describing the qualities of the metric
*
* @return this {@code Builder} object
*/
public Builder dimensions(Set<Dimension> dimensions) {
public Builder dimensions(Iterable<Dimension> dimensions) {
this.dimensions.addAll(checkNotNull(dimensions, "dimensions"));
return this;
}
/**
* A dimension describing qualities of the metric.
*
* @param dimension the dimension describing the qualities of the metric
*
*
* @param dimension
* the dimension describing the qualities of the metric
*
* @return this {@code Builder} object
*/
public Builder dimension(Dimension dimension) {
@ -149,9 +154,10 @@ public class MetricDatum {
/**
* The name of the metric.
*
* @param metricName the metric name
*
*
* @param metricName
* the metric name
*
* @return this {@code Builder} object
*/
public Builder metricName(String metricName) {
@ -161,34 +167,37 @@ public class MetricDatum {
/**
* The object describing the set of statistical values describing the metric.
*
* @param statisticValues the object describing the set of statistical values for the metric
*
*
* @param statisticValues
* the object describing the set of statistical values for the metric
*
* @return this {@code Builder} object
*/
public Builder statisticValues(StatisticValues statisticValues) {
this.statisticValues = statisticValues;
this.statisticValues = Optional.fromNullable(statisticValues);
return this;
}
/**
* The time stamp used for the metric. If not specified, the default value is set to the time the metric data was
* received.
*
* @param timestamp the time stamp used for the metric
*
* The time stamp used for the metric. If not specified, the default value is set to the time
* the metric data was received.
*
* @param timestamp
* the time stamp used for the metric
*
* @return this {@code Builder} object
*/
public Builder timestamp(Date timestamp) {
this.timestamp = timestamp;
this.timestamp = Optional.fromNullable(timestamp);
return this;
}
/**
* The unit for the metric.
*
* @param unit the unit for the metric
*
*
* @param unit
* the unit for the metric
*
* @return this {@code Builder} object
*/
public Builder unit(Unit unit) {
@ -198,13 +207,14 @@ public class MetricDatum {
/**
* The value for the metric.
*
* @param value the value for the metric
*
*
* @param value
* the value for the metric
*
* @return this {@code Builder} object
*/
public Builder value(double value) {
this.value = value;
public Builder value(Double value) {
this.value = Optional.fromNullable(value);
return this;
}
@ -212,7 +222,7 @@ public class MetricDatum {
* Returns a newly-created {@code MetricDatum} based on the contents of the {@code Builder}.
*/
public MetricDatum build() {
return new MetricDatum(dimensions, metricName, statisticValues, timestamp, unit, value);
return new MetricDatum(dimensions.build(), metricName, statisticValues, timestamp, unit, value);
}
}
@ -240,7 +250,8 @@ public class MetricDatum {
}
protected ToStringHelper string() {
return Objects.toStringHelper("").add("dimensions", dimensions).add("metricName", metricName).add(
"statisticValues", statisticValues).add("timestamp", timestamp).add("unit", unit).add("value", value);
return Objects.toStringHelper("").omitNullValues().add("dimensions", dimensions).add("metricName", metricName)
.add("statisticValues", statisticValues.orNull()).add("timestamp", timestamp.orNull()).add("unit", unit)
.add("value", value.orNull());
}
}

View File

@ -34,6 +34,7 @@ import org.jclouds.concurrent.Timeout;
* Provides access to Amazon CloudWatch via the Query API
* <p/>
*
* @see MetricAsyncApi
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference" />
* @author Jeremy Whitlock
*/

View File

@ -37,11 +37,14 @@ import org.jclouds.cloudwatch.xml.ListMetricsResponseHandler;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.PagedIterable;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.functions.ReturnEmptyIterableWithMarkerOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnEmptyPagedIterableOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
@ -64,6 +67,7 @@ public interface MetricAsyncApi {
@XMLResponseParser(ListMetricsResponseHandler.class)
@Transform(MetricsToPagedIterable.class)
@FormParams(keys = "Action", values = "ListMetrics")
@ExceptionParser(ReturnEmptyPagedIterableOnNotFoundOr404.class)
ListenableFuture<? extends PagedIterable<Metric>> list();
/**
@ -73,6 +77,7 @@ public interface MetricAsyncApi {
@Path("/")
@XMLResponseParser(ListMetricsResponseHandler.class)
@FormParams(keys = "Action", values = "ListMetrics")
@ExceptionParser(ReturnEmptyIterableWithMarkerOnNotFoundOr404.class)
ListenableFuture<? extends IterableWithMarker<Metric>> list(ListMetricsOptions options);
/**

View File

@ -60,7 +60,6 @@ public class MetricDataBinderTest {
.statisticValues(ss)
.dimension(new Dimension("TestDimension", "FAKE"))
.unit(Unit.COUNT)
.value(2)
.build();
HttpRequest request = binder.bindToRequest(request(), ImmutableSet.of(metricDatum));
@ -73,8 +72,7 @@ public class MetricDataBinderTest {
"&MetricData.member.1.StatisticValues.Minimum=1.0" +
"&MetricData.member.1.StatisticValues.SampleCount=4.0" +
"&MetricData.member.1.StatisticValues.Sum=10.0" +
"&MetricData.member.1.Unit=" + Unit.COUNT.toString() +
"&MetricData.member.1.Value=2.0");
"&MetricData.member.1.Unit=" + Unit.COUNT.toString());
}
public void testMetricWithMultipleDimensions() throws Exception {

View File

@ -33,6 +33,7 @@ import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.cloudwatch.internal.BaseCloudWatchApiExpectTest;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.collect.IterableWithMarkers;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.rest.ResourceNotFoundException;
@ -76,8 +77,6 @@ public class MetricApiExpectTest extends BaseCloudWatchApiExpectTest {
"[Metric{namespace=AWS/EC2, metricName=CPUUtilization, dimension=[Dimension{name=InstanceId, value=i-689fcf0f}]}]");
}
// TODO: this should really be an empty set
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testListMetricsWhenResponseIs404() throws Exception {
HttpResponse listMetricsResponse = HttpResponse.builder().statusCode(404).build();
@ -85,7 +84,7 @@ public class MetricApiExpectTest extends BaseCloudWatchApiExpectTest {
CloudWatchApi apiWhenMetricsDontExist = requestSendsResponse(
listMetrics, listMetricsResponse);
apiWhenMetricsDontExist.getMetricApiForRegion(null).list().get(0);
assertEquals(apiWhenMetricsDontExist.getMetricApiForRegion(null).list().get(0), IterableWithMarkers.EMPTY);
}
public void testListMetrics2PagesWhenResponseIs2xx() throws Exception {

View File

@ -196,7 +196,7 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
@VisibleForTesting
String getGroupForInstance(final RunningInstance instance) {
String group = parseGroupFrom(instance, instance.getGroupIds());
String group = parseGroupFrom(instance, instance.getGroupNames());
if(group == null && instance.getKeyName() != null) {
// when not using a generated security group, e.g. in VPC, try from key:
group = parseGroupFrom(instance, Sets.newHashSet(instance.getKeyName()));

View File

@ -114,8 +114,12 @@ public class Attachment implements Comparable<Attachment> {
}
/**
* Snapshots are tied to Regions and can only be used for volumes within the same Region.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -209,9 +209,12 @@ public class BundleTask implements Comparable<BundleTask> {
}
/**
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* @return region of the bundle task
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -219,9 +219,12 @@ public class Image implements Comparable<Image> {
}
/**
* AMIs are tied to the Region where its files are located within Amazon S3.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -47,8 +47,12 @@ public class InstanceStateChange implements Comparable<InstanceStateChange> {
}
/**
* Instances are tied to Availability Zones. However, the instance ID is tied to the Region.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -103,8 +103,12 @@ public class KeyPair implements Comparable<KeyPair> {
}
/**
* Key pairs (to connect to instances) are Region-specific.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -42,8 +42,12 @@ public class PublicIpInstanceIdPair implements Comparable<PublicIpInstanceIdPair
}
/**
* Elastic IP addresses are tied to a Region and cannot be mapped across Regions.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -20,27 +20,119 @@ package org.jclouds.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.LinkedHashSet;
import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.common.base.Objects;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.ForwardingSet;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Ordering;
/**
*
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-ReservationInfoType.html"
* @see <a href=
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-ReservationInfoType.html"
* />
* @author Adrian Cole
*/
public class Reservation<T extends RunningInstance> extends LinkedHashSet<T> implements Comparable<Reservation<T>>,
Set<T> {
public class Reservation<T extends RunningInstance> extends ForwardingSet<T> implements Comparable<Reservation<T>>{
public static <T extends RunningInstance> Builder<T> builder() {
return new Builder<T>();
}
public Builder<T> toBuilder() {
return Reservation.<T> builder().fromReservation(this);
}
public static class Builder<T extends RunningInstance> {
private String region;
private String ownerId;
private String requesterId;
private String reservationId;
private ImmutableSet.Builder<T> instances = ImmutableSet.<T> builder();
private ImmutableSet.Builder<String> groupNames = ImmutableSet.<String> builder();
/**
* @see Reservation#getRegion()
*/
public Builder<T> region(String region) {
this.region = region;
return this;
}
/**
* @see Reservation#getOwnerId()
*/
public Builder<T> ownerId(String ownerId) {
this.ownerId = ownerId;
return this;
}
/**
* @see Reservation#getRequesterId()
*/
public Builder<T> requesterId(String requesterId) {
this.requesterId = requesterId;
return this;
}
/**
* @see Reservation#getReservationId()
*/
public Builder<T> reservationId(String reservationId) {
this.reservationId = reservationId;
return this;
}
/**
* @see Reservation#iterator
*/
public Builder<T> instance(T instance) {
this.instances.add(checkNotNull(instance, "instance"));
return this;
}
/**
* @see Reservation#iterator
*/
public Builder<T> instances(Set<T> instances) {
this.instances.addAll(checkNotNull(instances, "instances"));
return this;
}
/**
* @see Reservation#getGroupNames()
*/
public Builder<T> groupName(String groupName) {
this.groupNames.add(checkNotNull(groupName, "groupName"));
return this;
}
/**
* @see Reservation#getGroupNames()
*/
public Builder<T> groupNames(Iterable<String> groupNames) {
this.groupNames = ImmutableSet.<String> builder().addAll(checkNotNull(groupNames, "groupNames"));
return this;
}
public Reservation<T> build() {
return new Reservation<T>(region, groupNames.build(), instances.build(), ownerId, requesterId, reservationId);
}
public Builder<T> fromReservation(Reservation<T> in) {
return region(in.region).ownerId(in.ownerId).requesterId(in.requesterId).reservationId(in.reservationId)
.instances(in).groupNames(in.groupNames);
}
}
/** The serialVersionUID */
private static final long serialVersionUID = -9051777593518861395L;
private final String region;
private final Set<String> groupIds = Sets.newLinkedHashSet();
private final ImmutableSet<String> groupNames;
private final ImmutableSet<T> instances;
@Nullable
private final String ownerId;
@Nullable
@ -48,32 +140,45 @@ public class Reservation<T extends RunningInstance> extends LinkedHashSet<T> imp
@Nullable
private final String reservationId;
public Reservation(String region, Iterable<String> groupIds, Iterable<T> instances, @Nullable String ownerId,
public Reservation(String region, Iterable<String> groupNames, Iterable<T> instances, @Nullable String ownerId,
@Nullable String requesterId, @Nullable String reservationId) {
this.region = checkNotNull(region, "region");
Iterables.addAll(this.groupIds, checkNotNull(groupIds, "groupIds"));
Iterables.addAll(this, checkNotNull(instances, "instances"));
this.groupNames = ImmutableSet.copyOf(checkNotNull(groupNames, "groupNames"));
this.instances = ImmutableSet.copyOf(checkNotNull(instances, "instances"));
this.ownerId = ownerId;
this.requesterId = requesterId;
this.reservationId = reservationId;
}
@Override
protected Set<T> delegate() {
return instances;
}
/**
* Instances are tied to Availability Zones. However, the instance ID is tied to the Region.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}
public int compareTo(Reservation<T> o) {
return (this == o) ? 0 : getReservationId().compareTo(o.getReservationId());
/**
* @see #getGroupNames()
*/
@Deprecated
public Set<String> getGroupIds() {
return groupNames;
}
/**
* Names of the security groups.
*/
public Set<String> getGroupIds() {
return groupIds;
public Set<String> getGroupNames() {
return groupNames;
}
/**
@ -84,7 +189,8 @@ public class Reservation<T extends RunningInstance> extends LinkedHashSet<T> imp
}
/**
* ID of the requester.
* The ID of the requester that launched the instances on your behalf (for example, AWS
* Management Console or Auto Scaling).
*/
public String getRequesterId() {
return requesterId;
@ -99,51 +205,34 @@ public class Reservation<T extends RunningInstance> extends LinkedHashSet<T> imp
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode());
result = prime * result + ((ownerId == null) ? 0 : ownerId.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode());
result = prime * result + ((requesterId == null) ? 0 : requesterId.hashCode());
result = prime * result + ((reservationId == null) ? 0 : reservationId.hashCode());
return result;
return Objects.hashCode(region, reservationId, super.hashCode());
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
if (obj == null || getClass() != obj.getClass())
return false;
if (getClass() != obj.getClass())
return false;
Reservation<?> other = (Reservation<?>) obj;
if (groupIds == null) {
if (other.groupIds != null)
return false;
} else if (!groupIds.equals(other.groupIds))
return false;
if (ownerId == null) {
if (other.ownerId != null)
return false;
} else if (!ownerId.equals(other.ownerId))
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
if (requesterId == null) {
if (other.requesterId != null)
return false;
} else if (!requesterId.equals(other.requesterId))
return false;
if (reservationId == null) {
if (other.reservationId != null)
return false;
} else if (!reservationId.equals(other.reservationId))
return false;
return true;
@SuppressWarnings("unchecked")
Reservation<T> that = Reservation.class.cast(obj);
return super.equals(that) && Objects.equal(this.region, that.region)
&& Objects.equal(this.reservationId, that.reservationId);
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return Objects.toStringHelper(this).omitNullValues().add("region", region).add("reservationId", reservationId)
.add("requesterId", requesterId).add("instances", instances).add("groupNames", groupNames).toString();
}
@Override
public int compareTo(Reservation<T> other) {
return ComparisonChain.start().compare(region, other.region)
.compare(reservationId, other.reservationId, Ordering.natural().nullsLast()).result();
}
}

View File

@ -46,10 +46,17 @@ public class ReservedInstancesOffering implements Comparable<ReservedInstancesOf
this.usagePrice = usagePrice;
}
/**
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}
/**
* @return The Availability Zone in which the Reserved Instance can be used.
*/

View File

@ -26,9 +26,13 @@ import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
/**
@ -44,7 +48,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
public static class Builder {
protected String region;
protected Set<String> groupIds = Sets.newLinkedHashSet();
protected Set<String> groupNames = Sets.newLinkedHashSet();
protected String amiLaunchIndex;
protected String dnsName;
protected String imageId;
@ -72,14 +76,14 @@ public class RunningInstance implements Comparable<RunningInstance> {
return this;
}
public Builder groupIds(Iterable<String> groupIds) {
this.groupIds = ImmutableSet.copyOf(checkNotNull(groupIds, "groupIds"));
public Builder groupNames(Iterable<String> groupNames) {
this.groupNames = ImmutableSet.copyOf(checkNotNull(groupNames, "groupNames"));
return this;
}
public Builder groupId(String groupId) {
if (groupId != null)
this.groupIds.add(groupId);
public Builder groupName(String groupName) {
if (groupName != null)
this.groupNames.add(groupName);
return this;
}
@ -195,7 +199,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
}
public RunningInstance build() {
return new RunningInstance(region, groupIds, amiLaunchIndex, dnsName, imageId, instanceId, instanceState,
return new RunningInstance(region, groupNames, amiLaunchIndex, dnsName, imageId, instanceId, instanceState,
rawState, instanceType, ipAddress, kernelId, keyName, launchTime, availabilityZone,
virtualizationType, platform, privateDnsName, privateIpAddress, ramdiskId, reason, rootDeviceType,
rootDeviceName, ebsBlockDevices);
@ -220,7 +224,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
}
protected final String region;
protected final Set<String> groupIds;
protected final Set<String> groupNames;
protected final String amiLaunchIndex;
@Nullable
protected final String dnsName;
@ -253,11 +257,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
protected final String rootDeviceName;
protected final Map<String, BlockDevice> ebsBlockDevices;
public int compareTo(RunningInstance o) {
return (this == o) ? 0 : getId().compareTo(o.getId());
}
protected RunningInstance(String region, Iterable<String> groupIds, @Nullable String amiLaunchIndex,
protected RunningInstance(String region, Iterable<String> groupNames, @Nullable String amiLaunchIndex,
@Nullable String dnsName, String imageId, String instanceId, InstanceState instanceState, String rawState,
String instanceType, @Nullable String ipAddress, @Nullable String kernelId, @Nullable String keyName,
Date launchTime, String availabilityZone, String virtualizationType, @Nullable String platform,
@ -286,12 +286,16 @@ public class RunningInstance implements Comparable<RunningInstance> {
this.rootDeviceType = checkNotNull(rootDeviceType, "rootDeviceType for %s/%s", region, instanceId);
this.rootDeviceName = rootDeviceName;
this.ebsBlockDevices = ImmutableMap.copyOf(checkNotNull(ebsBlockDevices, "ebsBlockDevices for %s/%s", region, instanceId));
this.groupIds = ImmutableSet.copyOf(checkNotNull(groupIds, "groupIds for %s/%s", region, instanceId));
this.groupNames = ImmutableSet.copyOf(checkNotNull(groupNames, "groupNames for %s/%s", region, instanceId));
}
/**
* Instance Ids are scoped to the region.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}
@ -443,160 +447,55 @@ public class RunningInstance implements Comparable<RunningInstance> {
return ebsBlockDevices;
}
/**
* @see #getGroupNames()
*/
@Deprecated
public Set<String> getGroupIds() {
return getGroupNames();
}
/**
* Names of the security groups.
*/
public Set<String> getGroupIds() {
return groupIds;
public Set<String> getGroupNames() {
return groupNames;
}
@Override
public int compareTo(RunningInstance other) {
return ComparisonChain.start().compare(region, other.region).compare(instanceId, other.instanceId, Ordering.natural().nullsLast()).result();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((amiLaunchIndex == null) ? 0 : amiLaunchIndex.hashCode());
result = prime * result + ((availabilityZone == null) ? 0 : availabilityZone.hashCode());
result = prime * result + ((dnsName == null) ? 0 : dnsName.hashCode());
result = prime * result + ((ebsBlockDevices == null) ? 0 : ebsBlockDevices.hashCode());
result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode());
result = prime * result + ((imageId == null) ? 0 : imageId.hashCode());
result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode());
result = prime * result + ((instanceType == null) ? 0 : instanceType.hashCode());
result = prime * result + ((ipAddress == null) ? 0 : ipAddress.hashCode());
result = prime * result + ((kernelId == null) ? 0 : kernelId.hashCode());
result = prime * result + ((keyName == null) ? 0 : keyName.hashCode());
result = prime * result + ((launchTime == null) ? 0 : launchTime.hashCode());
result = prime * result + ((platform == null) ? 0 : platform.hashCode());
result = prime * result + ((privateDnsName == null) ? 0 : privateDnsName.hashCode());
result = prime * result + ((privateIpAddress == null) ? 0 : privateIpAddress.hashCode());
result = prime * result + ((ramdiskId == null) ? 0 : ramdiskId.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode());
result = prime * result + ((rootDeviceName == null) ? 0 : rootDeviceName.hashCode());
result = prime * result + ((rootDeviceType == null) ? 0 : rootDeviceType.hashCode());
result = prime * result + ((virtualizationType == null) ? 0 : virtualizationType.hashCode());
return result;
return Objects.hashCode(region, instanceId);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
if (obj == null || getClass() != obj.getClass())
return false;
if (getClass() != obj.getClass())
return false;
RunningInstance other = (RunningInstance) obj;
if (amiLaunchIndex == null) {
if (other.amiLaunchIndex != null)
return false;
} else if (!amiLaunchIndex.equals(other.amiLaunchIndex))
return false;
if (availabilityZone == null) {
if (other.availabilityZone != null)
return false;
} else if (!availabilityZone.equals(other.availabilityZone))
return false;
if (dnsName == null) {
if (other.dnsName != null)
return false;
} else if (!dnsName.equals(other.dnsName))
return false;
if (ebsBlockDevices == null) {
if (other.ebsBlockDevices != null)
return false;
} else if (!ebsBlockDevices.equals(other.ebsBlockDevices))
return false;
if (groupIds == null) {
if (other.groupIds != null)
return false;
} else if (!groupIds.equals(other.groupIds))
return false;
if (imageId == null) {
if (other.imageId != null)
return false;
} else if (!imageId.equals(other.imageId))
return false;
if (instanceId == null) {
if (other.instanceId != null)
return false;
} else if (!instanceId.equals(other.instanceId))
return false;
if (instanceType == null) {
if (other.instanceType != null)
return false;
} else if (!instanceType.equals(other.instanceType))
return false;
if (ipAddress == null) {
if (other.ipAddress != null)
return false;
} else if (!ipAddress.equals(other.ipAddress))
return false;
if (kernelId == null) {
if (other.kernelId != null)
return false;
} else if (!kernelId.equals(other.kernelId))
return false;
if (keyName == null) {
if (other.keyName != null)
return false;
} else if (!keyName.equals(other.keyName))
return false;
if (launchTime == null) {
if (other.launchTime != null)
return false;
} else if (!launchTime.equals(other.launchTime))
return false;
if (platform == null) {
if (other.platform != null)
return false;
} else if (!platform.equals(other.platform))
return false;
if (privateDnsName == null) {
if (other.privateDnsName != null)
return false;
} else if (!privateDnsName.equals(other.privateDnsName))
return false;
if (privateIpAddress == null) {
if (other.privateIpAddress != null)
return false;
} else if (!privateIpAddress.equals(other.privateIpAddress))
return false;
if (ramdiskId == null) {
if (other.ramdiskId != null)
return false;
} else if (!ramdiskId.equals(other.ramdiskId))
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
if (rootDeviceName == null) {
if (other.rootDeviceName != null)
return false;
} else if (!rootDeviceName.equals(other.rootDeviceName))
return false;
if (rootDeviceType == null) {
if (other.rootDeviceType != null)
return false;
} else if (!rootDeviceType.equals(other.rootDeviceType))
return false;
if (virtualizationType == null) {
if (other.virtualizationType != null)
return false;
} else if (!virtualizationType.equals(other.virtualizationType))
return false;
return true;
RunningInstance that = RunningInstance.class.cast(obj);
return Objects.equal(this.region, that.region) && Objects.equal(this.instanceId, that.instanceId);
}
protected ToStringHelper string() {
return Objects.toStringHelper(this).omitNullValues().add("region", region)
.add("availabilityZone", availabilityZone).add("id", instanceId).add("state", rawState)
.add("type", instanceType).add("virtualizationType", virtualizationType).add("imageId", imageId)
.add("ipAddress", ipAddress).add("dnsName", dnsName).add("privateIpAddress", privateIpAddress)
.add("privateDnsName", privateDnsName).add("keyName", keyName).add("groupNames", groupNames)
.add("platform", platform).add("launchTime", launchTime).add("rootDeviceName", rootDeviceName)
.add("rootDeviceType", rootDeviceType).add("ebsBlockDevices", ebsBlockDevices);
}
@Override
public String toString() {
return "[region=" + region + ", availabilityZone=" + availabilityZone + ", instanceId=" + instanceId
+ ", instanceState=" + rawState + ", instanceType=" + instanceType + ", virtualizationType="
+ virtualizationType + ", imageId=" + imageId + ", ipAddress=" + ipAddress + ", dnsName=" + dnsName
+ ", privateIpAddress=" + privateIpAddress + ", privateDnsName=" + privateDnsName + ", keyName="
+ keyName + ", groupIds=" + groupIds + ", platform=" + platform + ", launchTime=" + launchTime + ", rootDeviceName="
+ rootDeviceName + ", rootDeviceType=" + rootDeviceType + ", ebsBlockDevices=" + ebsBlockDevices + "]";
return string().toString();
}
}

View File

@ -31,7 +31,7 @@ import org.jclouds.javax.annotation.Nullable;
* />
* @author Adrian Cole
*/
public class SecurityGroup implements Comparable<SecurityGroup> {
public class SecurityGroup {
private final String region;
private final String id;
@ -49,24 +49,18 @@ public class SecurityGroup implements Comparable<SecurityGroup> {
this.description = description;
this.ipPermissions = ipPermissions;
}
/**
* Security groups are not copied across Regions. Instances within the Region
* cannot communicate with instances outside the Region using group-based
* firewall rules. Traffic from instances in another Region is seen as WAN
* bandwidth.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}
/**
* {@inheritDoc}
*/
public int compareTo(SecurityGroup o) {
return (this == o) ? 0 : getName().compareTo(o.getName());
}
/**
* id of the security group. Not in all EC2 impls
*/

View File

@ -75,12 +75,16 @@ public class Snapshot implements Comparable<Snapshot> {
}
/**
* Snapshots are tied to Regions and can only be used for volumes within the same Region.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}
/**
* The ID of the snapshot.
*/

View File

@ -172,9 +172,12 @@ public class Volume implements Comparable<Volume> {
}
/**
* An Amazon EBS volume must be located within the same Availability Zone as the instance to
* which it attaches.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -80,7 +80,7 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
private String deviceName;
// reservation stuff
private Set<String> groupIds = Sets.newLinkedHashSet();
private Set<String> groupNames = Sets.newLinkedHashSet();
private String ownerId;
private String requesterId;
private String reservationId;
@ -111,7 +111,7 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
} else if (equalsOrSuffix(qName, "groupSet")) {
inGroupSet = false;
} else if (equalsOrSuffix(qName, "groupId")) {
groupIds.add(currentOrNull(currentText));
groupNames.add(currentOrNull(currentText));
} else if (equalsOrSuffix(qName, "ownerId")) {
ownerId = currentOrNull(currentText);
} else if (equalsOrSuffix(qName, "requesterId")) {
@ -210,7 +210,7 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
}
builder.region((region == null) ? defaultRegion.get() : region);
builder.groupIds(groupIds);
builder.groupNames(groupNames);
}
protected Builder builder() {
@ -229,9 +229,9 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
String region = getRequest() != null ? AWSUtils.findRegionInArgsOrNull(getRequest()) : null;
if (region == null)
region = defaultRegion.get();
Reservation<? extends RunningInstance> info = new Reservation<RunningInstance>(region, groupIds, instances,
Reservation<? extends RunningInstance> info = new Reservation<RunningInstance>(region, groupNames, instances,
ownerId, requesterId, reservationId);
this.groupIds = Sets.newLinkedHashSet();
this.groupNames = Sets.newLinkedHashSet();
this.instances = Sets.newLinkedHashSet();
this.ownerId = null;
this.requesterId = null;

View File

@ -130,7 +130,8 @@ public class DescribeSecurityGroupsResponseHandler extends
this.ipProtocol = null;
this.ipRanges = Sets.newLinkedHashSet();
} else if (inIpPermissions && !inIpRanges && inGroups) {
this.groups.put(userId, userIdGroupName);
if (userId != null && userIdGroupName != null)
this.groups.put(userId, userIdGroupName);
this.userId = null;
this.userIdGroupName = null;
} else if (!inIpPermissions && !inIpRanges && !inGroups) {

View File

@ -151,7 +151,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
assertEquals(instance.getKeyName(), group);
// make sure we made our dummy group and also let in the user's group
assertEquals(Sets.newTreeSet(instance.getGroupIds()), ImmutableSortedSet.<String> of("jclouds#" + group + "#"
assertEquals(Sets.newTreeSet(instance.getGroupNames()), ImmutableSortedSet.<String> of("jclouds#" + group + "#"
+ instance.getRegion(), group));
// make sure our dummy group has no rules

View File

@ -241,13 +241,13 @@ public class RunningInstanceToNodeMetadataTest {
public void testGroupNameIsSetWhenCustomKeyNameIsSetAndSecurityGroupIsGenerated() {
checkGroupName(RunningInstance.builder().instanceId("id").imageId("image").instanceType("m1.small")
.instanceState(InstanceState.RUNNING).rawState("running").region("us-east-1").keyName("custom-key")
.groupId("jclouds#groupname").build());
.groupName("jclouds#groupname").build());
}
@Test
public void testGroupNameIsSetWhenCustomSecurityGroupIsSetAndKeyNameIsGenerated() {
checkGroupName(RunningInstance.builder().instanceId("id").imageId("image").instanceType("m1.small")
.instanceState(InstanceState.RUNNING).rawState("running").region("us-east-1").groupId("custom-sec")
.instanceState(InstanceState.RUNNING).rawState("running").region("us-east-1").groupName("custom-sec")
.keyName("jclouds#groupname#23").build());
}

View File

@ -23,7 +23,6 @@ import static org.testng.Assert.assertNotNull;
import java.util.Iterator;
import java.util.Set;
import java.util.SortedSet;
import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
import org.jclouds.ec2.EC2ApiMetadata;
@ -32,14 +31,12 @@ import org.jclouds.ec2.domain.IpPermission;
import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.SecurityGroup;
import org.jclouds.ec2.domain.UserIdGroupPair;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
/**
@ -67,15 +64,13 @@ public class SecurityGroupClientLiveTest extends BaseComputeServiceContextLiveTe
@Test
void testDescribe() {
for (String region : ec2Client.getConfiguredRegions()) {
SortedSet<SecurityGroup> allResults = ImmutableSortedSet.<SecurityGroup> copyOf(client
.describeSecurityGroupsInRegion(region));
Set<SecurityGroup> allResults = client.describeSecurityGroupsInRegion(region);
assertNotNull(allResults);
if (allResults.size() >= 1) {
SecurityGroup group = allResults.last();
SortedSet<SecurityGroup> result = ImmutableSortedSet.<SecurityGroup> copyOf(client
.describeSecurityGroupsInRegion(region, group.getName()));
SecurityGroup group = Iterables.getLast(allResults);
Set<SecurityGroup> result = client.describeSecurityGroupsInRegion(region, group.getName());
assertNotNull(result);
SecurityGroup compare = result.last();
SecurityGroup compare = Iterables.getLast(result);
assertEquals(compare, group);
}
}
@ -233,8 +228,7 @@ public class SecurityGroupClientLiveTest extends BaseComputeServiceContextLiveTe
}
protected void ensureGroupsExist(String group1Name, String group2Name) {
SortedSet<SecurityGroup> twoResults = ImmutableSortedSet.copyOf(client.describeSecurityGroupsInRegion(null,
group1Name, group2Name));
Set<SecurityGroup> twoResults = client.describeSecurityGroupsInRegion(null, group1Name, group2Name);
assertNotNull(twoResults);
assertEquals(twoResults.size(), 2);
Iterator<SecurityGroup> iterator = twoResults.iterator();
@ -279,8 +273,4 @@ public class SecurityGroupClientLiveTest extends BaseComputeServiceContextLiveTe
public static final String PREFIX = System.getProperty("user.name") + "-ec2";
@AfterTest
public void shutdown() {
view.close();
}
}

View File

@ -70,7 +70,7 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
Set<Reservation<RunningInstance>> contents = ImmutableSet.of(new Reservation<RunningInstance>(defaultRegion,
ImmutableSet.of("adriancole.ec2ingress"), ImmutableSet.of(new RunningInstance.Builder().region(
defaultRegion).groupId("adriancole.ec2ingress").amiLaunchIndex("0").dnsName(
defaultRegion).groupName("adriancole.ec2ingress").amiLaunchIndex("0").dnsName(
"ec2-174-129-81-68.compute-1.amazonaws.com").imageId("ami-82e4b5c7").instanceId("i-0799056f")
.instanceState(InstanceState.RUNNING).rawState("running").instanceType(InstanceType.M1_SMALL)
.ipAddress("174.129.81.68").kernelId("aki-a71cf9ce").keyName("adriancole.ec21").launchTime(
@ -83,7 +83,7 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
Set<Reservation<? extends RunningInstance>> result = parseRunningInstances("/describe_instances_running.xml");
assertEquals(result, contents);
assertEquals(result.toString(), contents.toString());
assertEquals(get(get(result, 0), 0).getInstanceState(), InstanceState.RUNNING);
assertEquals(get(get(result, 0), 0).getRawState(), "running");
@ -91,7 +91,7 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
public void testApplyInputStream() {
Set<Reservation<RunningInstance>> contents = ImmutableSet.of(new Reservation<RunningInstance>(defaultRegion,
ImmutableSet.of("default"), ImmutableSet.of(new RunningInstance.Builder().region(defaultRegion).groupId(
ImmutableSet.of("default"), ImmutableSet.of(new RunningInstance.Builder().region(defaultRegion).groupName(
"default").amiLaunchIndex("23").dnsName("ec2-72-44-33-4.compute-1.amazonaws.com").imageId(
"ami-6ea54007").instanceId("i-28a64341").instanceState(InstanceState.RUNNING).rawState(
"running").instanceType(InstanceType.M1_LARGE).kernelId("aki-ba3adfd3").keyName(
@ -101,7 +101,7 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
"10-251-50-132.ec2.internal")// product codes
// ImmutableSet.of("774F4FF8")
.ramdiskId("ari-badbad00").rootDeviceType(RootDeviceType.INSTANCE_STORE).build(),
new RunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("23")
new RunningInstance.Builder().region(defaultRegion).groupName("default").amiLaunchIndex("23")
.dnsName("ec2-72-44-33-6.compute-1.amazonaws.com").imageId("ami-6ea54007").instanceId(
"i-28a64435").instanceState(InstanceState.RUNNING).rawState("running")
.instanceType(InstanceType.M1_LARGE).kernelId("aki-ba3adfd3").keyName(
@ -116,7 +116,7 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
Set<Reservation<? extends RunningInstance>> result = parseRunningInstances("/describe_instances.xml");
assertEquals(result, contents);
assertEquals(result.toString(), contents.toString());
assertEquals(get(get(result, 0), 0).getInstanceState(), InstanceState.RUNNING);
assertEquals(get(get(result, 0), 0).getRawState(), "running");
@ -126,7 +126,7 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
Set<Reservation<RunningInstance>> contents = ImmutableSet.of(new Reservation<RunningInstance>(defaultRegion,
ImmutableSet.of("adriancole.ec2ebsingress"), ImmutableSet.of(new RunningInstance.Builder().region(
defaultRegion).groupId("adriancole.ec2ebsingress").amiLaunchIndex("0").dnsName(
defaultRegion).groupName("adriancole.ec2ebsingress").amiLaunchIndex("0").dnsName(
"ec2-75-101-203-146.compute-1.amazonaws.com").imageId("ami-849875ed").instanceId("i-e564438d")
.instanceState(InstanceState.RUNNING).rawState("running").instanceType(InstanceType.M1_SMALL)
.ipAddress("75.101.203.146").kernelId("aki-a71cf9ce")
@ -145,7 +145,7 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
Set<Reservation<? extends RunningInstance>> result = parseRunningInstances("/describe_instances_ebs.xml");
assertEquals(result, contents);
assertEquals(result.toString(), contents.toString());
assertEquals(get(get(result, 0), 0).getInstanceState(), InstanceState.RUNNING);
assertEquals(get(get(result, 0), 0).getRawState(), "running");
}

View File

@ -65,19 +65,19 @@ public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest {
Reservation<? extends RunningInstance> expected = new Reservation<RunningInstance>(defaultRegion, ImmutableSet
.of("default"), ImmutableSet.of(
new RunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("0")
new RunningInstance.Builder().region(defaultRegion).groupName("default").amiLaunchIndex("0")
.imageId("ami-60a54009").instanceId("i-2ba64342").instanceState(InstanceState.PENDING).rawState(
"pending").instanceType(InstanceType.M1_SMALL).keyName("example-key-name").launchTime(
dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"))// MonitoringState.ENABLED,
.availabilityZone("us-east-1b").build(),
new RunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("1")
new RunningInstance.Builder().region(defaultRegion).groupName("default").amiLaunchIndex("1")
.imageId("ami-60a54009").instanceId("i-2bc64242").instanceState(InstanceState.PENDING).rawState(
"pending").instanceType(InstanceType.M1_SMALL).keyName("example-key-name").launchTime(
dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"))// MonitoringState.ENABLED,
.availabilityZone("us-east-1b").build(),
new RunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("2")
new RunningInstance.Builder().region(defaultRegion).groupName("default").amiLaunchIndex("2")
.imageId("ami-60a54009").instanceId("i-2be64332").instanceState(InstanceState.PENDING).rawState(
"pending").instanceType(InstanceType.M1_SMALL).keyName("example-key-name").launchTime(
dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"))// MonitoringState.ENABLED,
@ -96,9 +96,9 @@ public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest {
InputStream is = getClass().getResourceAsStream("/run_instances_cloudbridge.xml");
Reservation<? extends RunningInstance> expected = new Reservation<RunningInstance>(defaultRegion, ImmutableSet
.of("default"), ImmutableSet.of(
.of("jclouds#greenqloud-computeblock"), ImmutableSet.of(
new RunningInstance.Builder().region(defaultRegion).groupId("jclouds#greenqloud-computeblock").amiLaunchIndex("0")
new RunningInstance.Builder().region(defaultRegion).groupName("jclouds#greenqloud-computeblock").amiLaunchIndex("0")
.imageId("qmi-9ac92558").instanceId("i-01b0dac3").instanceState(InstanceState.PENDING).rawState(
"pending").instanceType(InstanceType.M1_SMALL).keyName("jclouds#greenqloud-computeblock#35")
.launchTime(dateService.iso8601DateParse("2012-06-15T19:06:35.000+00:00"))

View File

@ -33,27 +33,13 @@
<description>jclouds components to access elasticstack</description>
<packaging>bundle</packaging>
<!-- bootstrapping: need to fetch the project POM -->
<repositories>
<repository>
<id>sonatype-nexus-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<properties>
<test.elasticstack.endpoint>https://api-lon-p.elastichosts.com</test.elasticstack.endpoint>
<test.elasticstack.api-version>1.0</test.elasticstack.api-version>
<test.elasticstack.build-version />
<test.elasticstack.api-version>2.0</test.elasticstack.api-version>
<test.elasticstack.build-version></test.elasticstack.build-version>
<test.elasticstack.identity>FIXME</test.elasticstack.identity>
<test.elasticstack.credential>FIXME</test.elasticstack.credential>
<test.elasticstack.template>imageId=38df0986-4d85-4b76-b502-3878ffc80161</test.elasticstack.template>
<test.elasticstack.template>imageId=38df0986-4d85-4b76-b502-3878ffc80161,loginUser=toor</test.elasticstack.template>
<jclouds.osgi.export>org.jclouds.elasticstack*;version="${project.version}"</jclouds.osgi.export>
<jclouds.osgi.import>
org.jclouds.compute.internal;version="${project.version}",

View File

@ -122,7 +122,8 @@ public class ElasticStackComputeServiceAdapter implements
}
Server toCreate = small(name, drive.getUuid(), defaultVncPassword).mem(template.getHardware().getRam())
.cpu((int) (template.getHardware().getProcessors().get(0).getSpeed())).build();
.cpu((int) (template.getHardware().getProcessors().get(0).getSpeed()))
.tags(template.getOptions().getTags()).userMetadata(template.getOptions().getUserMetadata()).build();
ServerInfo from = client.createServer(toCreate);
client.startServer(from.getUuid());

View File

@ -93,7 +93,8 @@ public class ServerInfoToNodeMetadata implements Function<ServerInfo, NodeMetada
builder.name(from.getName());
builder.location(locationSupplier.get());
builder.group(nodeNamingConvention.groupInUniqueNameOrNull(from.getName()));
builder.tags(from.getTags());
builder.userMetadata(from.getUserMetadata());
String imageId = getImageIdFromServer.apply(from);
if (imageId != null) {
Image image = findImageForId.apply(imageId);

View File

@ -50,7 +50,7 @@ import org.jclouds.ssh.SshClient;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.jclouds.util.Strings2;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
@ -67,10 +67,8 @@ import com.google.inject.Guice;
* @author Adrian Cole
*/
@Test(groups = "live", singleThreaded = true, testName = "ElasticStackClientLiveTest")
public class ElasticStackClientLiveTest
extends
BaseComputeServiceContextLiveTest {
public class ElasticStackClientLiveTest extends BaseComputeServiceContextLiveTest {
public ElasticStackClientLiveTest() {
provider = "elasticstack";
}
@ -84,23 +82,19 @@ public class ElasticStackClientLiveTest
protected Predicate<DriveInfo> driveNotClaimed;
protected String imageId;
@BeforeGroups(groups = { "integration", "live" })
@Override
@BeforeClass(groups = { "integration", "live" })
public void setupContext() {
super.setupContext();
cloudStackContext = view.unwrap();
imageId = view.getComputeService().templateBuilder().build().getImage().getId();
client = cloudStackContext.getApi();
client = view.unwrap(ElasticStackApiMetadata.CONTEXT_TOKEN).getApi();
driveNotClaimed = new RetryablePredicate<DriveInfo>(Predicates.not(new DriveClaimed(client)), maxDriveImageTime,
1, TimeUnit.SECONDS);
socketTester = new RetryablePredicate<HostAndPort>(new InetSocketAddressConnect(), maxDriveImageTime, 1,
TimeUnit.SECONDS);
if (template == null || template.getImageId() == null) {
imageId = view.getComputeService().templateBuilder().build().getImage().getId();
}
}
@Test
public void testListServers() throws Exception {
Set<String> servers = client.listServers();

View File

@ -24,13 +24,12 @@ import org.jclouds.compute.internal.BaseComputeServiceLiveTest;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Module;
/**
* @author Adrian Cole
*/
@Test(groups = "live")
@Test(groups = "live", testName = "ElasticStackComputeServiceLiveTest")
public class ElasticStackComputeServiceLiveTest extends BaseComputeServiceLiveTest {
public ElasticStackComputeServiceLiveTest() {
@ -42,13 +41,6 @@ public class ElasticStackComputeServiceLiveTest extends BaseComputeServiceLiveTe
return new SshjSshClientModule();
}
// elasticstack does not support metadata
@Override
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
"node userMetadata did not match %s %s", userMetadata, node);
}
@Override
public void testOptionToNotBlock() {
// start call is blocking anyway.
@ -56,6 +48,6 @@ public class ElasticStackComputeServiceLiveTest extends BaseComputeServiceLiveTe
protected void checkResponseEqualsHostname(ExecResponse execResponse, NodeMetadata node1) {
// hostname is not predictable based on node metadata
assert execResponse.getOutput().trim().equals("ubuntu");
assert execResponse.getOutput().trim().equals("ubuntu") : execResponse.getOutput();
}
}

View File

@ -60,7 +60,6 @@ import org.jclouds.io.payloads.PhantomPayload;
import org.jclouds.io.payloads.StringPayload;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import com.google.common.io.ByteStreams;

View File

@ -46,7 +46,6 @@ import org.jclouds.filesystem.utils.TestUtils;
import org.jclouds.io.payloads.FilePayload;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import com.google.common.io.ByteStreams;

View File

@ -20,7 +20,6 @@ package org.jclouds.openstack.nova.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;

View File

@ -21,8 +21,6 @@ package org.jclouds.openstack.keystone.v2_0;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.functions.ZoneToEndpoint;
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
import org.jclouds.openstack.keystone.v2_0.features.ServiceApi;
import org.jclouds.openstack.keystone.v2_0.features.TenantApi;
@ -30,7 +28,6 @@ import org.jclouds.openstack.keystone.v2_0.features.TokenApi;
import org.jclouds.openstack.keystone.v2_0.features.UserApi;
import org.jclouds.openstack.v2_0.features.ExtensionApi;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam;
import com.google.common.base.Optional;

View File

@ -143,7 +143,7 @@ public class KeystoneRestClientModule<S extends KeystoneApi, A extends KeystoneA
.build(CacheLoader.from(Suppliers.memoize(new Supplier<Set<? extends Extension>>() {
@Override
public Set<? extends Extension> get() {
return keystoneApi.get().getExtensionApi().listExtensions();
return keystoneApi.get().getExtensionApi().list();
}
})));
}

View File

@ -23,6 +23,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ImmutableSet;
@ -105,10 +107,10 @@ public class Access implements Comparable<Access> {
@ConstructorProperties({
"token", "user", "serviceCatalog"
})
protected Access(Token token, User user, Set<Service> serviceCatalog) {
protected Access(Token token, User user, @Nullable Set<Service> serviceCatalog) {
this.token = checkNotNull(token, "token");
this.user = checkNotNull(user, "user");
this.serviceCatalog = ImmutableSet.copyOf(checkNotNull(serviceCatalog, "serviceCatalog"));
this.serviceCatalog = serviceCatalog == null ? ImmutableSet.<Service>of() : ImmutableSet.copyOf(serviceCatalog);
}
/**

View File

@ -0,0 +1,87 @@
/*
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.keystone.v2_0.domain;
import static org.jclouds.http.utils.Queries.parseQueryToMap;
import java.util.Collection;
import java.util.Iterator;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.openstack.v2_0.domain.Link;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
/**
* base class for a paginated collection in openstack
*
* @see <a
* href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/Paginated_Collections-d1e325.html">
* docs</a>
* @author Adrian Cole
*/
@Beta
public class PaginatedCollection<T> extends IterableWithMarker<T> {
@SuppressWarnings({ "rawtypes", "unchecked" })
public static final PaginatedCollection EMPTY = new PaginatedCollection(ImmutableSet.of(), ImmutableSet.of());
private Iterable<T> resources;
private Iterable<Link> links;
protected PaginatedCollection(Iterable<T> resources, Iterable<Link> links) {
this.resources = resources != null ? resources : ImmutableSet.<T> of();
this.links = links != null ? links : ImmutableSet.<Link> of();
}
@Override
public Iterator<T> iterator() {
return resources.iterator();
}
/**
* links that relate to this collection
*/
public Iterable<Link> getLinks() {
return links;
}
@Override
public Optional<Object> nextMarker() {
return FluentIterable.from(getLinks()).filter(new Predicate<Link>() {
@Override
public boolean apply(Link link) {
return Link.Relation.NEXT == link.getRelation();
}
}).transform(new Function<Link, Optional<Object>>() {
@Override
public Optional<Object> apply(Link link) {
Collection<String> markers = parseQueryToMap(link.getHref().getRawQuery()).get("marker");
return Optional.<Object> fromNullable(markers == null ? null : Iterables.get(markers, 0));
}
}).first().or(Optional.absent());
}
}

View File

@ -18,11 +18,13 @@
*/
package org.jclouds.openstack.keystone.v2_0.features;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.collect.PagedIterable;
import org.jclouds.concurrent.Timeout;
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
import org.jclouds.openstack.v2_0.options.PaginationOptions;
/**
* Provides synchronous access to the KeyStone Tenant API.
@ -40,7 +42,9 @@ public interface TenantApi {
/**
* The operation returns a list of tenants which the current token provides access to.
*/
Set<? extends Tenant> list();
PagedIterable<? extends Tenant> list();
PaginatedCollection<? extends Tenant> list(PaginationOptions options);
/**
* Retrieve information about a tenant, by tenant ID

View File

@ -18,8 +18,6 @@
*/
package org.jclouds.openstack.keystone.v2_0.features;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@ -27,14 +25,22 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.collect.PagedIterable;
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.keystone.v2_0.functions.ReturnEmptyPaginatedCollectionOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseTenants;
import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseTenants.ToPagedIterable;
import org.jclouds.openstack.v2_0.options.PaginationOptions;
import org.jclouds.openstack.v2_0.services.Identity;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.SkipEncoding;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.functions.ReturnEmptyPagedIterableOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
@ -57,12 +63,22 @@ public interface TenantAsyncApi {
* @see TenantApi#list()
*/
@GET
@SelectJson("tenants")
@Consumes(MediaType.APPLICATION_JSON)
@Path("/tenants")
@RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<? extends Tenant>> list();
@ResponseParser(ParseTenants.class)
@Transform(ToPagedIterable.class)
@ExceptionParser(ReturnEmptyPagedIterableOnNotFoundOr404.class)
ListenableFuture<? extends PagedIterable<? extends Tenant>> list();
/** @see TenantApi#list(PaginationOptions) */
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Path("/tenants")
@RequestFilters(AuthenticateRequest.class)
@ResponseParser(ParseTenants.class)
@ExceptionParser(ReturnEmptyPaginatedCollectionOnNotFoundOr404.class)
ListenableFuture<? extends PaginatedCollection<? extends Tenant>> list(PaginationOptions options);
/** @see TenantApi#get(String) */
@GET

View File

@ -21,9 +21,12 @@ package org.jclouds.openstack.keystone.v2_0.features;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.collect.PagedIterable;
import org.jclouds.concurrent.Timeout;
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
import org.jclouds.openstack.keystone.v2_0.domain.Role;
import org.jclouds.openstack.keystone.v2_0.domain.User;
import org.jclouds.openstack.v2_0.options.PaginationOptions;
import com.google.common.annotations.Beta;
@ -48,7 +51,9 @@ public interface UserApi {
*
* @return the list of users
*/
Set<? extends User> list();
PagedIterable<? extends User> list();
PaginatedCollection<? extends User> list(PaginationOptions options);
/**
* Retrieve information about a user, by user ID

View File

@ -27,14 +27,23 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.collect.PagedIterable;
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
import org.jclouds.openstack.keystone.v2_0.domain.Role;
import org.jclouds.openstack.keystone.v2_0.domain.User;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.keystone.v2_0.functions.ReturnEmptyPaginatedCollectionOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseUsers;
import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseUsers.ToPagedIterable;
import org.jclouds.openstack.v2_0.options.PaginationOptions;
import org.jclouds.openstack.v2_0.services.Identity;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.SkipEncoding;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.functions.ReturnEmptyPagedIterableOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
@ -43,10 +52,10 @@ import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to User via their REST API.
* <p/>
*
*
* @see UserApi
* @see <a href=
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/User_Operations.html"
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/User_Operations.html"
* />
* @author Adam Lowe
*/
@ -54,14 +63,26 @@ import com.google.common.util.concurrent.ListenableFuture;
@SkipEncoding({ '/', '=' })
public interface UserAsyncApi {
/** @see UserApi#list() */
/**
* @see UserApi#list()
*/
@GET
@SelectJson("users")
@Consumes(MediaType.APPLICATION_JSON)
@Path("/users")
@RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<? extends User>> list();
@ResponseParser(ParseUsers.class)
@Transform(ToPagedIterable.class)
@ExceptionParser(ReturnEmptyPagedIterableOnNotFoundOr404.class)
ListenableFuture<? extends PagedIterable<? extends User>> list();
/** @see UserApi#list(PaginationOptions) */
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Path("/users")
@RequestFilters(AuthenticateRequest.class)
@ResponseParser(ParseUsers.class)
@ExceptionParser(ReturnEmptyPaginatedCollectionOnNotFoundOr404.class)
ListenableFuture<? extends PaginatedCollection<? extends User>> list(PaginationOptions options);
/** @see UserApi#get(String) */
@GET
@ -71,7 +92,7 @@ public interface UserAsyncApi {
@RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends User> get(@PathParam("userId") String userId);
/** @see UserApi#getByName(String) */
@GET
@SelectJson("user")
@ -80,7 +101,7 @@ public interface UserAsyncApi {
@RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends User> getByName(@QueryParam("name") String userName);
/** @see UserApi#listRolesOfUser(String) */
@GET
@SelectJson("roles")
@ -97,5 +118,6 @@ public interface UserAsyncApi {
@Path("/tenants/{tenantId}/users/{userId}/roles")
@RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<? extends Role>> listRolesOfUserOnTenant(@PathParam("userId") String userId, @PathParam("tenantId") String tenantId);
ListenableFuture<? extends Set<? extends Role>> listRolesOfUserOnTenant(@PathParam("userId") String userId,
@PathParam("tenantId") String tenantId);
}

View File

@ -0,0 +1,58 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.keystone.v2_0.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.http.functions.ReturnTrueOn404;
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
import org.jclouds.rest.ResourceNotFoundException;
import com.google.common.base.Function;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ReturnEmptyPaginatedCollectionOnNotFoundOr404 implements Function<Exception, Object> {
private final ReturnTrueOn404 rto404;
@Inject
private ReturnEmptyPaginatedCollectionOnNotFoundOr404(ReturnTrueOn404 rto404) {
this.rto404 = checkNotNull(rto404, "rto404");
}
public Object apply(Exception from) {
Iterable<ResourceNotFoundException> throwables = Iterables.filter(Throwables.getCausalChain(from),
ResourceNotFoundException.class);
if (Iterables.size(throwables) >= 1) {
return PaginatedCollection.EMPTY;
} else if (rto404.apply(from)) {
return PaginatedCollection.EMPTY;
}
throw Throwables.propagate(from);
}
}

View File

@ -0,0 +1,96 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.keystone.v2_0.functions.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.marker;
import java.beans.ConstructorProperties;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.internal.CallerArg0ToPagedIterable;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.json.Json;
import org.jclouds.openstack.keystone.v2_0.KeystoneApi;
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
import org.jclouds.openstack.keystone.v2_0.features.TenantApi;
import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseTenants.Tenants;
import org.jclouds.openstack.v2_0.domain.Link;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.inject.TypeLiteral;
/**
* boiler plate until we determine a better way
*
* @author Adrian Cole
*/
@Beta
@Singleton
public class ParseTenants extends ParseJson<Tenants<? extends Tenant>> {
static class Tenants<T extends Tenant> extends PaginatedCollection<T> {
@ConstructorProperties({ "tenants", "tenants_links" })
protected Tenants(Iterable<T> tenants, Iterable<Link> tenants_links) {
super(tenants, tenants_links);
}
}
@Inject
public ParseTenants(Json json) {
super(json, new TypeLiteral<Tenants<? extends Tenant>>() {
});
}
public static class ToPagedIterable extends CallerArg0ToPagedIterable<Tenant, ToPagedIterable> {
private final KeystoneApi api;
@Inject
protected ToPagedIterable(KeystoneApi api) {
this.api = checkNotNull(api, "api");
}
@Override
protected Function<Object, IterableWithMarker<Tenant>> markerToNextForCallingArg0(final String ignored) {
final TenantApi tenantApi = api.getTenantApi().get();
return new Function<Object, IterableWithMarker<Tenant>>() {
@SuppressWarnings("unchecked")
@Override
public IterableWithMarker<Tenant> apply(Object input) {
return IterableWithMarker.class.cast(tenantApi.list(marker(input.toString())));
}
@Override
public String toString() {
return "listTenants()";
}
};
}
}
}

View File

@ -0,0 +1,96 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.keystone.v2_0.functions.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.marker;
import java.beans.ConstructorProperties;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.internal.CallerArg0ToPagedIterable;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.json.Json;
import org.jclouds.openstack.keystone.v2_0.KeystoneApi;
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
import org.jclouds.openstack.keystone.v2_0.domain.User;
import org.jclouds.openstack.keystone.v2_0.features.UserApi;
import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseUsers.Users;
import org.jclouds.openstack.v2_0.domain.Link;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.inject.TypeLiteral;
/**
* boiler plate until we determine a better way
*
* @author Adrian Cole
*/
@Beta
@Singleton
public class ParseUsers extends ParseJson<Users<? extends User>> {
static class Users<T extends User> extends PaginatedCollection<T> {
@ConstructorProperties({ "users", "users_links" })
protected Users(Iterable<T> users, Iterable<Link> users_links) {
super(users, users_links);
}
}
@Inject
public ParseUsers(Json json) {
super(json, new TypeLiteral<Users<? extends User>>() {
});
}
public static class ToPagedIterable extends CallerArg0ToPagedIterable<User, ToPagedIterable> {
private final KeystoneApi api;
@Inject
protected ToPagedIterable(KeystoneApi api) {
this.api = checkNotNull(api, "api");
}
@Override
protected Function<Object, IterableWithMarker<User>> markerToNextForCallingArg0(final String ignored) {
final UserApi userApi = api.getUserApi().get();
return new Function<Object, IterableWithMarker<User>>() {
@SuppressWarnings("unchecked")
@Override
public IterableWithMarker<User> apply(Object input) {
return IterableWithMarker.class.cast(userApi.list(marker(input.toString())));
}
@Override
public String toString() {
return "listUsers()";
}
};
}
}
}

View File

@ -25,18 +25,17 @@ import java.net.URI;
import javax.inject.Named;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.base.Optional;
/**
* For convenience, resources contain links to themselves. This allows a api to easily obtain a
* resource URIs rather than to construct them.
*
*
* @author AdrianCole
* @see <a href= "http://docs.openstack.org/api/openstack-compute/1.1/content/LinksReferences.html"
/>
* />
*/
public class Link {
/**
@ -57,9 +56,17 @@ public class Link {
*/
DESCRIBEDBY,
/**
* an alternate representation of the resource. For example, an OpenStack Compute image may
* have an alternate representation in the OpenStack Image service.
* Indicates that the link's context is a part of a series, and that the next in the series is
* the link target.
*/
NEXT,
/**
* Indicates that the link's context is a part of a series, and that the previous in the
* series is the link target.
*/
PREVIOUS,
ALTERNATE,
/**
* the value returned by the OpenStack service was not recognized.
@ -83,80 +90,67 @@ public class Link {
return new Link(relation, null, href);
}
public static Link create(Relation relation,String type, URI href) {
return new Link(relation, type, href);
public static Link create(Relation relation, String type, URI href) {
return new Link(relation, Optional.fromNullable(type), href);
}
public static Builder<?> builder() {
return new ConcreteBuilder();
public static Builder builder() {
return new Builder();
}
public Builder<?> toBuilder() {
return new ConcreteBuilder().fromLink(this);
public Builder toBuilder() {
return builder().fromLink(this);
}
public static abstract class Builder<T extends Builder<T>> {
protected abstract T self();
public static class Builder {
protected Link.Relation relation;
protected String type;
protected Optional<String> type = Optional.absent();
protected URI href;
/**
* @see Link#getRelation()
*/
public T relation(Link.Relation relation) {
public Builder relation(Link.Relation relation) {
this.relation = relation;
return self();
return this;
}
/**
* @see Link#getType()
*/
public T type(String type) {
this.type = type;
return self();
public Builder type(String type) {
this.type = Optional.fromNullable(type);
return this;
}
/**
* @see Link#getHref()
*/
public T href(URI href) {
public Builder href(URI href) {
this.href = href;
return self();
return this;
}
public Link build() {
return new Link(relation, type, href);
}
public T fromLink(Link in) {
return this
.relation(in.getRelation())
.type(in.getType())
.href(in.getHref());
}
}
private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
@Override
protected ConcreteBuilder self() {
return this;
public Builder fromLink(Link in) {
return this.relation(in.getRelation()).type(in.getType().orNull()).href(in.getHref());
}
}
@Named("rel")
private final Link.Relation relation;
private final String type;
private final Optional<String> type;
private final URI href;
@ConstructorProperties({
"rel", "type", "href"
})
protected Link(Link.Relation relation, @Nullable String type, URI href) {
this.relation = checkNotNull(relation, "relation");
this.type = type;
@ConstructorProperties({ "rel", "type", "href" })
protected Link(Link.Relation relation, Optional<String> type, URI href) {
this.href = checkNotNull(href, "href");
this.relation = checkNotNull(relation, "relation of %s", href);
this.type = (type == null) ? Optional.<String> absent() : type;
}
/**
@ -167,7 +161,7 @@ public class Link {
* of the resource. For example, an OpenStack Compute image may have an alternate representation
* in the OpenStack Image service. Note that the type attribute here is used to provide a hint as
* to the type of representation to expect when following the link.
*
*
* @return the relation of the resource in the current OpenStack deployment
*/
public Link.Relation getRelation() {
@ -177,8 +171,7 @@ public class Link {
/**
* @return the type of the resource or null if not specified
*/
@Nullable
public String getType() {
public Optional<String> getType() {
return this.type;
}
@ -196,17 +189,18 @@ public class Link {
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
Link that = Link.class.cast(obj);
return Objects.equal(this.relation, that.relation)
&& Objects.equal(this.type, that.type)
&& Objects.equal(this.href, that.href);
return Objects.equal(this.relation, that.relation) && Objects.equal(this.type, that.type)
&& Objects.equal(this.href, that.href);
}
protected ToStringHelper string() {
return Objects.toStringHelper(this)
.add("relation", relation).add("type", type).add("href", href);
return Objects.toStringHelper(this).omitNullValues().add("relation", relation).add("type", type.orNull())
.add("href", href);
}
@Override

View File

@ -28,7 +28,7 @@ import org.jclouds.openstack.v2_0.domain.Extension;
* Provides asynchronous access to Extensions via their REST API.
* <p/>
*
* @see ExtensionApi
* @see ExtensionAsyncApi
* @see <a href=
* "http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html"
* />
@ -42,7 +42,7 @@ public interface ExtensionApi {
*
* @return all extensions
*/
Set<? extends Extension> listExtensions();
Set<? extends Extension> list();
/**
* Extensions may also be queried individually by their unique alias.
@ -51,6 +51,6 @@ public interface ExtensionApi {
* id of the extension
* @return extension or null if not found
*/
Extension getExtensionByAlias(String alias);
Extension get(String alias);
}

View File

@ -52,23 +52,23 @@ import com.google.common.util.concurrent.ListenableFuture;
public interface ExtensionAsyncApi {
/**
* @see ExtensionApi#listExtensions
* @see ExtensionApi#list
*/
@GET
@SelectJson("extensions")
@Consumes(MediaType.APPLICATION_JSON)
@Path("/extensions")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<? extends Extension>> listExtensions();
ListenableFuture<? extends Set<? extends Extension>> list();
/**
* @see ExtensionApi#getExtensionByAlias
* @see ExtensionApi#get
*/
@GET
@SelectJson("extension")
@Consumes(MediaType.APPLICATION_JSON)
@Path("/extensions/{alias}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends Extension> getExtensionByAlias(@PathParam("alias") String id);
ListenableFuture<? extends Extension> get(@PathParam("alias") String id);
}

View File

@ -28,30 +28,26 @@ import org.jclouds.http.options.BaseHttpRequestOptions;
/**
* Options used to control paginated results (aka list commands).
*
* @see <a href="http://docs.rackspacecloud.com/servers/api/cs-devguide-latest.pdf" />
* @see <a href=
* "http://docs.openstack.org/api/openstack-compute/2/content/Paginated_Collections-d1e664.html"
* />
* @author Adrian Cole
*/
public class BaseListOptions extends BaseHttpRequestOptions {
public static final BaseListOptions NONE = new BaseListOptions();
public class PaginationOptions extends BaseHttpRequestOptions {
/**
* Only return objects changed since this time.
*/
public BaseListOptions changesSince(Date ifModifiedSince) {
this.queryParameters.put("changes-since", checkNotNull(ifModifiedSince, "ifModifiedSince")
.getTime()
/ 1000 + "");
public PaginationOptions changesSince(Date ifModifiedSince) {
this.queryParameters.put("changes-since", checkNotNull(ifModifiedSince, "ifModifiedSince").getTime() / 1000 + "");
return this;
}
/**
* Indicates where to begin listing. The list will only include objects that occur after the
* offset. This is convenient for pagination: To get the next page of results use the last result
* number of the current page + current page offset as the offset.
* The marker parameter is the ID of the last item in the previous list. Items are sorted by
* create time in descending order. When a create time is not available they are sorted by ID.
*/
public BaseListOptions startAt(long offset) {
checkState(offset >= 0, "offset must be >= 0");
queryParameters.put("offset", Long.toString(checkNotNull(offset, "offset")));
public PaginationOptions marker(String marker) {
queryParameters.put("marker", checkNotNull(marker, "marker"));
return this;
}
@ -63,7 +59,7 @@ public class BaseListOptions extends BaseHttpRequestOptions {
* <p/>
* Note that list operations never return itemNotFound (404) faults.
*/
public BaseListOptions maxResults(int limit) {
public PaginationOptions limit(int limit) {
checkState(limit >= 0, "limit must be >= 0");
checkState(limit <= 10000, "limit must be <= 10000");
queryParameters.put("limit", Integer.toString(limit));
@ -73,26 +69,26 @@ public class BaseListOptions extends BaseHttpRequestOptions {
public static class Builder {
/**
* @see BaseListOptions#startAt(long)
* @see PaginationOptions#marker(String)
*/
public static BaseListOptions startAt(long prefix) {
BaseListOptions options = new BaseListOptions();
return options.startAt(prefix);
public static PaginationOptions marker(String marker) {
PaginationOptions options = new PaginationOptions();
return options.marker(marker);
}
/**
* @see BaseListOptions#maxResults
* @see PaginationOptions#limit
*/
public static BaseListOptions maxResults(int maxKeys) {
BaseListOptions options = new BaseListOptions();
return options.maxResults(maxKeys);
public static PaginationOptions limit(int limit) {
PaginationOptions options = new PaginationOptions();
return options.limit(limit);
}
/**
* @see BaseListOptions#changesSince(Date)
* @see PaginationOptions#changesSince(Date)
*/
public static BaseListOptions changesSince(Date since) {
BaseListOptions options = new BaseListOptions();
public static PaginationOptions changesSince(Date since) {
PaginationOptions options = new PaginationOptions();
return options.changesSince(since);
}

View File

@ -91,7 +91,7 @@ public class LinkPredicates {
return new Predicate<Link>() {
@Override
public boolean apply(Link link) {
return type.equals(link.getType());
return type.equals(link.getType().orNull());
}
@Override

View File

@ -31,6 +31,7 @@ import org.jclouds.http.HttpResponse;
import org.jclouds.openstack.keystone.v2_0.KeystoneApi;
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneRestApiExpectTest;
import org.jclouds.openstack.v2_0.options.PaginationOptions;
import org.jclouds.rest.AuthorizationException;
import org.testng.annotations.Test;
@ -47,7 +48,10 @@ public class TenantApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneA
public TenantApiExpectTest(){
endpoint = "https://csnode.jclouds.org:35357";
}
Set<Tenant> expectedTenants = ImmutableSet.of(Tenant.builder().name("demo").id("05d1dc7af71646deba64cfc17b81bec0")
.build(), Tenant.builder().name("admin").id("7aa2e17ec29f44d193c48feaba0852cc").build());
public void testListTenants() {
TenantApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPassword,
@ -56,16 +60,28 @@ public class TenantApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneA
HttpResponse.builder().statusCode(200).payload(
payloadFromResourceWithContentType("/tenant_list.json", APPLICATION_JSON)).build())
.getTenantApi().get();
Set<? extends Tenant> tenants = api.list();
assertEquals(api.list().concat().toImmutableSet(), expectedTenants);
}
public void testListTenantsPage() {
TenantApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPassword,
responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/v2.0/tenants").build(),
HttpResponse.builder().statusCode(200).payload(
payloadFromResourceWithContentType("/tenant_list.json", APPLICATION_JSON)).build())
.getTenantApi().get();
Set<? extends Tenant> tenants = api.list(new PaginationOptions()).toImmutableSet();
assertNotNull(tenants);
assertFalse(tenants.isEmpty());
Set<Tenant> expected = ImmutableSet.of(Tenant.builder().name("demo").id("05d1dc7af71646deba64cfc17b81bec0")
.build(), Tenant.builder().name("admin").id("7aa2e17ec29f44d193c48feaba0852cc").build());
assertEquals(tenants, expected);
assertEquals(tenants, expectedTenants);
}
// this is not a compatible format of json per:
// http://docs.openstack.org/api/openstack-identity-service/2.0/content/Paginated_Collections-d1e325.html
@Test(enabled = false)
public void testListTenantsATT() {
TenantApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPassword,
@ -74,15 +90,15 @@ public class TenantApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneA
HttpResponse.builder().statusCode(200).payload(
payloadFromResourceWithContentType("/tenant_list_att.json", APPLICATION_JSON)).build())
.getTenantApi().get();
Set<? extends Tenant> tenants = api.list();
assertNotNull(tenants);
assertFalse(tenants.isEmpty());
Set<Tenant> expected = ImmutableSet.of(Tenant.builder().name("this-is-a-test").id("14").description("None").build());
assertEquals(tenants, expected);
assertEquals(api.list().concat().toImmutableSet(), expected);
}
// this is not a compatible format of json per:
// http://docs.openstack.org/api/openstack-identity-service/2.0/content/Paginated_Collections-d1e325.html
@Test(enabled = false)
public void testListTenantsFailNotFound() {
TenantApi api = requestsSendResponses(keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/v2.0/tenants").build(), HttpResponse.builder().statusCode(404).build())

View File

@ -38,7 +38,7 @@ public class TenantApiLiveTest extends BaseKeystoneApiLiveTest {
public void testTenants() {
TenantApi api = keystoneContext.getApi().getTenantApi().get();
Set<? extends Tenant> result = api.list();
Set<? extends Tenant> result = api.list().concat().toImmutableSet();
assertNotNull(result);
assertFalse(result.isEmpty());
@ -56,7 +56,7 @@ public class TenantApiLiveTest extends BaseKeystoneApiLiveTest {
TenantApi api = keystoneContext.getApi().getTenantApi().get();
for (Tenant tenant : api.list()) {
for (Tenant tenant : api.list().concat()) {
Tenant aTenant = api.getByName(tenant.getName());
assertNotNull(aTenant, "get returned null for tenant: " + tenant);

View File

@ -30,9 +30,11 @@ import java.util.Set;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException;
import org.jclouds.openstack.keystone.v2_0.KeystoneApi;
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
import org.jclouds.openstack.keystone.v2_0.domain.Role;
import org.jclouds.openstack.keystone.v2_0.domain.User;
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneRestApiExpectTest;
import org.jclouds.openstack.v2_0.options.PaginationOptions;
import org.jclouds.rest.AuthorizationException;
import org.testng.annotations.Test;
@ -43,31 +45,50 @@ import com.google.common.collect.ImmutableSet;
*
* @author Adam Lowe
*/
@Test(testName = "UserApiExpectTest")
@Test(singleThreaded = true, testName = "UserApiExpectTest")
public class UserApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneApi> {
public UserApiExpectTest(){
endpoint = "https://csnode.jclouds.org:35357";
}
Set<User> expectedUsers = ImmutableSet.of(
User.builder().name("nova").id("e021dfd758eb44a89f1c57c8ef3be8e2").build(),
User.builder().name("glance").id("3f6c1c9ba993495ead7d2eb2192e284f").build(),
User.builder().name("demo").id("667b2e1420604df8b67cd8ea57d4ee64").build(),
User.builder().name("admin").id("2b9b606181634ae9ac86fd95a8bc2cde").build()
);
public void testListUsers() {
UserApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/v2.0/users").build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResourceWithContentType("/user_list.json", APPLICATION_JSON)).build())
.getUserApi().get();
Set<? extends User> users = api.list();
assertEquals(api.list().concat().toImmutableSet(), expectedUsers);
}
public void testListUsersPage() {
UserApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/v2.0/users").build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResourceWithContentType("/user_list.json", APPLICATION_JSON)).build())
.getUserApi().get();
PaginatedCollection<? extends User> users = api.list(new PaginationOptions());
assertNotNull(users);
assertFalse(users.isEmpty());
Set<User> expected = ImmutableSet.of(
User.builder().name("nova").id("e021dfd758eb44a89f1c57c8ef3be8e2").build(),
User.builder().name("glance").id("3f6c1c9ba993495ead7d2eb2192e284f").build(),
User.builder().name("demo").id("667b2e1420604df8b67cd8ea57d4ee64").build(),
User.builder().name("admin").id("2b9b606181634ae9ac86fd95a8bc2cde").build()
);
assertEquals(users, expected);
assertEquals(users.toImmutableSet(), expectedUsers);
}
public void testListUsersNotFound() {
UserApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/v2.0/users").build(),
HttpResponse.builder().statusCode(404).build()).getUserApi().get();
assertEquals( api.list(new PaginationOptions()).size(), 0);
}
@Test(expectedExceptions = AuthorizationException.class)
@ -76,7 +97,7 @@ public class UserApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneApi
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/v2.0/users").build(),
HttpResponse.builder().statusCode(401).build()).getUserApi().get();
api.list();
api.list(new PaginationOptions());
}
public void testGetUser() {

View File

@ -41,7 +41,7 @@ public class UserApiLiveTest extends BaseKeystoneApiLiveTest {
public void testUsers() {
UserApi api = keystoneContext.getApi().getUserApi().get();
Set<? extends User> users = api.list();
Set<? extends User> users = api.list().concat().toImmutableSet();
assertNotNull(users);
assertFalse(users.isEmpty());
for (User user : users) {
@ -54,10 +54,9 @@ public class UserApiLiveTest extends BaseKeystoneApiLiveTest {
public void testUserRolesOnTenant() {
UserApi api = keystoneContext.getApi().getUserApi().get();
Set<? extends User> users = api.list();
Set<? extends Tenant> tenants = keystoneContext.getApi().getTenantApi().get().list();
Set<? extends Tenant> tenants = keystoneContext.getApi().getTenantApi().get().list().concat().toImmutableSet();
for (User user : users) {
for (User user : api.list().concat()) {
for (Tenant tenant : tenants) {
Set<? extends Role> roles = api.listRolesOfUserOnTenant(user.getId(), tenant.getId());
for (Role role : roles) {
@ -71,7 +70,7 @@ public class UserApiLiveTest extends BaseKeystoneApiLiveTest {
public void testListRolesOfUser() {
UserApi api = keystoneContext.getApi().getUserApi().get();
for (User user : api.list()) {
for (User user : api.list().concat()) {
Set<? extends Role> roles = api.listRolesOfUser(user.getId());
for (Role role : roles) {
assertNotNull(role.getId());
@ -83,7 +82,7 @@ public class UserApiLiveTest extends BaseKeystoneApiLiveTest {
public void testUsersByName() {
UserApi api = keystoneContext.getApi().getUserApi().get();
for (User user : api.list()) {
for (User user : api.list().concat()) {
User aUser = api.getByName(user.getName());
assertEquals(aUser, user);
}

View File

@ -5,13 +5,10 @@ import static org.testng.Assert.assertEquals;
import java.net.URI;
import java.util.Set;
import javax.inject.Named;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.internal.ClassMethodArgsAndReturnVal;
import org.jclouds.openstack.v2_0.ServiceType;
import org.jclouds.openstack.v2_0.domain.Extension;
import org.jclouds.openstack.v2_0.functions.PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet;
import org.jclouds.rest.annotations.Delegate;
import org.testng.annotations.Test;

View File

@ -18,9 +18,9 @@
*/
package org.jclouds.openstack.v2_0.options;
import static org.jclouds.openstack.v2_0.options.BaseListOptions.Builder.changesSince;
import static org.jclouds.openstack.v2_0.options.BaseListOptions.Builder.maxResults;
import static org.jclouds.openstack.v2_0.options.BaseListOptions.Builder.startAt;
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.changesSince;
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.limit;
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.marker;
import static org.testng.Assert.assertEquals;
import java.util.Date;
@ -34,44 +34,44 @@ import com.google.common.collect.ImmutableList;
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class BaseListOptionsTest {
@Test(groups = "unit", testName = "PaginationOptionsTest")
public class PaginationOptionsTest {
public void testChangesSince() {
Date ifModifiedSince = new Date();
BaseListOptions options = new BaseListOptions().changesSince(ifModifiedSince);
assertEquals(ImmutableList.of(ifModifiedSince.getTime() / 1000 + ""), options
.buildQueryParameters().get("changes-since"));
PaginationOptions options = new PaginationOptions().changesSince(ifModifiedSince);
assertEquals(ImmutableList.of(ifModifiedSince.getTime() / 1000 + ""),
options.buildQueryParameters().get("changes-since"));
}
public void testStartAt() {
long offset = 1;
BaseListOptions options = new BaseListOptions().startAt(offset);
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("offset"));
public void testMarker() {
String marker = "52415800-8b69-11e0-9b19-734f6f006e54";
PaginationOptions options = new PaginationOptions().marker(marker);
assertEquals(ImmutableList.of(marker), options.buildQueryParameters().get("marker"));
}
public void testMaxResults() {
int limit = 1;
BaseListOptions options = new BaseListOptions().maxResults(limit);
PaginationOptions options = new PaginationOptions().limit(limit);
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("limit"));
}
public void testChangesSinceStatic() {
Date ifModifiedSince = new Date();
BaseListOptions options = changesSince(ifModifiedSince);
assertEquals(ImmutableList.of(ifModifiedSince.getTime() / 1000 + ""), options
.buildQueryParameters().get("changes-since"));
PaginationOptions options = changesSince(ifModifiedSince);
assertEquals(ImmutableList.of(ifModifiedSince.getTime() / 1000 + ""),
options.buildQueryParameters().get("changes-since"));
}
public void testStartAtStatic() {
long offset = 1;
BaseListOptions options = startAt(offset);
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("offset"));
public void testMarkerStatic() {
String marker = "52415800-8b69-11e0-9b19-734f6f006e54";
PaginationOptions options = marker(marker);
assertEquals(ImmutableList.of(marker), options.buildQueryParameters().get("marker"));
}
public void testMaxResultsStatic() {
int limit = 1;
BaseListOptions options = maxResults(limit);
PaginationOptions options = limit(limit);
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("limit"));
}
}

View File

@ -25,7 +25,7 @@ import org.jclouds.concurrent.Timeout;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Zone;
import org.jclouds.location.functions.ZoneToEndpoint;
import org.jclouds.openstack.nova.v2_0.extensions.AdminActionsApi;
import org.jclouds.openstack.nova.v2_0.extensions.ServerAdminApi;
import org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsApi;
import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPApi;
import org.jclouds.openstack.nova.v2_0.extensions.HostAdministrationApi;
@ -156,7 +156,7 @@ public interface NovaApi {
* Provides synchronous access to Server Admin Actions features.
*/
@Delegate
Optional<? extends AdminActionsApi> getAdminActionsExtensionForZone(
Optional<? extends ServerAdminApi> getServerAdminExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/**

View File

@ -23,7 +23,7 @@ import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Zone;
import org.jclouds.location.functions.ZoneToEndpoint;
import org.jclouds.openstack.nova.v2_0.extensions.AdminActionsAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.ServerAdminAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.HostAdministrationAsyncApi;
@ -155,7 +155,7 @@ public interface NovaAsyncApi {
* Provides asynchronous access to Server Admin Actions features.
*/
@Delegate
Optional<? extends AdminActionsAsyncApi> getAdminActionsExtensionForZone(
Optional<? extends ServerAdminAsyncApi> getServerAdminExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/**

View File

@ -0,0 +1,49 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v2_0.binders;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.http.HttpRequest;
import org.jclouds.json.Json;
import org.jclouds.rest.binders.BindToJsonPayload;
import com.google.common.collect.ImmutableMap;
/**
*
* @author Adrian Cole
*/
@Singleton
public class BindMetadataToJsonPayload extends BindToJsonPayload {
@Inject
public BindMetadataToJsonPayload(Json jsonBinder) {
super(jsonBinder);
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
return bindToRequest(request,
(Object) ImmutableMap.of("metadata", ImmutableMap.of(postParams.get("key"), postParams.get("value"))));
}
}

View File

@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
import static org.jclouds.openstack.nova.v2_0.predicates.KeyPairPredicates.nameMatches;
import java.util.Map;
import java.util.Set;
@ -65,7 +66,6 @@ import org.jclouds.openstack.nova.v2_0.domain.zonescoped.SecurityGroupInZone;
import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndName;
import org.jclouds.openstack.nova.v2_0.extensions.KeyPairApi;
import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupApi;
import org.jclouds.openstack.nova.v2_0.predicates.KeyPairPredicates;
import org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates;
import org.jclouds.scriptbuilder.functions.InitAdminAccess;
@ -138,11 +138,11 @@ public class NovaComputeService extends BaseComputeService {
Optional<? extends SecurityGroupApi> securityGroupApi = novaApi.getSecurityGroupExtensionForZone(zoneId);
if (securityGroupApi.isPresent()) {
for (String group : groups) {
for (SecurityGroup securityGroup : Iterables.filter(securityGroupApi.get().listSecurityGroups(),
for (SecurityGroup securityGroup : Iterables.filter(securityGroupApi.get().list(),
SecurityGroupPredicates.nameMatches(namingConvention.create().containsGroup(group)))) {
ZoneAndName zoneAndName = ZoneAndName.fromZoneAndName(zoneId, securityGroup.getName());
logger.debug(">> deleting securityGroup(%s)", zoneAndName);
securityGroupApi.get().deleteSecurityGroup(securityGroup.getId());
securityGroupApi.get().delete(securityGroup.getId());
// TODO: test this clear happens
securityGroupMap.invalidate(zoneAndName);
logger.debug("<< deleted securityGroup(%s)", zoneAndName);
@ -155,16 +155,13 @@ public class NovaComputeService extends BaseComputeService {
Optional<? extends KeyPairApi> keyPairApi = novaApi.getKeyPairExtensionForZone(zoneId);
if (keyPairApi.isPresent()) {
for (String group : groups) {
for (Map<String, ? extends KeyPair> view : keyPairApi.get().listKeyPairs()) {
for (KeyPair pair : Iterables.filter(view.values(),
KeyPairPredicates.nameMatches(namingConvention.create().containsGroup(group)))) {
ZoneAndName zoneAndName = ZoneAndName.fromZoneAndName(zoneId, pair.getName());
logger.debug(">> deleting keypair(%s)", zoneAndName);
keyPairApi.get().deleteKeyPair(pair.getName());
// TODO: test this clear happens
keyPairCache.invalidate(zoneAndName);
logger.debug("<< deleted keypair(%s)", zoneAndName);
}
for (KeyPair pair : keyPairApi.get().list().filter(nameMatches(namingConvention.create().containsGroup(group)))) {
ZoneAndName zoneAndName = ZoneAndName.fromZoneAndName(zoneId, pair.getName());
logger.debug(">> deleting keypair(%s)", zoneAndName);
keyPairApi.get().delete(pair.getName());
// TODO: test this clear happens
keyPairCache.invalidate(zoneAndName);
logger.debug("<< deleted keypair(%s)", zoneAndName);
}
keyPairCache.invalidate(ZoneAndName.fromZoneAndName(zoneId,
namingConvention.create().sharedNameForGroup(group)));

View File

@ -124,8 +124,8 @@ public class NovaComputeServiceAdapter implements
String flavorId = template.getHardware().getProviderId();
logger.debug(">> creating new server zone(%s) name(%s) image(%s) flavor(%s) options(%s)", zoneId, name, imageId, flavorId, options);
ServerCreated lightweightServer = novaApi.getServerApiForZone(zoneId).createServer(name, imageId, flavorId, options);
Server server = novaApi.getServerApiForZone(zoneId).getServer(lightweightServer.getId());
ServerCreated lightweightServer = novaApi.getServerApiForZone(zoneId).create(name, imageId, flavorId, options);
Server server = novaApi.getServerApiForZone(zoneId).get(lightweightServer.getId());
logger.trace("<< server(%s)", server.getId());
@ -140,7 +140,7 @@ public class NovaComputeServiceAdapter implements
public Iterable<FlavorInZone> listHardwareProfiles() {
Builder<FlavorInZone> builder = ImmutableSet.builder();
for (final String zoneId : zoneIds.get()) {
builder.addAll(transform(novaApi.getFlavorApiForZone(zoneId).listFlavorsInDetail(),
builder.addAll(transform(novaApi.getFlavorApiForZone(zoneId).listInDetail().concat(),
new Function<Flavor, FlavorInZone>() {
@Override
@ -159,7 +159,7 @@ public class NovaComputeServiceAdapter implements
Set<String> zones = zoneIds.get();
checkState(zones.size() > 0, "no zones found in supplier %s", zoneIds);
for (final String zoneId : zones) {
Set<? extends Image> images = novaApi.getImageApiForZone(zoneId).listImagesInDetail();
Set<? extends Image> images = novaApi.getImageApiForZone(zoneId).listInDetail().concat().toImmutableSet();
if (images.size() == 0) {
logger.debug("no images found in zone %s", zoneId);
continue;
@ -194,8 +194,8 @@ public class NovaComputeServiceAdapter implements
public Iterable<ServerInZone> listNodes() {
Builder<ServerInZone> builder = ImmutableSet.builder();
for (final String zoneId : zoneIds.get()) {
builder.addAll(transform(novaApi.getServerApiForZone(zoneId).listServersInDetail(),
new Function<Server, ServerInZone>() {
builder.addAll(novaApi.getServerApiForZone(zoneId).listInDetail().concat()
.transform(new Function<Server, ServerInZone>() {
@Override
public ServerInZone apply(Server arg0) {
@ -216,14 +216,14 @@ public class NovaComputeServiceAdapter implements
@Override
public ServerInZone getNode(String id) {
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
Server server = novaApi.getServerApiForZone(zoneAndId.getZone()).getServer(zoneAndId.getId());
Server server = novaApi.getServerApiForZone(zoneAndId.getZone()).get(zoneAndId.getId());
return server == null ? null : new ServerInZone(server, zoneAndId.getZone());
}
@Override
public ImageInZone getImage(String id) {
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
Image image = novaApi.getImageApiForZone(zoneAndId.getZone()).getImage(zoneAndId.getId());
Image image = novaApi.getImageApiForZone(zoneAndId.getZone()).get(zoneAndId.getId());
return image == null ? null : new ImageInZone(image, zoneAndId.getZone());
}
@ -237,20 +237,20 @@ public class NovaComputeServiceAdapter implements
logger.warn(e, "<< error removing and deallocating ip from node(%s): %s", id, e.getMessage());
}
}
novaApi.getServerApiForZone(zoneAndId.getZone()).deleteServer(zoneAndId.getId());
novaApi.getServerApiForZone(zoneAndId.getZone()).delete(zoneAndId.getId());
}
@Override
public void rebootNode(String id) {
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
novaApi.getServerApiForZone(zoneAndId.getZone()).rebootServer(zoneAndId.getId(), RebootType.HARD);
novaApi.getServerApiForZone(zoneAndId.getZone()).reboot(zoneAndId.getId(), RebootType.HARD);
}
@Override
public void resumeNode(String id) {
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
if (novaApi.getAdminActionsExtensionForZone(zoneAndId.getZone()).isPresent()) {
novaApi.getAdminActionsExtensionForZone(zoneAndId.getZone()).get().resumeServer(zoneAndId.getId());
if (novaApi.getServerAdminExtensionForZone(zoneAndId.getZone()).isPresent()) {
novaApi.getServerAdminExtensionForZone(zoneAndId.getZone()).get().resume(zoneAndId.getId());
}
throw new UnsupportedOperationException("resume requires installation of the Admin Actions extension");
}
@ -258,8 +258,8 @@ public class NovaComputeServiceAdapter implements
@Override
public void suspendNode(String id) {
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
if (novaApi.getAdminActionsExtensionForZone(zoneAndId.getZone()).isPresent()) {
novaApi.getAdminActionsExtensionForZone(zoneAndId.getZone()).get().suspendServer(zoneAndId.getId());
if (novaApi.getServerAdminExtensionForZone(zoneAndId.getZone()).isPresent()) {
novaApi.getServerAdminExtensionForZone(zoneAndId.getZone()).get().suspend(zoneAndId.getId());
}
throw new UnsupportedOperationException("suspend requires installation of the Admin Actions extension");
}

View File

@ -84,7 +84,7 @@ public class NovaImageExtension implements ImageExtension {
@Override
public ImageTemplate buildImageTemplateFromNode(String name, final String id) {
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
Server server = novaApi.getServerApiForZone(zoneAndId.getZone()).getServer(zoneAndId.getId());
Server server = novaApi.getServerApiForZone(zoneAndId.getZone()).get(zoneAndId.getId());
if (server == null)
throw new NoSuchElementException("Cannot find server with id: " + zoneAndId);
CloneImageTemplate template = new ImageTemplateBuilder.CloneImageTemplateBuilder().nodeId(id).name(name).build();
@ -119,7 +119,7 @@ public class NovaImageExtension implements ImageExtension {
public boolean deleteImage(String id) {
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
try {
this.novaApi.getImageApiForZone(zoneAndId.getZone()).deleteImage(zoneAndId.getId());
this.novaApi.getImageApiForZone(zoneAndId.getZone()).delete(zoneAndId.getId());
} catch (Exception e) {
return false;
}

View File

@ -82,11 +82,11 @@ public class AllocateAndAddFloatingIpToNode implements
FloatingIP ip = null;
try {
logger.debug(">> allocating or reassigning floating ip for node(%s)", node.getId());
ip = floatingIpApi.allocate();
ip = floatingIpApi.create();
} catch (InsufficientResourcesException e) {
logger.trace("<< [%s] allocating a new floating ip for node(%s)", e.getMessage(), node.getId());
logger.trace(">> searching for existing, unassigned floating ip for node(%s)", node.getId());
ArrayList<FloatingIP> unassignedIps = Lists.newArrayList(Iterables.filter(floatingIpApi.listFloatingIPs(),
ArrayList<FloatingIP> unassignedIps = Lists.newArrayList(Iterables.filter(floatingIpApi.list(),
new Predicate<FloatingIP>() {
@Override
@ -101,7 +101,7 @@ public class AllocateAndAddFloatingIpToNode implements
}
logger.debug(">> adding floatingIp(%s) to node(%s)", ip.getIp(), node.getId());
floatingIpApi.addFloatingIPToServer(ip.getIp(), node.getProviderId());
floatingIpApi.addToServer(ip.getIp(), node.getProviderId());
input.set(NodeMetadataBuilder.fromNodeMetadata(node).publicAddresses(ImmutableSet.of(ip.getIp())).build());
floatingIpCache.invalidate(ZoneAndId.fromSlashEncoded(node.getId()));
return input;

View File

@ -67,17 +67,17 @@ public class CreateSecurityGroupIfNeeded implements Function<ZoneSecurityGroupNa
logger.debug(">> creating securityGroup %s", zoneSecurityGroupNameAndPorts);
try {
SecurityGroup securityGroup = api.get().createSecurityGroupWithNameAndDescription(
SecurityGroup securityGroup = api.get().createWithDescription(
zoneSecurityGroupNameAndPorts.getName(), zoneSecurityGroupNameAndPorts.getName());
logger.debug("<< created securityGroup(%s)", securityGroup);
for (int port : zoneSecurityGroupNameAndPorts.getPorts()) {
authorizeGroupToItselfAndAllIPsToTCPPort(api.get(), securityGroup, port);
}
return new SecurityGroupInZone(api.get().getSecurityGroup(securityGroup.getId()), zoneId);
return new SecurityGroupInZone(api.get().get(securityGroup.getId()), zoneId);
} catch (IllegalStateException e) {
logger.trace("<< trying to find securityGroup(%s): %s", zoneSecurityGroupNameAndPorts, e.getMessage());
SecurityGroup group = find(api.get().listSecurityGroups(), nameEquals(zoneSecurityGroupNameAndPorts
SecurityGroup group = find(api.get().list(), nameEquals(zoneSecurityGroupNameAndPorts
.getName()));
logger.debug("<< reused securityGroup(%s)", group.getId());
return new SecurityGroupInZone(group, zoneId);
@ -88,7 +88,7 @@ public class CreateSecurityGroupIfNeeded implements Function<ZoneSecurityGroupNa
SecurityGroup securityGroup, int port) {
// NOTE that permission to itself isn't supported on trystack!
logger.debug(">> authorizing securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, port);
securityGroupApi.createSecurityGroupRuleAllowingCidrBlock(securityGroup.getId(), Ingress.builder().ipProtocol(
securityGroupApi.createRuleAllowingCidrBlock(securityGroup.getId(), Ingress.builder().ipProtocol(
IpProtocol.TCP).fromPort(port).toPort(port).build(), "0.0.0.0/0");
logger.debug("<< authorized securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, port);

View File

@ -61,9 +61,9 @@ public class RemoveFloatingIpFromNodeAndDeallocate implements Function<ZoneAndId
FloatingIPApi floatingIpApi = novaApi.getFloatingIPExtensionForZone(id.getZone()).get();
for (FloatingIP ip : floatingIpCache.getUnchecked(id)) {
logger.debug(">> removing floatingIp(%s) from node(%s)", ip, id);
floatingIpApi.removeFloatingIPFromServer(ip.getIp(), id.getId());
floatingIpApi.removeFromServer(ip.getIp(), id.getId());
logger.debug(">> deallocating floatingIp(%s)", ip);
floatingIpApi.deallocate(ip.getId());
floatingIpApi.delete(ip.getId());
}
floatingIpCache.invalidate(id);
return id;
@ -71,6 +71,6 @@ public class RemoveFloatingIpFromNodeAndDeallocate implements Function<ZoneAndId
@Override
public String toString() {
return Objects.toStringHelper("RemoveFloatingIpFromNodeAndDeallocate").toString();
return Objects.toStringHelper("RemoveFloatingIpFromNodeAndDecreate").toString();
}
}

View File

@ -68,7 +68,7 @@ public class CreateUniqueKeyPair extends CacheLoader<ZoneAndName, KeyPair> {
KeyPair keyPair = null;
while (keyPair == null) {
try {
keyPair = api.get().createKeyPair(namingConvention.createWithoutPrefix().uniqueNameForGroup(prefix));
keyPair = api.get().create(namingConvention.createWithoutPrefix().uniqueNameForGroup(prefix));
} catch (IllegalStateException e) {
}

View File

@ -30,7 +30,6 @@ import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.cache.CacheLoader;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
/**
* Each zone may or may not have the floating ip function present. In order to safely proceed, we
@ -53,7 +52,7 @@ public class LoadFloatingIpsForInstance extends CacheLoader<ZoneAndId, Iterable<
String zone = key.getZone();
Optional<? extends FloatingIPApi> ipApiOptional = api.getFloatingIPExtensionForZone(zone);
if (ipApiOptional.isPresent()) {
return Iterables.filter(ipApiOptional.get().listFloatingIPs(),
return ipApiOptional.get().list().filter(
new Predicate<FloatingIP>() {
@Override
public boolean apply(FloatingIP input) {

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