mirror of https://github.com/apache/jclouds.git
Merge branch 'master' of git://github.com/jclouds/jclouds
This commit is contained in:
commit
477466ca64
|
@ -26,7 +26,7 @@ two abstractions at the moment: compute and blobstore. compute helps you
|
|||
bootstrap machines in the cloud. blobstore helps you manage key-value
|
||||
data.
|
||||
|
||||
our current version is 1.0-beta-7
|
||||
our current version is 1.0-beta-8
|
||||
our dev version is 1.0-SNAPSHOT
|
||||
|
||||
our compute api supports: ec2, gogrid, cloudservers (rackspace), rimuhosting, vcloud,
|
||||
|
@ -102,13 +102,13 @@ Compute Example (Clojure):
|
|||
(run-nodes "mycluster" 2))
|
||||
|
||||
Downloads:
|
||||
* distribution zip: http://jclouds.googlecode.com/files/jclouds-1.0-beta-7.zip
|
||||
* distribution zip: http://jclouds.googlecode.com/files/jclouds-1.0-beta-8.zip
|
||||
* maven repo: http://jclouds.googlecode.com/svn/repo
|
||||
* snapshot repo: http://jclouds.rimuhosting.com/maven2/snapshots
|
||||
|
||||
Links:
|
||||
* project page: http://code.google.com/p/jclouds/
|
||||
* javadocs (1.0-beta-7): http://jclouds.rimuhosting.com/apidocs/
|
||||
* javadocs (1.0-beta-8): http://jclouds.rimuhosting.com/apidocs/
|
||||
* javadocs (1.0-SNAPSHOT): http://jclouds.rimuhosting.com/apidocs-SNAPSHOT/
|
||||
* community: http://code.google.com/p/jclouds/wiki/AppsThatUseJClouds
|
||||
* user group: http://groups.google.com/group/jclouds
|
||||
|
|
|
@ -19,10 +19,11 @@
|
|||
|
||||
package org.jclouds.atmosonline.saas.domain;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.io.PayloadEnclosing;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
* Amazon Atmos is designed to store objects. Objects are stored in buckets and consist of a
|
||||
|
|
|
@ -116,7 +116,7 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
ec2Client.getPlacementGroupServices().deletePlacementGroupInRegion(region, group);
|
||||
checkState(placementGroupDeleted.apply(new PlacementGroup(region, group, "cluster", State.PENDING)),
|
||||
String.format("placementGroup region(%s) name(%s) failed to delete", region, group));
|
||||
placementGroupMap.remove(new RegionAndName(region, tag));
|
||||
placementGroupMap.remove(new RegionAndName(region, group));
|
||||
logger.debug("<< deleted placementGroup(%s)", group);
|
||||
} catch (AWSResponseException e) {
|
||||
if (e.getError().getCode().equals("InvalidPlacementGroup.InUse")) {
|
||||
|
@ -142,7 +142,7 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
logger.debug(">> deleting securityGroup(%s)", group);
|
||||
ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(region, group);
|
||||
// TODO: test this clear happens
|
||||
securityGroupMap.remove(new RegionNameAndIngressRules(region, tag, null, false));
|
||||
securityGroupMap.remove(new RegionNameAndIngressRules(region, group, null, false));
|
||||
logger.debug("<< deleted securityGroup(%s)", group);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.jclouds.aws.ec2.EC2Client;
|
|||
import org.jclouds.aws.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.ResourceNotFoundException;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
@ -55,11 +54,10 @@ public final class RegionAndIdToImage implements Function<RegionAndName, Image>
|
|||
public Image apply(RegionAndName key) {
|
||||
try {
|
||||
org.jclouds.aws.ec2.domain.Image image = Iterables.getOnlyElement(sync.getAMIServices()
|
||||
.describeImagesInRegion(key.getRegion(), imageIds(key.getName())));
|
||||
.describeImagesInRegion(key.getRegion(), imageIds(key.getName())));
|
||||
return parser.apply(image);
|
||||
} catch (ResourceNotFoundException e) {
|
||||
logger.warn(e, "no image found for %s/%s: %s", key.getRegion(), key.getName(), e
|
||||
.getMessage());
|
||||
} catch (Exception e) {
|
||||
logger.warn(e, "could not find image %s/%s: %s", key.getRegion(), key.getName(), e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,9 +101,20 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
|
|||
builder.imageId(instance.getRegion() + "/" + instance.getImageId());
|
||||
|
||||
// extract the operating system from the image
|
||||
Image image = instanceToImage.get(new RegionAndName(instance.getRegion(), instance.getImageId()));
|
||||
if (image != null)
|
||||
builder.operatingSystem(image.getOperatingSystem());
|
||||
RegionAndName regionAndName = new RegionAndName(instance.getRegion(), instance.getImageId());
|
||||
try {
|
||||
Image image = instanceToImage.get(regionAndName);
|
||||
if (image != null)
|
||||
builder.operatingSystem(image.getOperatingSystem());
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
// The instanceToImage Map may throw NullPointerException (actually subclass NullOutputException) if the
|
||||
// computing Function returns a null value.
|
||||
//
|
||||
// See the following for more information:
|
||||
// MapMaker.makeComputingMap()
|
||||
// RegionAndIdToImage.apply()
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
@ -209,4 +220,4 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,10 +21,11 @@ package org.jclouds.aws.ec2.domain;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
* Defines the mapping of volumes for
|
||||
|
|
|
@ -24,10 +24,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -21,7 +21,7 @@ package org.jclouds.aws.ec2.domain;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.inject.internal.Nullable;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -21,7 +21,7 @@ package org.jclouds.aws.ec2.domain;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.inject.internal.Nullable;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -24,9 +24,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -25,12 +25,13 @@ import java.util.Date;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.Attachment.Status;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -35,10 +35,14 @@ import com.google.common.collect.Sets;
|
|||
*/
|
||||
public class BaseEC2RequestOptions extends BaseHttpRequestOptions {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[formParameters=" + formParameters + "]";
|
||||
}
|
||||
|
||||
protected void indexFormValuesWithPrefix(String prefix, String... values) {
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
formParameters.put(prefix + "." + (i + 1), checkNotNull(values[i], prefix.toLowerCase()
|
||||
+ "s[" + i + "]"));
|
||||
formParameters.put(prefix + "." + (i + 1), checkNotNull(values[i], prefix.toLowerCase() + "s[" + i + "]"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler {
|
|||
&& (error.getCode().endsWith(".NotFound") || error.getCode().endsWith(".Unknown")))
|
||||
exception = new ResourceNotFoundException(message, exception);
|
||||
else if ((error != null && error.getCode() != null && (error.getCode().equals("IncorrectState") || error
|
||||
.getCode().endsWith(".Duplicate"))) || (message != null && message.indexOf("already exists") != -1))
|
||||
.getCode().endsWith(".Duplicate"))) || (message != null && (message.indexOf("already exists") != -1)))
|
||||
exception = new IllegalStateException(message, exception);
|
||||
else if (error != null && error.getCode() != null && error.getCode().equals("AuthFailure"))
|
||||
exception = new AuthorizationException(exception.getMessage(), exception);
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.aws.s3.blobstore;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.aws.s3.S3ContextBuilder;
|
||||
import org.jclouds.aws.s3.blobstore.config.ScaleUpCloudBlobStoreContextModule;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ScaleUpCloudBlobStoreContextContextBuilder extends S3ContextBuilder {
|
||||
|
||||
public ScaleUpCloudBlobStoreContextContextBuilder(Properties props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
modules.add(new ScaleUpCloudBlobStoreContextModule());
|
||||
}
|
||||
|
||||
}
|
|
@ -29,6 +29,8 @@ import org.jclouds.aws.s3.S3Client;
|
|||
import org.jclouds.aws.s3.blobstore.S3AsyncBlobStore;
|
||||
import org.jclouds.aws.s3.blobstore.S3BlobRequestSigner;
|
||||
import org.jclouds.aws.s3.blobstore.S3BlobStore;
|
||||
import org.jclouds.aws.s3.blobstore.functions.LocationFromBucketLocation;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.suppliers.DefaultLocationSupplier;
|
||||
import org.jclouds.blobstore.AsyncBlobStore;
|
||||
import org.jclouds.blobstore.BlobRequestSigner;
|
||||
|
@ -43,6 +45,7 @@ import org.jclouds.domain.LocationScope;
|
|||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.rest.annotations.Provider;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.Sets;
|
||||
|
@ -70,6 +73,12 @@ public class S3BlobStoreContextModule extends AbstractModule {
|
|||
bind(BlobStoreContext.class).to(new TypeLiteral<BlobStoreContextImpl<S3Client, S3AsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
bind(BlobRequestSigner.class).to(S3BlobRequestSigner.class);
|
||||
bindBucketLocationStrategy();
|
||||
}
|
||||
|
||||
protected void bindBucketLocationStrategy() {
|
||||
bind(new TypeLiteral<Function<BucketMetadata, Location>>() {
|
||||
}).to(LocationFromBucketLocation.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.aws.s3.blobstore.config;
|
||||
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.domain.Location;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ScaleUpCloudBlobStoreContextModule extends S3BlobStoreContextModule {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
protected void bindBucketLocationStrategy() {
|
||||
bind(new TypeLiteral<Function<BucketMetadata, Location>>() {
|
||||
}).toInstance((Function)Functions.constant(null));
|
||||
}
|
||||
}
|
|
@ -19,80 +19,36 @@
|
|||
|
||||
package org.jclouds.aws.s3.blobstore.functions;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.blobstore.domain.MutableStorageMetadata;
|
||||
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class BucketToResourceMetadata implements Function<BucketMetadata, StorageMetadata> {
|
||||
private final S3Client client;
|
||||
private final Location onlyLocation;
|
||||
private final Supplier<Set<? extends Location>> locations;
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
private final Function<BucketMetadata, Location> locationOfBucket;
|
||||
|
||||
@Inject
|
||||
BucketToResourceMetadata(S3Client client, @Memoized Supplier<Set<? extends Location>> locations) {
|
||||
this.client = client;
|
||||
this.onlyLocation = locations.get().size() == 1 ? Iterables.get(locations.get(), 0) : null;
|
||||
this.locations = locations;
|
||||
BucketToResourceMetadata(Function<BucketMetadata, Location> locationOfBucket) {
|
||||
this.locationOfBucket = locationOfBucket;
|
||||
}
|
||||
|
||||
public StorageMetadata apply(BucketMetadata from) {
|
||||
MutableStorageMetadata to = new MutableStorageMetadataImpl();
|
||||
to.setName(from.getName());
|
||||
to.setType(StorageType.CONTAINER);
|
||||
to.setLocation(onlyLocation != null ? onlyLocation : getLocation(from));
|
||||
to.setLocation(locationOfBucket.apply(from));
|
||||
return to;
|
||||
}
|
||||
|
||||
private Location getLocation(BucketMetadata from) {
|
||||
try {
|
||||
Set<? extends Location> locations = this.locations.get();
|
||||
final String region = client.getBucketLocation(from.getName());
|
||||
assert region != null : String.format("could not get region for %s", from.getName());
|
||||
if (region != null) {
|
||||
try {
|
||||
return Iterables.find(locations, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equalsIgnoreCase(region.toString());
|
||||
}
|
||||
|
||||
});
|
||||
} catch (NoSuchElementException e) {
|
||||
logger.error("could not get location for region %s in %s", region, locations);
|
||||
}
|
||||
} else {
|
||||
logger.error("could not get region for %s", from.getName());
|
||||
}
|
||||
} catch (ContainerNotFoundException e) {
|
||||
logger.error(e, "could not get region for %s, as service suggests the bucket doesn't exist", from.getName());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.aws.s3.blobstore.functions;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class LocationFromBucketLocation implements Function<BucketMetadata, Location> {
|
||||
private final Location onlyLocation;
|
||||
private final Supplier<Set<? extends Location>> locations;
|
||||
private final S3Client client;
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
@Inject
|
||||
LocationFromBucketLocation(S3Client client, @Memoized Supplier<Set<? extends Location>> locations) {
|
||||
this.client = client;
|
||||
this.onlyLocation = locations.get().size() == 1 ? Iterables.get(locations.get(), 0) : null;
|
||||
this.locations = locations;
|
||||
}
|
||||
|
||||
public Location apply(BucketMetadata from) {
|
||||
if (onlyLocation != null)
|
||||
return onlyLocation;
|
||||
try {
|
||||
Set<? extends Location> locations = this.locations.get();
|
||||
final String region = client.getBucketLocation(from.getName());
|
||||
assert region != null : String.format("could not get region for %s", from.getName());
|
||||
if (region != null) {
|
||||
try {
|
||||
return Iterables.find(locations, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equalsIgnoreCase(region.toString());
|
||||
}
|
||||
|
||||
});
|
||||
} catch (NoSuchElementException e) {
|
||||
logger.error("could not get location for region %s in %s", region, locations);
|
||||
}
|
||||
} else {
|
||||
logger.error("could not get region for %s", from.getName());
|
||||
}
|
||||
} catch (ContainerNotFoundException e) {
|
||||
logger.error(e, "could not get region for %s, as service suggests the bucket doesn't exist", from.getName());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -19,10 +19,11 @@
|
|||
|
||||
package org.jclouds.aws.s3.domain;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.io.PayloadEnclosing;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
* Amazon S3 is designed to store objects. Objects are stored in buckets and consist of a
|
||||
|
|
|
@ -19,8 +19,14 @@
|
|||
|
||||
package org.jclouds.aws.s3.functions;
|
||||
|
||||
import static com.google.common.base.Throwables.getCausalChain;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.get;
|
||||
import static com.google.common.collect.Iterables.size;
|
||||
import static org.jclouds.util.Utils.propagateOrNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.AWSResponseException;
|
||||
|
@ -35,11 +41,12 @@ import com.google.common.base.Function;
|
|||
public class ReturnFalseIfBucketAlreadyOwnedByYou implements Function<Exception, Boolean> {
|
||||
|
||||
public Boolean apply(Exception from) {
|
||||
if (from instanceof AWSResponseException) {
|
||||
AWSResponseException responseException = (AWSResponseException) from;
|
||||
if ("BucketAlreadyOwnedByYou".equals(responseException.getError().getCode())) {
|
||||
List<Throwable> throwables = getCausalChain(from);
|
||||
|
||||
Iterable<AWSResponseException> matchingAWSResponseException = filter(throwables, AWSResponseException.class);
|
||||
if (size(matchingAWSResponseException) >= 1 && get(matchingAWSResponseException, 0).getError() != null) {
|
||||
if (get(matchingAWSResponseException, 0).getError().getCode().equals("BucketAlreadyOwnedByYou"))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return Boolean.class.cast(propagateOrNull(from));
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getInstanceServices();
|
||||
|
||||
String tag = this.tag + "optionsandlogin";
|
||||
String tag = this.tag + "o";
|
||||
|
||||
TemplateOptions options = client.templateOptions();
|
||||
|
||||
|
@ -190,7 +190,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getInstanceServices();
|
||||
|
||||
String tag = this.tag + "optionsnokey";
|
||||
String tag = this.tag + "k";
|
||||
|
||||
TemplateOptions options = client.templateOptions();
|
||||
|
||||
|
@ -250,7 +250,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getInstanceServices();
|
||||
|
||||
String tag = this.tag + "optionswithsubnetid";
|
||||
String tag = this.tag + "g";
|
||||
|
||||
TemplateOptions options = client.templateOptions();
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ public class EucalyptusComputeServiceLiveTestDisabled extends EC2ComputeServiceL
|
|||
@Override
|
||||
public void setServiceDefaults() {
|
||||
// security groups must be <30 characters
|
||||
tag = "euc";
|
||||
tag = "eu";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.aws.ec2.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.RunNodesException;
|
||||
import org.jclouds.compute.predicates.NodePredicates;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class TestCanRecreateTagLiveTest {
|
||||
|
||||
private ComputeServiceContext context;
|
||||
protected String provider = "ec2";
|
||||
protected String identity;
|
||||
protected String credential;
|
||||
protected String endpoint;
|
||||
protected String apiversion;
|
||||
|
||||
@BeforeClass
|
||||
protected void setupCredentials() {
|
||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
||||
credential = System.getProperty("test." + provider + ".credential");
|
||||
endpoint = System.getProperty("test." + provider + ".endpoint");
|
||||
apiversion = System.getProperty("test." + provider + ".apiversion");
|
||||
}
|
||||
|
||||
protected Properties setupProperties() {
|
||||
Properties overrides = new Properties();
|
||||
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
||||
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
||||
overrides.setProperty(provider + ".identity", identity);
|
||||
if (credential != null)
|
||||
overrides.setProperty(provider + ".credential", credential);
|
||||
if (endpoint != null)
|
||||
overrides.setProperty(provider + ".endpoint", endpoint);
|
||||
if (apiversion != null)
|
||||
overrides.setProperty(provider + ".apiversion", apiversion);
|
||||
return overrides;
|
||||
}
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() throws FileNotFoundException, IOException {
|
||||
setupCredentials();
|
||||
Properties overrides = setupProperties();
|
||||
context = new ComputeServiceContextFactory().createContext(provider,
|
||||
ImmutableSet.<Module> of(new Log4JLoggingModule(), new JschSshClientModule()), overrides);
|
||||
}
|
||||
|
||||
public void testCanRecreateTag() throws Exception {
|
||||
|
||||
String tag = PREFIX + "recreate";
|
||||
context.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
|
||||
try {
|
||||
context.getComputeService().runNodesWithTag(tag, 1);
|
||||
context.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
context.getComputeService().runNodesWithTag(tag, 1);
|
||||
} catch (RunNodesException e) {
|
||||
System.err.println(e.getNodeErrors().keySet());
|
||||
Throwables.propagate(e);
|
||||
} finally {
|
||||
context.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
}
|
||||
}
|
||||
|
||||
public static final String PREFIX = System.getProperty("user.name") + "ec2";
|
||||
|
||||
}
|
|
@ -27,6 +27,7 @@ import static org.easymock.classextension.EasyMock.verify;
|
|||
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.imageIds;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.aws.ec2.EC2Client;
|
||||
|
@ -44,7 +45,7 @@ import com.google.common.collect.ImmutableSet;
|
|||
@Test(groups = "unit", testName = "ec2.RegionAndIdToImageTest")
|
||||
public class RegionAndIdToImageTest {
|
||||
|
||||
@SuppressWarnings({ "unchecked"})
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@Test
|
||||
public void testApply() {
|
||||
|
||||
|
@ -54,10 +55,10 @@ public class RegionAndIdToImageTest {
|
|||
org.jclouds.aws.ec2.domain.Image ec2Image = createMock(org.jclouds.aws.ec2.domain.Image.class);
|
||||
Image image = createNiceMock(Image.class);
|
||||
Set<? extends org.jclouds.aws.ec2.domain.Image> images = ImmutableSet
|
||||
.<org.jclouds.aws.ec2.domain.Image> of(ec2Image);
|
||||
.<org.jclouds.aws.ec2.domain.Image> of(ec2Image);
|
||||
|
||||
expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
|
||||
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn((Set)images);
|
||||
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn((Set) images);
|
||||
expect(parser.apply(ec2Image)).andReturn(image);
|
||||
|
||||
replay(caller);
|
||||
|
@ -76,7 +77,7 @@ public class RegionAndIdToImageTest {
|
|||
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked"})
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@Test
|
||||
public void testApplyNotFound() {
|
||||
|
||||
|
@ -86,10 +87,10 @@ public class RegionAndIdToImageTest {
|
|||
org.jclouds.aws.ec2.domain.Image ec2Image = createMock(org.jclouds.aws.ec2.domain.Image.class);
|
||||
Image image = createNiceMock(Image.class);
|
||||
Set<? extends org.jclouds.aws.ec2.domain.Image> images = ImmutableSet
|
||||
.<org.jclouds.aws.ec2.domain.Image> of(ec2Image);
|
||||
.<org.jclouds.aws.ec2.domain.Image> of(ec2Image);
|
||||
|
||||
expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
|
||||
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn((Set)images);
|
||||
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn((Set) images);
|
||||
expect(parser.apply(ec2Image)).andThrow(new ResourceNotFoundException());
|
||||
|
||||
replay(caller);
|
||||
|
@ -107,4 +108,36 @@ public class RegionAndIdToImageTest {
|
|||
verify(client);
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@Test
|
||||
public void testApplyNoSuchElementException() {
|
||||
|
||||
ImageParser parser = createMock(ImageParser.class);
|
||||
EC2Client caller = createMock(EC2Client.class);
|
||||
AMIClient client = createMock(AMIClient.class);
|
||||
org.jclouds.aws.ec2.domain.Image ec2Image = createMock(org.jclouds.aws.ec2.domain.Image.class);
|
||||
Image image = createNiceMock(Image.class);
|
||||
Set<? extends org.jclouds.aws.ec2.domain.Image> images = ImmutableSet
|
||||
.<org.jclouds.aws.ec2.domain.Image> of(ec2Image);
|
||||
|
||||
expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
|
||||
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn((Set) images);
|
||||
expect(parser.apply(ec2Image)).andThrow(new NoSuchElementException());
|
||||
|
||||
replay(caller);
|
||||
replay(image);
|
||||
replay(parser);
|
||||
replay(client);
|
||||
|
||||
RegionAndIdToImage function = new RegionAndIdToImage(parser, caller);
|
||||
|
||||
assertEquals(function.apply(new RegionAndName("region", "ami")), null);
|
||||
|
||||
verify(caller);
|
||||
verify(image);
|
||||
verify(parser);
|
||||
verify(client);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,9 @@ import com.google.common.collect.ImmutableMap;
|
|||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.MapMaker;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -140,15 +143,44 @@ public class RunningInstanceToNodeMetadataTest {
|
|||
"i-9slweygo").location(provider).build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleMissingAMIs() {
|
||||
|
||||
// Handle the case when the installed AMI no longer can be found in AWS.
|
||||
|
||||
// Create a null-returning function to simulate that the AMI can't be found.
|
||||
Function<RegionAndName, Image> nullReturningFunction = new Function<RegionAndName, Image>() {
|
||||
|
||||
@Override
|
||||
public Image apply(@Nullable RegionAndName from) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
Map<RegionAndName, Image> instanceToImage = new MapMaker().makeComputingMap(nullReturningFunction);
|
||||
|
||||
RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet.of(m1_small().build()), ImmutableSet
|
||||
.of(provider), ImmutableMap
|
||||
.<String, Credentials>of(), EC2ComputeServiceDependenciesModule.instanceToNodeState, instanceToImage);
|
||||
|
||||
RunningInstance server = firstInstanceFromResource("/ec2/describe_instances_nova.xml");
|
||||
|
||||
assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.TERMINATED).privateAddresses(
|
||||
ImmutableSet.of("10.128.207.5")).tag("NOTAG-i-9slweygo").imageId("us-east-1/ami-25CB1213").id(
|
||||
"us-east-1/i-9slweygo").providerId("i-9slweygo").hardware(m1_small().build()).location(
|
||||
provider).build());
|
||||
}
|
||||
|
||||
|
||||
protected RunningInstance firstInstanceFromResource(String resource) {
|
||||
RunningInstance server = Iterables.get(Iterables.get(DescribeInstancesResponseHandlerTest
|
||||
.parseRunningInstances(resource), 0), 0);
|
||||
.parseRunningInstances(resource), 0), 0);
|
||||
return server;
|
||||
}
|
||||
|
||||
protected RunningInstanceToNodeMetadata createNodeParser(final ImmutableSet<Hardware> hardware,
|
||||
final ImmutableSet<Location> locations, Set<org.jclouds.compute.domain.Image> images,
|
||||
Map<String, Credentials> credentialStore) {
|
||||
final ImmutableSet<Location> locations,
|
||||
Set<org.jclouds.compute.domain.Image> images,
|
||||
Map<String, Credentials> credentialStore) {
|
||||
Map<InstanceState, NodeState> instanceToNodeState = EC2ComputeServiceDependenciesModule.instanceToNodeState;
|
||||
|
||||
Map<RegionAndName, Image> instanceToImage = Maps.uniqueIndex(images, new Function<Image, RegionAndName>() {
|
||||
|
@ -159,6 +191,13 @@ public class RunningInstanceToNodeMetadataTest {
|
|||
}
|
||||
|
||||
});
|
||||
|
||||
return createNodeParser(hardware, locations, credentialStore, instanceToNodeState, instanceToImage);
|
||||
}
|
||||
|
||||
private RunningInstanceToNodeMetadata createNodeParser(final ImmutableSet<Hardware> hardware, final
|
||||
ImmutableSet<Location> locations, Map<String, Credentials> credentialStore, Map<InstanceState, NodeState>
|
||||
instanceToNodeState, Map<RegionAndName, Image> instanceToImage) {
|
||||
Supplier<Set<? extends Location>> locationSupplier = new Supplier<Set<? extends Location>>() {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
<dependency>
|
||||
<groupId>com.google.code.guice</groupId>
|
||||
<artifactId>guice-servlet</artifactId>
|
||||
<version>2.1-r1201</version>
|
||||
<version>3.0-snapshot-20101120</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>displaytag</groupId>
|
||||
|
|
|
@ -26,6 +26,8 @@ import java.net.URI;
|
|||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.BlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobType;
|
||||
import org.jclouds.azure.storage.blob.domain.LeaseStatus;
|
||||
|
@ -33,7 +35,6 @@ import org.jclouds.io.ContentMetadata;
|
|||
import org.jclouds.io.payloads.BaseImmutableContentMetadata;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
* Allows you to manipulate metadata.
|
||||
|
|
|
@ -299,7 +299,7 @@ Options can also be specified for extension modules
|
|||
([container-name]
|
||||
(count-blobs container-name *blobstore*))
|
||||
([container-name blobstore]
|
||||
(.countBlob blobstore container-name)))
|
||||
(.countBlobs blobstore container-name)))
|
||||
|
||||
(defn blobs
|
||||
"List the blobs in a container:
|
||||
|
|
|
@ -49,27 +49,28 @@ import java.util.Collections;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.Blob.Factory;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
||||
import org.jclouds.blobstore.domain.MutableStorageMetadata;
|
||||
import org.jclouds.blobstore.domain.PageSet;
|
||||
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.blobstore.domain.Blob.Factory;
|
||||
import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl;
|
||||
import org.jclouds.blobstore.domain.internal.PageSetImpl;
|
||||
import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions;
|
||||
|
@ -103,7 +104,6 @@ import com.google.common.collect.Iterables;
|
|||
import com.google.common.collect.Multimaps;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
* Implementation of {@link BaseAsyncBlobStore} which keeps all data in a local Map object.
|
||||
|
|
|
@ -19,10 +19,12 @@
|
|||
|
||||
package org.jclouds.blobstore.domain;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.PayloadEnclosing;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
* Value type for an HTTP Blob service. Blobs are stored in containers and consist of a
|
||||
|
|
|
@ -26,14 +26,14 @@ import java.net.URI;
|
|||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.io.ContentMetadata;
|
||||
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
* System and user Metadata for the {@link Blob}.
|
||||
*
|
||||
|
|
|
@ -26,13 +26,13 @@ import java.net.URI;
|
|||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.internal.ResourceMetadataImpl;
|
||||
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
* Idpayload of the object
|
||||
*
|
||||
|
|
|
@ -87,8 +87,11 @@ public class ParseSystemAndUserMetadataFromHeaders implements Function<HttpRespo
|
|||
@VisibleForTesting
|
||||
void parseLastModifiedOrThrowException(HttpResponse from, MutableBlobMetadata metadata) throws HttpException {
|
||||
String lastModified = from.getFirstHeaderOrNull(HttpHeaders.LAST_MODIFIED);
|
||||
if (lastModified == null)
|
||||
throw new HttpException(HttpHeaders.LAST_MODIFIED + " header not present in response: " + from.getStatusLine());
|
||||
if (lastModified == null) {
|
||||
// scaleup-storage uses the wrong case for the last modified header
|
||||
if ((lastModified = from.getFirstHeaderOrNull("Last-modified")) == null)
|
||||
throw new HttpException(HttpHeaders.LAST_MODIFIED + " header not present in response: " + from.getStatusLine());
|
||||
}
|
||||
// Eucalyptus 1.6 returns iso8601 dates
|
||||
if (apiVersion.indexOf("Walrus-1.6") != -1) {
|
||||
metadata.setLastModified(dateParser.iso8601DateParse(lastModified.replace("+0000", "Z")));
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
(is (= 1 (count (list-container "container" :max-results 1))))
|
||||
(create-directory "container" "dir")
|
||||
(is (upload-blob "container" "dir/blob2" "blob2"))
|
||||
(is (= 3 (count-blobs "container")))
|
||||
(is (= 3 (count (list-container "container"))))
|
||||
(is (= 4 (count (list-container "container" :recursive true))))
|
||||
(is (= 3 (count (list-container "container" :with-details true))))
|
||||
|
|
|
@ -97,7 +97,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
@SuppressWarnings("unchecked")
|
||||
public static InputSupplier<InputStream> getTestDataSupplier() throws IOException {
|
||||
byte[] oneConstitution = ByteStreams.toByteArray(new GZIPInputStream(BaseJettyTest.class
|
||||
.getResourceAsStream("/const.txt.gz")));
|
||||
.getResourceAsStream("/const.txt.gz")));
|
||||
InputSupplier<ByteArrayInputStream> constitutionSupplier = ByteStreams.newInputStreamSupplier(oneConstitution);
|
||||
|
||||
InputSupplier<InputStream> temp = ByteStreams.join(constitutionSupplier);
|
||||
|
@ -120,24 +120,24 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
Map<Integer, Future<?>> responses = Maps.newHashMap();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
|
||||
responses.put(i, Futures.compose(context.getAsyncBlobStore().getBlob(containerName, key),
|
||||
new Function<Blob, Void>() {
|
||||
responses.put(i,
|
||||
Futures.compose(context.getAsyncBlobStore().getBlob(containerName, key), new Function<Blob, Void>() {
|
||||
|
||||
@Override
|
||||
public Void apply(Blob from) {
|
||||
try {
|
||||
assertEquals(CryptoStreams.md5(from.getPayload()), oneHundredOneConstitutionsMD5);
|
||||
checkContentDisposition(from, expectedContentDisposition);
|
||||
} catch (IOException e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
return null;
|
||||
@Override
|
||||
public Void apply(Blob from) {
|
||||
try {
|
||||
assertEquals(CryptoStreams.md5(from.getPayload()), oneHundredOneConstitutionsMD5);
|
||||
checkContentDisposition(from, expectedContentDisposition);
|
||||
} catch (IOException e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}, this.exec));
|
||||
}, this.exec));
|
||||
}
|
||||
Map<Integer, Exception> exceptions = awaitCompletion(responses, exec, 30000l, Logger.CONSOLE,
|
||||
"get constitution");
|
||||
"get constitution");
|
||||
assert exceptions.size() == 0 : exceptions;
|
||||
|
||||
} finally {
|
||||
|
@ -156,7 +156,6 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
context.getBlobStore().putBlob(containerName, sourceObject);
|
||||
}
|
||||
|
||||
|
||||
@Test(groups = { "integration", "live" })
|
||||
public void testGetIfModifiedSince() throws InterruptedException {
|
||||
String containerName = getContainerName();
|
||||
|
@ -365,15 +364,15 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
@DataProvider(name = "delete")
|
||||
public Object[][] createData() {
|
||||
return new Object[][] { { "normal" }, { "sp ace" }, { "qu?stion" }, { "unic₪de" }, { "path/foo" }, { "colon:" },
|
||||
{ "asteri*k" }, { "quote\"" }, { "{great<r}" }, { "lesst>en" }, { "p|pe" } };
|
||||
return new Object[][] { { "normal" }, { "sp ace" }, { "qu?stion" }, { "unic₪de" }, { "path/foo" },
|
||||
{ "colon:" }, { "asteri*k" }, { "quote\"" }, { "{great<r}" }, { "lesst>en" }, { "p|pe" } };
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" }, dataProvider = "delete")
|
||||
public void deleteObject(String key) throws InterruptedException {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
addBlobToContainer(containerName, key);
|
||||
addBlobToContainer(containerName, key, key, MediaType.TEXT_PLAIN);
|
||||
context.getBlobStore().removeBlob(containerName, key);
|
||||
assertContainerEmptyDeleting(containerName, key);
|
||||
} finally {
|
||||
|
@ -383,17 +382,19 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
private void assertContainerEmptyDeleting(String containerName, String key) {
|
||||
Iterable<? extends StorageMetadata> listing = Iterables.filter(context.getBlobStore().list(containerName),
|
||||
new Predicate<StorageMetadata>() {
|
||||
new Predicate<StorageMetadata>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(StorageMetadata input) {
|
||||
return input.getType() == StorageType.BLOB;
|
||||
}
|
||||
@Override
|
||||
public boolean apply(StorageMetadata input) {
|
||||
return input.getType() == StorageType.BLOB;
|
||||
}
|
||||
|
||||
});
|
||||
assertEquals(Iterables.size(listing), 0, String.format(
|
||||
"deleting %s, we still have %s blobs left in container %s, using encoding %s", key, Iterables
|
||||
.size(listing), containerName, LOCAL_ENCODING));
|
||||
});
|
||||
assertEquals(
|
||||
Iterables.size(listing),
|
||||
0,
|
||||
String.format("deleting %s, we still have %s blobs left in container %s, using encoding %s", key,
|
||||
Iterables.size(listing), containerName, LOCAL_ENCODING));
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" })
|
||||
|
@ -413,13 +414,13 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
String realObject = Utils.toStringAndClose(new FileInputStream("pom.xml"));
|
||||
|
||||
return new Object[][] { { "file", "text/xml", new File("pom.xml"), realObject },
|
||||
{ "string", "text/xml", realObject, realObject },
|
||||
{ "bytes", "application/octet-stream", realObject.getBytes(), realObject } };
|
||||
{ "string", "text/xml", realObject, realObject },
|
||||
{ "bytes", "application/octet-stream", realObject.getBytes(), realObject } };
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" }, dataProvider = "putTests")
|
||||
public void testPutObject(String key, String type, Object content, Object realObject) throws InterruptedException,
|
||||
IOException {
|
||||
IOException {
|
||||
Blob blob = context.getBlobStore().newBlob(key);
|
||||
blob.setPayload(Payloads.newPayload(content));
|
||||
blob.getMetadata().getContentMetadata().setContentType(type);
|
||||
|
@ -486,32 +487,32 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
protected void checkContentType(Blob blob, String contentType) {
|
||||
assert blob.getPayload().getContentMetadata().getContentType().startsWith(contentType) : blob.getPayload()
|
||||
.getContentMetadata().getContentType();
|
||||
.getContentMetadata().getContentType();
|
||||
assert blob.getMetadata().getContentMetadata().getContentType().startsWith(contentType) : blob.getMetadata()
|
||||
.getContentMetadata().getContentType();
|
||||
.getContentMetadata().getContentType();
|
||||
}
|
||||
|
||||
protected void checkContentDisposition(Blob blob, String contentDisposition) {
|
||||
assert blob.getPayload().getContentMetadata().getContentDisposition().startsWith(contentDisposition) : blob
|
||||
.getPayload().getContentMetadata().getContentDisposition();
|
||||
.getPayload().getContentMetadata().getContentDisposition();
|
||||
assert blob.getMetadata().getContentMetadata().getContentDisposition().startsWith(contentDisposition) : blob
|
||||
.getMetadata().getContentMetadata().getContentDisposition();
|
||||
.getMetadata().getContentMetadata().getContentDisposition();
|
||||
|
||||
}
|
||||
|
||||
protected void checkContentEncoding(Blob blob, String contentEncoding) {
|
||||
assert blob.getPayload().getContentMetadata().getContentEncoding().startsWith(contentEncoding) : blob
|
||||
.getPayload().getContentMetadata().getContentEncoding();
|
||||
.getPayload().getContentMetadata().getContentEncoding();
|
||||
assert blob.getMetadata().getContentMetadata().getContentEncoding().startsWith(contentEncoding) : blob
|
||||
.getMetadata().getContentMetadata().getContentEncoding();
|
||||
.getMetadata().getContentMetadata().getContentEncoding();
|
||||
|
||||
}
|
||||
|
||||
protected void checkContentLanguage(Blob blob, String contentLanguage) {
|
||||
assert blob.getPayload().getContentMetadata().getContentLanguage().startsWith(contentLanguage) : blob
|
||||
.getPayload().getContentMetadata().getContentLanguage();
|
||||
.getPayload().getContentMetadata().getContentLanguage();
|
||||
assert blob.getMetadata().getContentMetadata().getContentLanguage().startsWith(contentLanguage) : blob
|
||||
.getMetadata().getContentMetadata().getContentLanguage();
|
||||
.getMetadata().getContentMetadata().getContentLanguage();
|
||||
|
||||
}
|
||||
|
||||
|
@ -565,7 +566,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
protected void validateMetadata(BlobMetadata metadata) throws IOException {
|
||||
assert metadata.getContentMetadata().getContentType().startsWith("text/plain") : metadata.getContentMetadata()
|
||||
.getContentType();
|
||||
.getContentType();
|
||||
assertEquals(metadata.getContentMetadata().getContentLength(), new Long(TEST_STRING.length()));
|
||||
assertEquals(metadata.getUserMetadata().get("adrian"), "powderpuff");
|
||||
checkMD5(metadata);
|
||||
|
|
|
@ -25,8 +25,8 @@ import static org.testng.Assert.assertEquals;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.CancellationException;
|
||||
|
@ -35,6 +35,8 @@ import java.util.concurrent.Executors;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.attr.ConsistencyModel;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
|
@ -60,13 +62,13 @@ public class BaseBlobStoreIntegrationTest {
|
|||
protected static final String TEST_STRING = String.format(XML_STRING_FORMAT, "apple");
|
||||
|
||||
protected Map<String, String> fiveStrings = ImmutableMap.of("one", String.format(XML_STRING_FORMAT, "apple"), "two",
|
||||
String.format(XML_STRING_FORMAT, "bear"), "three", String.format(XML_STRING_FORMAT, "candy"), "four",
|
||||
String.format(XML_STRING_FORMAT, "dogma"), "five", String.format(XML_STRING_FORMAT, "emma"));
|
||||
String.format(XML_STRING_FORMAT, "bear"), "three", String.format(XML_STRING_FORMAT, "candy"), "four",
|
||||
String.format(XML_STRING_FORMAT, "dogma"), "five", String.format(XML_STRING_FORMAT, "emma"));
|
||||
|
||||
protected Map<String, String> fiveStringsUnderPath = ImmutableMap.of("path/1", String.format(XML_STRING_FORMAT,
|
||||
"apple"), "path/2", String.format(XML_STRING_FORMAT, "bear"), "path/3", String.format(XML_STRING_FORMAT,
|
||||
"candy"), "path/4", String.format(XML_STRING_FORMAT, "dogma"), "path/5", String.format(XML_STRING_FORMAT,
|
||||
"emma"));
|
||||
protected Map<String, String> fiveStringsUnderPath = ImmutableMap.of("path/1",
|
||||
String.format(XML_STRING_FORMAT, "apple"), "path/2", String.format(XML_STRING_FORMAT, "bear"), "path/3",
|
||||
String.format(XML_STRING_FORMAT, "candy"), "path/4", String.format(XML_STRING_FORMAT, "dogma"), "path/5",
|
||||
String.format(XML_STRING_FORMAT, "emma"));
|
||||
|
||||
public static long INCONSISTENCY_WINDOW = 10000;
|
||||
protected static volatile AtomicInteger containerIndex = new AtomicInteger(0);
|
||||
|
@ -90,7 +92,7 @@ public class BaseBlobStoreIntegrationTest {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
private BlobStoreContext getCloudResources(ITestContext testContext) throws ClassNotFoundException,
|
||||
InstantiationException, IllegalAccessException, Exception {
|
||||
InstantiationException, IllegalAccessException, Exception {
|
||||
String initializerClass = checkNotNull(System.getProperty("test.initializer"), "test.initializer");
|
||||
Class<BaseTestInitializer> clazz = (Class<BaseTestInitializer>) Class.forName(initializerClass);
|
||||
BaseTestInitializer initializer = clazz.newInstance();
|
||||
|
@ -123,7 +125,7 @@ public class BaseBlobStoreIntegrationTest {
|
|||
private static volatile boolean initialized = false;
|
||||
|
||||
protected void createContainersSharedByAllThreads(BlobStoreContext context, ITestContext testContext)
|
||||
throws Exception {
|
||||
throws Exception {
|
||||
while (!initialized) {
|
||||
synchronized (BaseBlobStoreIntegrationTest.class) {
|
||||
if (!initialized) {
|
||||
|
@ -174,12 +176,12 @@ public class BaseBlobStoreIntegrationTest {
|
|||
try {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
Iterable<? extends StorageMetadata> testContainers = Iterables.filter(context.getBlobStore().list(),
|
||||
new Predicate<StorageMetadata>() {
|
||||
public boolean apply(StorageMetadata input) {
|
||||
return (input.getType() == StorageType.CONTAINER || input.getType() == StorageType.FOLDER)
|
||||
&& input.getName().startsWith(CONTAINER_PREFIX.toLowerCase());
|
||||
}
|
||||
});
|
||||
new Predicate<StorageMetadata>() {
|
||||
public boolean apply(StorageMetadata input) {
|
||||
return (input.getType() == StorageType.CONTAINER || input.getType() == StorageType.FOLDER)
|
||||
&& input.getName().startsWith(CONTAINER_PREFIX.toLowerCase());
|
||||
}
|
||||
});
|
||||
for (StorageMetadata container : testContainers) {
|
||||
deleteContainerOrWarnIfUnable(context, container.getName());
|
||||
}
|
||||
|
@ -200,7 +202,7 @@ public class BaseBlobStoreIntegrationTest {
|
|||
* we will try up to the inconsistency window to see if the assertion completes.
|
||||
*/
|
||||
protected static void assertConsistencyAware(BlobStoreContext context, Runnable assertion)
|
||||
throws InterruptedException {
|
||||
throws InterruptedException {
|
||||
if (context.getConsistencyModel() == ConsistencyModel.STRICT) {
|
||||
assertion.run();
|
||||
return;
|
||||
|
@ -226,7 +228,7 @@ public class BaseBlobStoreIntegrationTest {
|
|||
}
|
||||
|
||||
protected static void createContainerAndEnsureEmpty(BlobStoreContext context, final String containerName)
|
||||
throws InterruptedException {
|
||||
throws InterruptedException {
|
||||
context.getBlobStore().createContainerInLocation(null, containerName);
|
||||
if (context.getConsistencyModel() == ConsistencyModel.EVENTUAL)
|
||||
Thread.sleep(1000);
|
||||
|
@ -238,9 +240,13 @@ public class BaseBlobStoreIntegrationTest {
|
|||
}
|
||||
|
||||
protected String addBlobToContainer(String sourceContainer, String key) {
|
||||
return addBlobToContainer(sourceContainer, key, TEST_STRING, MediaType.TEXT_XML);
|
||||
}
|
||||
|
||||
protected String addBlobToContainer(String sourceContainer, String key, String payload, String contentType) {
|
||||
Blob sourceObject = context.getBlobStore().newBlob(key);
|
||||
sourceObject.setPayload(TEST_STRING);
|
||||
sourceObject.getMetadata().getContentMetadata().setContentType("text/xml");
|
||||
sourceObject.setPayload(payload);
|
||||
sourceObject.getMetadata().getContentMetadata().setContentType(contentType);
|
||||
return addBlobToContainer(sourceContainer, sourceObject);
|
||||
}
|
||||
|
||||
|
@ -270,19 +276,19 @@ public class BaseBlobStoreIntegrationTest {
|
|||
}
|
||||
|
||||
protected void assertConsistencyAwareContainerSize(final String containerName, final int count)
|
||||
throws InterruptedException {
|
||||
throws InterruptedException {
|
||||
assertConsistencyAware(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
assert context.getBlobStore().countBlobs(containerName) == count : String.format(
|
||||
"expected only %d values in %s: %s", count, containerName, Sets.newHashSet(Iterables.transform(
|
||||
context.getBlobStore().list(containerName), new Function<StorageMetadata, String>() {
|
||||
"expected only %d values in %s: %s", count, containerName, Sets.newHashSet(Iterables.transform(
|
||||
context.getBlobStore().list(containerName), new Function<StorageMetadata, String>() {
|
||||
|
||||
public String apply(StorageMetadata from) {
|
||||
return from.getName();
|
||||
}
|
||||
public String apply(StorageMetadata from) {
|
||||
return from.getName();
|
||||
}
|
||||
|
||||
})));
|
||||
})));
|
||||
} catch (Exception e) {
|
||||
Throwables.propagateIfPossible(e);
|
||||
}
|
||||
|
|
|
@ -200,7 +200,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
// starting this one alphabetically before create2nodes..
|
||||
@Test(enabled = true, dependsOnMethods = { "testCompareSizes" })
|
||||
public void testAScriptExecutionAfterBootWithBasicTemplate() throws Exception {
|
||||
String tag = this.tag + "run";
|
||||
String tag = this.tag + "r";
|
||||
try {
|
||||
client.destroyNodesMatching(withTag(tag));
|
||||
} catch (Exception e) {
|
||||
|
@ -460,7 +460,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
@Test(enabled = true)
|
||||
public void testCreateAndRunAService() throws Exception {
|
||||
|
||||
String tag = this.tag + "service";
|
||||
String tag = this.tag + "s";
|
||||
try {
|
||||
client.destroyNodesMatching(withTag(tag));
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
<dependency>
|
||||
<groupId>com.google.code.guice</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<version>2.1-r1201</version>
|
||||
<version>3.0-snapshot-20101120</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
|
@ -106,7 +106,7 @@
|
|||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>r06</version>
|
||||
<version>r07</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
|
|
|
@ -25,11 +25,12 @@ import java.io.Serializable;
|
|||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.ResourceMetadata;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
* Idpayload of the object
|
||||
|
|
|
@ -19,10 +19,15 @@
|
|||
|
||||
package org.jclouds.http;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.io.Payload;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
/**
|
||||
* Represents a response produced from {@link HttpCommandExecutorService}
|
||||
*
|
||||
|
@ -34,9 +39,14 @@ public class HttpResponse extends HttpMessage {
|
|||
private final String message;
|
||||
|
||||
public HttpResponse(int statusCode, String message, @Nullable Payload payload) {
|
||||
this(statusCode, message, payload, ImmutableMultimap.<String, String> of());
|
||||
}
|
||||
|
||||
public HttpResponse(int statusCode, String message, @Nullable Payload payload, Multimap<String, String> headers) {
|
||||
super(payload);
|
||||
this.statusCode = statusCode;
|
||||
this.message = message;
|
||||
this.headers.putAll(checkNotNull(headers));
|
||||
}
|
||||
|
||||
public int getStatusCode() {
|
||||
|
@ -49,8 +59,8 @@ public class HttpResponse extends HttpMessage {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[message=" + message + ", statusCode=" + statusCode + ", headers=" + headers
|
||||
+ ", payload=" + payload + "]";
|
||||
return "[message=" + message + ", statusCode=" + statusCode + ", headers=" + headers + ", payload=" + payload
|
||||
+ "]";
|
||||
}
|
||||
|
||||
public String getStatusLine() {
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
package org.jclouds.http.handlers;
|
||||
|
||||
import static org.jclouds.http.HttpUtils.changePathTo;
|
||||
import static org.jclouds.http.HttpUtils.changeSchemeHostAndPortTo;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static javax.ws.rs.core.HttpHeaders.HOST;
|
||||
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
|
||||
|
||||
import java.net.URI;
|
||||
|
@ -58,8 +58,7 @@ public class RedirectionRetryHandler implements HttpRetryHandler {
|
|||
protected final Provider<UriBuilder> uriBuilderProvider;
|
||||
|
||||
@Inject
|
||||
protected RedirectionRetryHandler(Provider<UriBuilder> uriBuilderProvider,
|
||||
BackoffLimitedRetryHandler backoffHandler) {
|
||||
protected RedirectionRetryHandler(Provider<UriBuilder> uriBuilderProvider, BackoffLimitedRetryHandler backoffHandler) {
|
||||
this.backoffHandler = backoffHandler;
|
||||
this.uriBuilderProvider = uriBuilderProvider;
|
||||
}
|
||||
|
@ -67,25 +66,36 @@ public class RedirectionRetryHandler implements HttpRetryHandler {
|
|||
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
|
||||
closeClientButKeepContentStream(response);
|
||||
String hostHeader = response.getFirstHeaderOrNull(HttpHeaders.LOCATION);
|
||||
if (hostHeader != null && command.incrementRedirectCount() < retryCountLimit) {
|
||||
URI redirectionUrl = uriBuilderProvider.get().uri(URI.create(hostHeader)).build();
|
||||
if (redirectionUrl.getScheme().equals(command.getRequest().getEndpoint().getScheme())
|
||||
&& redirectionUrl.getHost().equals(command.getRequest().getEndpoint().getHost())
|
||||
&& redirectionUrl.getPort() == command.getRequest().getEndpoint().getPort()) {
|
||||
if (!redirectionUrl.getPath().equals(command.getRequest().getEndpoint().getPath())) {
|
||||
changePathTo(command.getRequest(), redirectionUrl.getPath(), uriBuilderProvider
|
||||
.get());
|
||||
} else {
|
||||
return backoffHandler.shouldRetryRequest(command, response);
|
||||
}
|
||||
} else {
|
||||
changeSchemeHostAndPortTo(command.getRequest(), redirectionUrl.getScheme(),
|
||||
redirectionUrl.getHost(), redirectionUrl.getPort(), uriBuilderProvider.get());
|
||||
if (command.incrementRedirectCount() < retryCountLimit && hostHeader != null) {
|
||||
URI redirectionUrl = URI.create(hostHeader);
|
||||
|
||||
// if you are sent the same uri, assume there's a transient problem and retry.
|
||||
if (redirectionUrl.equals(command.getRequest().getEndpoint()))
|
||||
return backoffHandler.shouldRetryRequest(command, response);
|
||||
|
||||
UriBuilder builder = uriBuilderProvider.get().uri(command.getRequest().getEndpoint());
|
||||
assert redirectionUrl.getPath() != null : "no path in redirect header from: " + response;
|
||||
builder.replacePath(redirectionUrl.getPath());
|
||||
|
||||
if (redirectionUrl.getScheme() != null)
|
||||
builder.scheme(redirectionUrl.getScheme());
|
||||
|
||||
if (redirectionUrl.getHost() != null) {
|
||||
builder.host(redirectionUrl.getHost());
|
||||
if (command.getRequest().getFirstHeaderOrNull(HOST) != null)
|
||||
command.getRequest().getHeaders().replaceValues(HOST, singletonList(redirectionUrl.getHost()));
|
||||
}
|
||||
if (redirectionUrl.getPort() != command.getRequest().getEndpoint().getPort())
|
||||
builder.port(redirectionUrl.getPort());
|
||||
|
||||
if (redirectionUrl.getQuery() != null)
|
||||
builder.replaceQuery(redirectionUrl.getQuery());
|
||||
|
||||
command.getRequest().setEndpoint(builder.build());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -19,18 +19,27 @@
|
|||
|
||||
package org.jclouds.io.payloads;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.jclouds.util.Utils;
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
/**
|
||||
* This implementation converts the String to a byte array using UTF-8 encoding. If you wish to use
|
||||
* a different encoding, please use {@link ByteArrayPayload}.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class StringPayload extends BasePayload<String> {
|
||||
|
||||
private final byte[] bytes;
|
||||
|
||||
// it is possible to discover length by walking the string and updating current length based on
|
||||
// character code. However, this is process intense, and assumes an encoding type of UTF-8
|
||||
public StringPayload(String content) {
|
||||
super(content);
|
||||
getContentMetadata().setContentLength((long) content.length());
|
||||
this.bytes = content.getBytes(Charsets.UTF_8);
|
||||
getContentMetadata().setContentLength(new Long(bytes.length));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,7 +47,7 @@ public class StringPayload extends BasePayload<String> {
|
|||
*/
|
||||
@Override
|
||||
public InputStream getInput() {
|
||||
return Utils.toInputStream(content);
|
||||
return new ByteArrayInputStream(bytes);
|
||||
}
|
||||
|
||||
}
|
|
@ -21,7 +21,9 @@ package org.jclouds.util;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Predicates.equalTo;
|
||||
import static com.google.common.base.Predicates.instanceOf;
|
||||
import static com.google.common.base.Predicates.not;
|
||||
import static com.google.common.base.Predicates.notNull;
|
||||
import static com.google.common.base.Splitter.on;
|
||||
import static com.google.common.base.Throwables.getCausalChain;
|
||||
|
@ -32,6 +34,7 @@ import static com.google.common.collect.Iterables.find;
|
|||
import static com.google.common.collect.Iterables.get;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
import static com.google.common.collect.Maps.filterKeys;
|
||||
import static com.google.common.io.ByteStreams.toByteArray;
|
||||
import static com.google.common.io.Closeables.closeQuietly;
|
||||
import static org.jclouds.util.Patterns.CHAR_TO_PATTERN;
|
||||
|
@ -47,10 +50,10 @@ import java.util.Comparator;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -70,6 +73,8 @@ import com.google.common.base.Predicate;
|
|||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.io.OutputSupplier;
|
||||
|
@ -84,6 +89,32 @@ import com.google.inject.spi.Message;
|
|||
*/
|
||||
public class Utils {
|
||||
|
||||
/**
|
||||
* If the supplied map contains the key {@code k1}, its value will be assigned to the key
|
||||
* {@code k2}. Note that this doesn't modify the input map.
|
||||
*
|
||||
* @param <V>
|
||||
* type of value the map holds
|
||||
* @param in
|
||||
* the map you wish to make a copy of
|
||||
* @param k1
|
||||
* old key
|
||||
* @param k2
|
||||
* new key
|
||||
* @return copy of the map with the value of the key re-routed, or the original, if it {@code k1}
|
||||
* wasn't present.
|
||||
*/
|
||||
public static <V> Map<String, V> renameKey(Map<String, V> in, String k1, String k2) {
|
||||
if (in.containsKey(k1)) {
|
||||
Builder<String, V> builder = ImmutableMap.builder();
|
||||
builder.putAll(filterKeys(in, not(equalTo(k1))));
|
||||
V tags = in.get(k1);
|
||||
builder.put(k2, tags);
|
||||
in = builder.build();
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
public static <K, V> Supplier<Map<K, V>> composeMapSupplier(Iterable<Supplier<Map<K, V>>> suppliers) {
|
||||
return new ListMapSupplier<K, V>(suppliers);
|
||||
}
|
||||
|
|
|
@ -89,6 +89,12 @@ bluelock-vcdirector.propertiesbuilder=org.jclouds.vcloud.bluelock.BlueLockVCloud
|
|||
gogrid.propertiesbuilder=org.jclouds.gogrid.GoGridPropertiesBuilder
|
||||
gogrid.contextbuilder=org.jclouds.gogrid.GoGridContextBuilder
|
||||
|
||||
elasticstack.propertiesbuilder=org.jclouds.elasticstack.ElasticStackPropertiesBuilder
|
||||
elasticstack.contextbuilder=org.jclouds.elasticstack.ElasticStackContextBuilder
|
||||
|
||||
cloudsigma.propertiesbuilder=org.jclouds.cloudsigma.CloudSigmaPropertiesBuilder
|
||||
cloudsigma.contextbuilder=org.jclouds.cloudsigma.CloudSigmaContextBuilder
|
||||
|
||||
ibmdev.propertiesbuilder=org.jclouds.ibmdev.IBMDeveloperCloudPropertiesBuilder
|
||||
ibmdev.contextbuilder=org.jclouds.ibmdev.IBMDeveloperCloudContextBuilder
|
||||
|
||||
|
@ -119,6 +125,10 @@ walrus.propertiesbuilder=org.jclouds.aws.s3.WalrusPropertiesBuilder
|
|||
googlestorage.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
|
||||
googlestorage.propertiesbuilder=org.jclouds.aws.s3.GoogleStoragePropertiesBuilder
|
||||
|
||||
scaleup-storage.contextbuilder=org.jclouds.aws.s3.blobstore.ScaleUpCloudBlobStoreContextContextBuilder
|
||||
scaleup-storage.propertiesbuilder=org.jclouds.aws.s3.S3PropertiesBuilder
|
||||
scaleup-storage.endpoint=https://scs.scaleupstorage.com
|
||||
|
||||
transient.contextbuilder=org.jclouds.blobstore.TransientBlobStoreContextBuilder
|
||||
transient.propertiesbuilder=org.jclouds.blobstore.TransientBlobStorePropertiesBuilder
|
||||
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.http.handlers;
|
||||
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createMock;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.easymock.classextension.EasyMock.verify;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.rest.BaseRestClientTest.MockModule;
|
||||
import org.jclouds.rest.config.RestModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.inject.Guice;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code RedirectionRetryHandler}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "http.RedirectionRetryHandlerTest")
|
||||
public class RedirectionRetryHandlerTest {
|
||||
|
||||
@Test
|
||||
public void test302DoesNotRetry() {
|
||||
|
||||
HttpCommand command = createMock(HttpCommand.class);
|
||||
HttpResponse response = new HttpResponse(302, "HTTP/1.1 302 Found", null);
|
||||
|
||||
expect(command.incrementRedirectCount()).andReturn(0);
|
||||
|
||||
replay(command);
|
||||
|
||||
RedirectionRetryHandler retry = Guice.createInjector(new MockModule(), new RestModule()).getInstance(
|
||||
RedirectionRetryHandler.class);
|
||||
|
||||
assert !retry.shouldRetryRequest(command, response);
|
||||
|
||||
verify(command);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test302DoesNotRetryAfterLimit() {
|
||||
|
||||
HttpCommand command = createMock(HttpCommand.class);
|
||||
HttpResponse response = new HttpResponse(302, "HTTP/1.1 302 Found", null, ImmutableMultimap.of(
|
||||
HttpHeaders.LOCATION, "/api/v0.8b-ext2.5/Error.aspx?aspxerrorpath=/api/v0.8b-ext2.5/org.svc/1906645"));
|
||||
|
||||
expect(command.incrementRedirectCount()).andReturn(5);
|
||||
|
||||
replay(command);
|
||||
|
||||
RedirectionRetryHandler retry = Guice.createInjector(new MockModule(), new RestModule()).getInstance(
|
||||
RedirectionRetryHandler.class);
|
||||
|
||||
assert !retry.shouldRetryRequest(command, response);
|
||||
|
||||
verify(command);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test302WithPathOnlyHeader() {
|
||||
|
||||
verifyRedirectRoutes(
|
||||
new HttpRequest("GET",
|
||||
URI.create("https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")),
|
||||
new HttpResponse(302, "HTTP/1.1 302 Found", null, ImmutableMultimap.of(HttpHeaders.LOCATION,
|
||||
"/api/v0.8b-ext2.5/Error.aspx?aspxerrorpath=/api/v0.8b-ext2.5/org.svc/1906645")),
|
||||
new HttpRequest(
|
||||
"GET",
|
||||
URI.create("https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/Error.aspx?aspxerrorpath=/api/v0.8b-ext2.5/org.svc/1906645")));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test302ToHttps() {
|
||||
|
||||
verifyRedirectRoutes(
|
||||
new HttpRequest("GET",
|
||||
URI.create("http://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")),
|
||||
new HttpResponse(302, "HTTP/1.1 302 Found", null, ImmutableMultimap.of(HttpHeaders.LOCATION,
|
||||
"https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")),//
|
||||
new HttpRequest("GET", URI
|
||||
.create("https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test302ToDifferentPort() {
|
||||
|
||||
verifyRedirectRoutes(
|
||||
new HttpRequest("GET",
|
||||
URI.create("http://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")),
|
||||
new HttpResponse(302, "HTTP/1.1 302 Found", null, ImmutableMultimap.of(HttpHeaders.LOCATION,
|
||||
"http://services.enterprisecloud.terremark.com:3030/api/v0.8b-ext2.5/org/1906645")),//
|
||||
new HttpRequest("GET", URI
|
||||
.create("http://services.enterprisecloud.terremark.com:3030/api/v0.8b-ext2.5/org/1906645")));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test302WithHeader() {
|
||||
|
||||
verifyRedirectRoutes(
|
||||
new HttpRequest("GET",
|
||||
URI.create("https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")),
|
||||
new HttpResponse(302, "HTTP/1.1 302 Found", null, ImmutableMultimap.of(HttpHeaders.LOCATION,
|
||||
"https://services1.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")), new HttpRequest(
|
||||
"GET", URI.create("https://services1.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test302WithHeaderReplacesHostHeader() {
|
||||
|
||||
verifyRedirectRoutes(
|
||||
new HttpRequest("GET",
|
||||
URI.create("https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645"),
|
||||
ImmutableMultimap.of(HttpHeaders.HOST, "services.enterprisecloud.terremark.com")),
|
||||
new HttpResponse(302, "HTTP/1.1 302 Found", null, ImmutableMultimap.of(HttpHeaders.LOCATION,
|
||||
"https://services1.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")),//
|
||||
new HttpRequest("GET", URI
|
||||
.create("https://services1.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645"),
|
||||
ImmutableMultimap.of(HttpHeaders.HOST, "services1.enterprisecloud.terremark.com")));
|
||||
|
||||
}
|
||||
|
||||
protected void verifyRedirectRoutes(HttpRequest request, HttpResponse response, HttpRequest expected) {
|
||||
HttpCommand command = createMock(HttpCommand.class);
|
||||
|
||||
expect(command.incrementRedirectCount()).andReturn(0);
|
||||
expect(command.getRequest()).andReturn(request).atLeastOnce();
|
||||
|
||||
replay(command);
|
||||
|
||||
RedirectionRetryHandler retry = Guice.createInjector(new MockModule(), new RestModule()).getInstance(
|
||||
RedirectionRetryHandler.class);
|
||||
|
||||
assert retry.shouldRetryRequest(command, response);
|
||||
assertEquals(command.getRequest(), expected);
|
||||
verify(command);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.io.payloads;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.io.Payload;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test
|
||||
public class StringPayloadTest {
|
||||
public void testLengthIsCorrectPerUTF8() {
|
||||
Payload stringPayload = new StringPayload("unic₪de");
|
||||
assertEquals(stringPayload.getContentMetadata().getContentLength(), new Long(
|
||||
"unic₪de".getBytes(Charsets.UTF_8).length));
|
||||
}
|
||||
}
|
|
@ -29,12 +29,13 @@ import static org.testng.Assert.assertNull;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.concurrent.MoreExecutors;
|
||||
import org.jclouds.concurrent.config.ConfiguresExecutorService;
|
||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.crypto.CryptoStreams;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
|
@ -47,6 +48,7 @@ import org.jclouds.rest.internal.RestAnnotationProcessor;
|
|||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
public abstract class BaseRestClientTest {
|
||||
|
||||
|
@ -69,7 +71,8 @@ public abstract class BaseRestClientTest {
|
|||
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(new ExecutorServiceModule(MoreExecutors.sameThreadExecutor(), MoreExecutors.sameThreadExecutor()));
|
||||
bind(ExecutorService.class).annotatedWith(Names.named(Constants.PROPERTY_USER_THREADS)).toInstance(MoreExecutors.sameThreadExecutor());
|
||||
bind(ExecutorService.class).annotatedWith(Names.named(Constants.PROPERTY_IO_WORKER_THREADS)).toInstance(MoreExecutors.sameThreadExecutor());
|
||||
bind(TransformingHttpCommandExecutorService.class).toInstance(mock);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import static org.easymock.classextension.EasyMock.createMock;
|
|||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
|
@ -42,6 +43,15 @@ import com.google.inject.spi.Message;
|
|||
*/
|
||||
@Test(groups = "unit", testName = "jclouds.UtilsTest")
|
||||
public class UtilsTest {
|
||||
public void testRenameKeyWhenNotFound() {
|
||||
Map<String, String> nothing = ImmutableMap.of();
|
||||
assertEquals(Utils.renameKey(nothing, "foo", "bar"), nothing);
|
||||
}
|
||||
|
||||
public void testRenameKeyWhenFound() {
|
||||
Map<String, String> nothing = ImmutableMap.of("foo", "bar");
|
||||
assertEquals(Utils.renameKey(nothing, "foo", "bar"), ImmutableMap.of("bar", "bar"));
|
||||
}
|
||||
|
||||
public void testOverridingCredentialsWhenOverridingIsNull() {
|
||||
Credentials defaultCredentials = new Credentials("foo", "bar");
|
||||
|
@ -69,7 +79,7 @@ public class UtilsTest {
|
|||
assertEquals(Utils.overrideCredentialsIfSupplied(defaultCredentials, overridingCredentials), new Credentials(
|
||||
"foo", "bar"));
|
||||
}
|
||||
|
||||
|
||||
public void testGetCause() {
|
||||
AuthorizationException aex = createMock(AuthorizationException.class);
|
||||
Message message = new Message(ImmutableList.of(), "test", aex);
|
||||
|
|
|
@ -103,7 +103,7 @@
|
|||
<dependency>
|
||||
<groupId>com.google.code.guice</groupId>
|
||||
<artifactId>guice-servlet</artifactId>
|
||||
<version>2.1-r1201</version>
|
||||
<version>3.0-snapshot-20101120</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>displaytag</groupId>
|
||||
|
|
|
@ -49,12 +49,13 @@ import java.util.Collection;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
@ -66,13 +67,13 @@ import org.jclouds.blobstore.BlobStoreContext;
|
|||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.blobstore.KeyNotFoundException;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.Blob.Factory;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
||||
import org.jclouds.blobstore.domain.MutableStorageMetadata;
|
||||
import org.jclouds.blobstore.domain.PageSet;
|
||||
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.blobstore.domain.Blob.Factory;
|
||||
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
|
||||
import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl;
|
||||
import org.jclouds.blobstore.domain.internal.PageSetImpl;
|
||||
|
@ -107,7 +108,6 @@ import com.google.common.base.Throwables;
|
|||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -335,12 +335,12 @@ public class FilesystemStorageStrategyImpl implements FilesystemStorageStrategy
|
|||
* @return the resulting string
|
||||
*/
|
||||
protected String buildPathStartingFromBaseDir(String...pathTokens) {
|
||||
String normalizedToken = removeFileSeparatorFromBorders(normalize(baseDirectory));
|
||||
String normalizedToken = removeFileSeparatorFromBorders(normalize(baseDirectory), true);
|
||||
StringBuilder completePath = new StringBuilder(normalizedToken);
|
||||
if(pathTokens!=null && pathTokens.length>0) {
|
||||
for(int i=0; i<pathTokens.length; i++) {
|
||||
if(pathTokens[i]!=null) {
|
||||
normalizedToken = removeFileSeparatorFromBorders(normalize(pathTokens[i]));
|
||||
normalizedToken = removeFileSeparatorFromBorders(normalize(pathTokens[i]), false);
|
||||
completePath.append(File.separator).append(normalizedToken);
|
||||
}
|
||||
}
|
||||
|
@ -367,16 +367,19 @@ public class FilesystemStorageStrategyImpl implements FilesystemStorageStrategy
|
|||
* Remove leading and trailing {@link File.separator} character from the
|
||||
* string.
|
||||
* @param pathToBeCleaned
|
||||
* @param remove only trailing separator char from path
|
||||
* @return
|
||||
*/
|
||||
private String removeFileSeparatorFromBorders(String pathToBeCleaned) {
|
||||
private String removeFileSeparatorFromBorders(String pathToBeCleaned, boolean onlyTrailing) {
|
||||
if (null == pathToBeCleaned || pathToBeCleaned.equals("")) return pathToBeCleaned;
|
||||
|
||||
int beginIndex = 0;
|
||||
int endIndex = pathToBeCleaned.length();
|
||||
|
||||
//search for separator chars
|
||||
if (pathToBeCleaned.substring(0, 1).equals(File.separator)) beginIndex = 1;
|
||||
if (!onlyTrailing) {
|
||||
if (pathToBeCleaned.substring(0, 1).equals(File.separator)) beginIndex = 1;
|
||||
}
|
||||
if (pathToBeCleaned.substring(pathToBeCleaned.length() - 1).equals(File.separator)) endIndex--;
|
||||
|
||||
return pathToBeCleaned.substring(beginIndex, endIndex);
|
||||
|
|
|
@ -185,16 +185,8 @@ public class FilesystemAsyncBlobStoreTest {
|
|||
/**
|
||||
* Test of list method, of class FilesystemAsyncBlobStore.
|
||||
*/
|
||||
public void testList_NoOptionSingleContainer() throws IOException {
|
||||
|
||||
// Testing list for a not existing container
|
||||
try {
|
||||
blobStore.list(CONTAINER_NAME);
|
||||
fail("Found a not existing container");
|
||||
} catch(ContainerNotFoundException e) {
|
||||
|
||||
}
|
||||
|
||||
public void testList_NoOptionSingleContainer()
|
||||
throws IOException {
|
||||
blobStore.createContainerInLocation(null, CONTAINER_NAME);
|
||||
// Testing list for an empty container
|
||||
checkForContainerContent(CONTAINER_NAME, null);
|
||||
|
@ -268,6 +260,29 @@ public class FilesystemAsyncBlobStoreTest {
|
|||
}
|
||||
|
||||
|
||||
public void testList_Subdirectory()
|
||||
throws IOException {
|
||||
blobStore.createContainerInLocation(null, CONTAINER_NAME);
|
||||
// Testing list for an empty container
|
||||
checkForContainerContent(CONTAINER_NAME, null);
|
||||
|
||||
//creates blobs in first container
|
||||
Set<String> blobsExpected = TestUtils.createBlobsInContainer(
|
||||
CONTAINER_NAME,
|
||||
new String[] {
|
||||
"bbb" + File.separator + "ccc" + File.separator + "ddd" + File.separator + "1234.jpg",
|
||||
"4rrr.jpg",
|
||||
"rrr" + File.separator + "sss" + File.separator + "788.jpg",
|
||||
"rrr" + File.separator + "wert.kpg" }
|
||||
);
|
||||
|
||||
//remove not expected values
|
||||
blobsExpected.remove("bbb" + File.separator + "ccc" + File.separator + "ddd" + File.separator + "1234.jpg");
|
||||
blobsExpected.remove("4rrr.jpg");
|
||||
|
||||
checkForContainerContent(CONTAINER_NAME, "rrr", blobsExpected);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* Should throws an exception?
|
||||
|
@ -809,12 +824,17 @@ public class FilesystemAsyncBlobStoreTest {
|
|||
* @param expectedBlobKeys
|
||||
*/
|
||||
private void checkForContainerContent(final String containerName, Set<String> expectedBlobKeys) {
|
||||
checkForContainerContent(containerName, null, expectedBlobKeys);
|
||||
}
|
||||
|
||||
private void checkForContainerContent(final String containerName, String inDirectory, Set<String> expectedBlobKeys) {
|
||||
ListContainerOptions options = ListContainerOptions.Builder.recursive();
|
||||
if (null != inDirectory && !"".equals(inDirectory)) options.inDirectory(inDirectory);
|
||||
|
||||
PageSet<? extends StorageMetadata> blobsRetrieved = blobStore.list(containerName, options);
|
||||
|
||||
//nothing expected
|
||||
if (null == expectedBlobKeys) {
|
||||
if (null == expectedBlobKeys || 0 == expectedBlobKeys.size()) {
|
||||
assertTrue(blobsRetrieved.isEmpty(), "Wrong blob number retrieved in the containter [" + containerName + "]");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -417,6 +417,38 @@ public class FilesystemStorageStrategyImplTest {
|
|||
}
|
||||
|
||||
|
||||
public void testGetFileForBlobKey_AbsolutePath()
|
||||
throws IOException {
|
||||
String absoluteBasePath = (new File(getAbsoluteDirectory(), "basedir")).getAbsolutePath() + FS;
|
||||
String absoluteContainerPath = absoluteBasePath + CONTAINER_NAME + FS;
|
||||
|
||||
//create storageStrategy with an absolute path
|
||||
FilesystemStorageStrategy storageStrategyAbsolute = new FilesystemStorageStrategyImpl(
|
||||
new Blob.Factory() {
|
||||
@Override
|
||||
public Blob create(MutableBlobMetadata metadata) {
|
||||
return new BlobImpl(metadata != null ? metadata : new MutableBlobMetadataImpl());
|
||||
}
|
||||
},
|
||||
absoluteBasePath,
|
||||
new FilesystemContainerNameValidatorImpl(),
|
||||
new FilesystemBlobKeyValidatorImpl());
|
||||
TestUtils.cleanDirectoryContent(absoluteContainerPath);
|
||||
|
||||
String blobKey;
|
||||
File fileForPayload;
|
||||
|
||||
blobKey = TestUtils.createRandomBlobKey("getFileForBlobKey-", ".img");
|
||||
fileForPayload = storageStrategyAbsolute.getFileForBlobKey(CONTAINER_NAME, blobKey);
|
||||
assertNotNull(fileForPayload, "Result File object is null");
|
||||
assertEquals(fileForPayload.getAbsolutePath(), absoluteContainerPath + blobKey, "Wrong file path");
|
||||
|
||||
blobKey = TestUtils.createRandomBlobKey("asd" + FS + "vmad" + FS + "andsnf" + FS + "getFileForBlobKey-", ".img");
|
||||
fileForPayload = storageStrategyAbsolute.getFileForBlobKey(CONTAINER_NAME, blobKey);
|
||||
assertEquals(fileForPayload.getAbsolutePath(), absoluteContainerPath + blobKey, "Wrong file path");
|
||||
}
|
||||
|
||||
|
||||
public void testBlobExists() throws IOException {
|
||||
String[] sourceBlobKeys = new String[]{
|
||||
TestUtils.createRandomBlobKey("blobExists-", ".jpg"),
|
||||
|
@ -530,5 +562,16 @@ public class FilesystemStorageStrategyImplTest {
|
|||
//---------------------------------------------------------- Private methods
|
||||
|
||||
|
||||
/**
|
||||
* Calculates an absolute directory path that depends on operative system
|
||||
* @return
|
||||
*/
|
||||
private String getAbsoluteDirectory() throws IOException {
|
||||
File tempFile = File.createTempFile("prefix", "suffix");
|
||||
String tempAbsolutePath = tempFile.getParent();
|
||||
|
||||
return tempAbsolutePath;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -89,6 +89,8 @@ public class ServerImage implements Comparable<ServerImage> {
|
|||
}
|
||||
|
||||
public String getDescription() {
|
||||
if (description == null)
|
||||
return "";
|
||||
return description;
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,8 @@ public class ParseServerNameToCredentialsMapFromJsonResponse implements
|
|||
|
||||
@Override
|
||||
public int compareTo(Password o) {
|
||||
return server.getName().compareTo(o.getServer().getName());
|
||||
if (null == o.getServer() || null == server) return -1;
|
||||
return server.getName().compareTo(o.getServer().getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,6 +108,7 @@ public class ParseServerNameToCredentialsMapFromJsonResponse implements
|
|||
public Map<String, Credentials> apply(HttpResponse arg0) {
|
||||
Map<String, Credentials> serverNameToCredentials = Maps.newHashMap();
|
||||
for (Password password : json.apply(arg0).getList()) {
|
||||
if( null != password.getServer())
|
||||
serverNameToCredentials.put(password.getServer().getName(),
|
||||
new Credentials(password.getUserName(), password.getPassword()));
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ public class ParseCredentialsFromJsonResponseTest {
|
|||
ParseCredentialsFromJsonResponse parser = i.getInstance(ParseCredentialsFromJsonResponse.class);
|
||||
Credentials creds = parser.apply(response);
|
||||
assertEquals(creds.identity, "root");
|
||||
assertEquals(creds.credential, "dig44sos");
|
||||
assertEquals(creds.credential, "zot40ced");
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,103 +1,124 @@
|
|||
{
|
||||
"list": [
|
||||
{
|
||||
"password": "dig44sos",
|
||||
"object": "password",
|
||||
"username": "root",
|
||||
"server": {
|
||||
"object": "server",
|
||||
"isSandbox": false,
|
||||
{
|
||||
"password": "zot40ced",
|
||||
"object": "password",
|
||||
"username": "root",
|
||||
"server": {
|
||||
"isSandbox": false,
|
||||
"object": "server",
|
||||
"type": {
|
||||
"id": 1,
|
||||
"description": "Web or Application Server",
|
||||
"name": "Web Server",
|
||||
"object": "option"
|
||||
},
|
||||
"os": {
|
||||
"id": 17,
|
||||
"description": "CentOS 5.3 (64-bit)",
|
||||
"name": "CentOS 5.3 (64-bit)",
|
||||
"object": "option"
|
||||
},
|
||||
"image": {
|
||||
"type": {
|
||||
"object": "option",
|
||||
"id": 1,
|
||||
"description": "Web or Application Server",
|
||||
"name": "Web Server",
|
||||
"id": 1
|
||||
"object": "option"
|
||||
},
|
||||
"owner": {
|
||||
"id": -1,
|
||||
"name": "GoGrid",
|
||||
"object": "customer"
|
||||
},
|
||||
"updatedTime": 1257789076417,
|
||||
"isActive": true,
|
||||
"id": 1532,
|
||||
"isPublic": true,
|
||||
"name": "centos5.3_64_base",
|
||||
"billingtokens": [
|
||||
{
|
||||
"id": 47,
|
||||
"price": 0,
|
||||
"name": "CentOS 5.3 64bit",
|
||||
"object": "billingtoken"
|
||||
}
|
||||
],
|
||||
"object": "serverimage",
|
||||
"friendlyName": "CentOS 5.3 (64-bit) w/ None",
|
||||
"os": {
|
||||
"object": "option",
|
||||
"id": 17,
|
||||
"description": "CentOS 5.3 (64-bit)",
|
||||
"name": "CentOS 5.3 (64-bit)",
|
||||
"id": 17
|
||||
},
|
||||
"image": {
|
||||
"type": {
|
||||
"object": "option",
|
||||
"description": "Web or Application Server",
|
||||
"name": "Web Server",
|
||||
"id": 1
|
||||
},
|
||||
"owner": {
|
||||
"object": "customer",
|
||||
"name": "Gear6",
|
||||
"id": 26443
|
||||
},
|
||||
"updatedTime": 1265675466171,
|
||||
"isActive": true,
|
||||
"id": 2500,
|
||||
"createdTime": 1265412834154,
|
||||
"isPublic": true,
|
||||
"billingtokens": [
|
||||
{
|
||||
"price": 0,
|
||||
"name": "CentOS 5.3 64bit",
|
||||
"id": 47
|
||||
},
|
||||
{
|
||||
"price": 60,
|
||||
"name": "Gear 6 Paid Version",
|
||||
"id": 76
|
||||
}
|
||||
],
|
||||
"object": "serverimage",
|
||||
"friendlyName": "gear6-memcache-server-2.3.6.2-x86_64",
|
||||
"os": {
|
||||
"object": "option",
|
||||
"description": "CentOS 5.3 (64-bit)",
|
||||
"name": "CentOS 5.3 (64-bit)",
|
||||
"id": 17
|
||||
},
|
||||
"price": 60,
|
||||
"description": "Gear6 Memcache Server 2.3.6.2 (64 bit)",
|
||||
"state": {
|
||||
"object": "option",
|
||||
"description": "Image is available for adds",
|
||||
"name": "Available",
|
||||
"id": 2
|
||||
},
|
||||
"location": "26443/GSI-7f498260-2b8a-43ef-aa77-5b403f8f739a.img",
|
||||
"name": "GSI-7f498260-2b8a-43ef-aa77-5b403f8f739a"
|
||||
"object": "option"
|
||||
},
|
||||
"price": 0,
|
||||
"description": "CentOS 5.3 (64-bit) w/ None",
|
||||
"state": {
|
||||
"object": "option",
|
||||
"description": "Server is in active state.",
|
||||
"name": "On",
|
||||
"id": 1
|
||||
"id": 2,
|
||||
"description": "Image is available for adds",
|
||||
"name": "Available",
|
||||
"object": "option"
|
||||
},
|
||||
"ram": {
|
||||
"object": "option",
|
||||
"description": "Server with 512MB RAM",
|
||||
"name": "512MB",
|
||||
"id": 1
|
||||
},
|
||||
"name": "gogrid-19",
|
||||
"ip": {
|
||||
"object": "ip",
|
||||
"public": true,
|
||||
"subnet": "204.51.240.176/255.255.255.240",
|
||||
"state": {
|
||||
"object": "option",
|
||||
"description": "IP is reserved or in use",
|
||||
"name": "Assigned",
|
||||
"id": 2
|
||||
},
|
||||
"ip": "204.51.240.189",
|
||||
"id": 1313090
|
||||
},
|
||||
"id": 77332
|
||||
"location": "gogrid/GSI-939ef909-84b8-4a2f-ad56-02ccd7da05ff.img",
|
||||
"name": "bogus",
|
||||
"architecture": {
|
||||
"id": 2,
|
||||
"description": "64 bit OS",
|
||||
"name": "64-bit",
|
||||
"object": "option"
|
||||
}
|
||||
},
|
||||
"id": 82647,
|
||||
"applicationtype": "os"
|
||||
}
|
||||
"state": {
|
||||
"id": 1,
|
||||
"description": "Server is in active state.",
|
||||
"name": "On",
|
||||
"object": "option"
|
||||
},
|
||||
"ram": {
|
||||
"id": 1,
|
||||
"description": "Server with 512MB RAM",
|
||||
"name": "512MB",
|
||||
"object": "option"
|
||||
},
|
||||
"name": "proxied-944",
|
||||
"ip": {
|
||||
"id": 1104200,
|
||||
"subnet": "173.1.155.16/255.255.255.240",
|
||||
"state": {
|
||||
"id": 2,
|
||||
"description": "IP is reserved or in use",
|
||||
"name": "Assigned",
|
||||
"object": "option"
|
||||
},
|
||||
"datacenter": {
|
||||
"id": 1,
|
||||
"description": "US West 1 Datacenter",
|
||||
"name": "US-West-1",
|
||||
"object": "option"
|
||||
},
|
||||
"object": "ip",
|
||||
"public": true,
|
||||
"ip": "173.1.155.19"
|
||||
},
|
||||
"datacenter": {
|
||||
"id": 1,
|
||||
"description": "US West 1 Datacenter",
|
||||
"name": "US-West-1",
|
||||
"object": "option"
|
||||
},
|
||||
"id": 134551
|
||||
},
|
||||
"id": 142243,
|
||||
"applicationtype": "os"
|
||||
},
|
||||
{
|
||||
"id": 28000,
|
||||
"username": "22290",
|
||||
"applicationtype": "cloudstorage",
|
||||
"object": "password",
|
||||
"password": "200FMd2nDeomtfW."
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"total": 6,
|
||||
|
@ -107,4 +128,4 @@
|
|||
},
|
||||
"status": "success",
|
||||
"method": "/support/password/list"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,10 +19,11 @@
|
|||
|
||||
package org.jclouds.rackspace.cloudfiles.domain;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.io.PayloadEnclosing;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -24,11 +24,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (C) 2010 Cloud Conscious, LLC <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF 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.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
====================================================================
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<artifactId>jclouds-project</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../../project/pom.xml</relativePath>
|
||||
</parent>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<artifactId>jclouds-elasticstack</artifactId>
|
||||
<name>jclouds elasticstack core</name>
|
||||
<description>jclouds components to access elasticstack</description>
|
||||
|
||||
<scm>
|
||||
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/elasticstack</connection>
|
||||
<developerConnection>scm:svn:https://jclouds.googlecode.com/svn/trunk/elasticstack</developerConnection>
|
||||
<url>http://jclouds.googlecode.com/svn/trunk/elasticstack</url>
|
||||
</scm>
|
||||
|
||||
<!-- bootstrapping: need to fetch the project POM -->
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jclouds-googlecode-deploy</id>
|
||||
<url>http://jclouds.googlecode.com/svn/repo</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>jclouds-rimu-snapshots-nexus</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<properties>
|
||||
<!-- when instances are hung, open a ticket and add here -->
|
||||
<jclouds.compute.blacklist-nodes>trmkrun-ccc,test.trmk-924</jclouds.compute.blacklist-nodes>
|
||||
<test.elasticstack.endpoint>https://api.cloudsigma.com</test.elasticstack.endpoint>
|
||||
<test.elasticstack.apiversion>1.0</test.elasticstack.apiversion>
|
||||
<test.elasticstack.identity>FIXME</test.elasticstack.identity>
|
||||
<test.elasticstack.credential>FIXME</test.elasticstack.credential>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.14</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-log4j</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>live</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>integration</id>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>test.elasticstack.endpoint</name>
|
||||
<value>${test.elasticstack.endpoint}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.elasticstack.apiversion</name>
|
||||
<value>${test.elasticstack.apiversion}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.elasticstack.identity</name>
|
||||
<value>${test.elasticstack.identity}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.elasticstack.credential</name>
|
||||
<value>${test.elasticstack.credential}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>jclouds.compute.blacklist-nodes</name>
|
||||
<value>${jclouds.compute.blacklist-nodes}</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -0,0 +1,125 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudsigma;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.cloudsigma.domain.DriveInfo;
|
||||
import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToDriveInfo;
|
||||
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet;
|
||||
import org.jclouds.elasticstack.CommonElasticStackAsyncClient;
|
||||
import org.jclouds.elasticstack.ElasticStackClient;
|
||||
import org.jclouds.elasticstack.binders.BindCreateDriveRequestToPlainTextString;
|
||||
import org.jclouds.elasticstack.binders.BindDriveDataToPlainTextString;
|
||||
import org.jclouds.elasticstack.domain.CreateDriveRequest;
|
||||
import org.jclouds.elasticstack.domain.DriveData;
|
||||
import org.jclouds.elasticstack.functions.SplitNewlines;
|
||||
import org.jclouds.http.filters.BasicAuthentication;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to CloudSigma via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
* @see ElasticStackClient
|
||||
* @see <a href="TODO: insert URL of provider documentation" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@RequestFilters(BasicAuthentication.class)
|
||||
@Consumes(MediaType.TEXT_PLAIN)
|
||||
public interface CloudSigmaAsyncClient extends CommonElasticStackAsyncClient {
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#listStandardDrives()
|
||||
*/
|
||||
@GET
|
||||
@Path("/drives/standard/list")
|
||||
@ResponseParser(SplitNewlines.class)
|
||||
ListenableFuture<Set<String>> listStandardDrives();
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#listStandardCds()
|
||||
*/
|
||||
@GET
|
||||
@Path("/drives/standard/cd/list")
|
||||
@ResponseParser(SplitNewlines.class)
|
||||
ListenableFuture<Set<String>> listStandardCds();
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#listStandardImages()
|
||||
*/
|
||||
@GET
|
||||
@Path("/drives/standard/img/list")
|
||||
@ResponseParser(SplitNewlines.class)
|
||||
ListenableFuture<Set<String>> listStandardImages();
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#listDriveInfo()
|
||||
*/
|
||||
@Override
|
||||
@GET
|
||||
@Path("/drives/info")
|
||||
@ResponseParser(ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet.class)
|
||||
ListenableFuture<Set<? extends org.jclouds.elasticstack.domain.DriveInfo>> listDriveInfo();
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#getDriveInfo
|
||||
*/
|
||||
@Override
|
||||
@GET
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
@ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class)
|
||||
@Path("/drives/{uuid}/info")
|
||||
ListenableFuture<? extends DriveInfo> getDriveInfo(@PathParam("uuid") String uuid);
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#createDrive
|
||||
*/
|
||||
@Override
|
||||
@POST
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
@ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class)
|
||||
@Path("/drives/create")
|
||||
ListenableFuture<? extends DriveInfo> createDrive(
|
||||
@BinderParam(BindCreateDriveRequestToPlainTextString.class) CreateDriveRequest createDrive);
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#setDriveData
|
||||
*/
|
||||
@POST
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
@ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class)
|
||||
@Path("/drives/{uuid}/set")
|
||||
ListenableFuture<? extends DriveInfo> setDriveData(@PathParam("uuid") String uuid,
|
||||
@BinderParam(BindDriveDataToPlainTextString.class) DriveData createDrive);
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudsigma;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.cloudsigma.domain.DriveInfo;
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.elasticstack.CommonElasticStackClient;
|
||||
import org.jclouds.elasticstack.domain.CreateDriveRequest;
|
||||
import org.jclouds.elasticstack.domain.DriveData;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to CloudSigma.
|
||||
* <p/>
|
||||
*
|
||||
* @see CloudSigmaAsyncClient
|
||||
* @see <a href="TODO: insert URL of elasticstack documentation" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
|
||||
public interface CloudSigmaClient extends CommonElasticStackClient {
|
||||
|
||||
/**
|
||||
* list of drive uuids that are in the library
|
||||
*
|
||||
* @return or empty set if no drives are found
|
||||
*/
|
||||
Set<String> listStandardDrives();
|
||||
|
||||
/**
|
||||
* list of cd uuids that are in the library
|
||||
*
|
||||
* @return or empty set if no cds are found
|
||||
*/
|
||||
Set<String> listStandardCds();
|
||||
|
||||
/**
|
||||
* list of image uuids that are in the library
|
||||
*
|
||||
* @return or empty set if no images are found
|
||||
*/
|
||||
Set<String> listStandardImages();
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
Set<? extends DriveInfo> listDriveInfo();
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
DriveInfo getDriveInfo(String uuid);
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
DriveInfo createDrive(CreateDriveRequest createDrive);
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
DriveInfo setDriveData(String uuid, DriveData driveData);
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudsigma;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.cloudsigma.config.CloudSigmaRestClientModule;
|
||||
import org.jclouds.rest.RestContextBuilder;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class CloudSigmaContextBuilder extends
|
||||
RestContextBuilder<CloudSigmaClient, CloudSigmaAsyncClient> {
|
||||
|
||||
public CloudSigmaContextBuilder(Properties props) {
|
||||
super(CloudSigmaClient.class, CloudSigmaAsyncClient.class, props);
|
||||
}
|
||||
|
||||
protected void addClientModule(List<Module> modules) {
|
||||
modules.add(new CloudSigmaRestClientModule());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudsigma;
|
||||
|
||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.PropertiesBuilder;
|
||||
|
||||
/**
|
||||
* Builds properties used in CloudSigma Clients
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class CloudSigmaPropertiesBuilder extends PropertiesBuilder {
|
||||
@Override
|
||||
protected Properties defaultProperties() {
|
||||
Properties properties = super.defaultProperties();
|
||||
properties.setProperty(PROPERTY_ENDPOINT, "https://api.cloudsigma.com");
|
||||
properties.setProperty(PROPERTY_API_VERSION, "1.0");
|
||||
return properties;
|
||||
}
|
||||
|
||||
public CloudSigmaPropertiesBuilder(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudsigma.config;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.cloudsigma.CloudSigmaAsyncClient;
|
||||
import org.jclouds.cloudsigma.CloudSigmaClient;
|
||||
import org.jclouds.cloudsigma.functions.CreateDriveRequestToMap;
|
||||
import org.jclouds.cloudsigma.functions.DriveDataToMap;
|
||||
import org.jclouds.elasticstack.domain.CreateDriveRequest;
|
||||
import org.jclouds.elasticstack.domain.DriveData;
|
||||
import org.jclouds.elasticstack.handlers.ElasticStackErrorHandler;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.annotation.Redirection;
|
||||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Configures the CloudSigma connection.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@RequiresHttp
|
||||
@ConfiguresRestClient
|
||||
public class CloudSigmaRestClientModule extends RestClientModule<CloudSigmaClient, CloudSigmaAsyncClient> {
|
||||
|
||||
public CloudSigmaRestClientModule() {
|
||||
super(CloudSigmaClient.class, CloudSigmaAsyncClient.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ElasticStackErrorHandler.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ElasticStackErrorHandler.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ElasticStackErrorHandler.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
bind(new TypeLiteral<Function<CreateDriveRequest, Map<String, String>>>() {
|
||||
}).to(CreateDriveRequestToMap.class);
|
||||
bind(new TypeLiteral<Function<DriveData, Map<String, String>>>() {
|
||||
}).to(DriveDataToMap.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindRetryHandlers() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,415 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudsigma.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.elasticstack.domain.ClaimType;
|
||||
import org.jclouds.elasticstack.domain.DriveStatus;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class DriveInfo extends org.jclouds.elasticstack.domain.DriveInfo {
|
||||
public static class Builder extends org.jclouds.elasticstack.domain.DriveInfo.Builder {
|
||||
private Boolean autoexpanding;
|
||||
private Integer bits;
|
||||
private String description;
|
||||
private Set<String> driveType = ImmutableSet.of();
|
||||
private String encryptionKey;
|
||||
private Boolean free;
|
||||
private String installNotes;
|
||||
private String os;
|
||||
private DriveType type;
|
||||
private URI url;
|
||||
|
||||
public Builder autoexpanding(Boolean autoexpanding) {
|
||||
this.autoexpanding = autoexpanding;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder bits(Integer bits) {
|
||||
this.bits = bits;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder description(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder driveType(Iterable<String> driveType) {
|
||||
this.driveType = ImmutableSet.copyOf(checkNotNull(driveType, "driveType"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder encryptionKey(String encryptionKey) {
|
||||
this.encryptionKey = encryptionKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder free(Boolean free) {
|
||||
this.free = free;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder installNotes(String installNotes) {
|
||||
this.installNotes = installNotes;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder os(String os) {
|
||||
this.os = os;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder type(DriveType type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder url(URI url) {
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder status(DriveStatus status) {
|
||||
return Builder.class.cast(super.status(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder user(String user) {
|
||||
return Builder.class.cast(super.user(user));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder claimed(Iterable<String> claimed) {
|
||||
return Builder.class.cast(super.claimed(claimed));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder imaging(String imaging) {
|
||||
return Builder.class.cast(super.imaging(imaging));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder readBytes(long readBytes) {
|
||||
return Builder.class.cast(super.readBytes(readBytes));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder readRequests(long readRequests) {
|
||||
return Builder.class.cast(super.readRequests(readRequests));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder writeBytes(long writeBytes) {
|
||||
return Builder.class.cast(super.writeBytes(writeBytes));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder writeRequests(long writeRequests) {
|
||||
return Builder.class.cast(super.writeRequests(writeRequests));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder encryptionCipher(String encryptionCipher) {
|
||||
return Builder.class.cast(super.encryptionCipher(encryptionCipher));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder claimType(ClaimType claimType) {
|
||||
return Builder.class.cast(super.claimType(claimType));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder readers(Iterable<String> readers) {
|
||||
return Builder.class.cast(super.readers(readers));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder size(long size) {
|
||||
return Builder.class.cast(super.size(size));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder uuid(String uuid) {
|
||||
return Builder.class.cast(super.uuid(uuid));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder name(String name) {
|
||||
return Builder.class.cast(super.name(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder tags(Iterable<String> tags) {
|
||||
return Builder.class.cast(super.tags(tags));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder userMetadata(Map<String, String> userMetadata) {
|
||||
return Builder.class.cast(super.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
public static Builder fromDriveInfo(org.jclouds.elasticstack.domain.DriveInfo driveInfo) {
|
||||
return new Builder().uuid(driveInfo.getUuid()).name(driveInfo.getName()).size(driveInfo.getSize())
|
||||
.claimType(driveInfo.getClaimType()).readers(driveInfo.getReaders()).tags(driveInfo.getTags())
|
||||
.userMetadata(driveInfo.getUserMetadata()).status(driveInfo.getStatus()).user(driveInfo.getUser())
|
||||
.claimed(driveInfo.getClaimed()).encryptionCipher(driveInfo.getEncryptionCipher())
|
||||
.imaging(driveInfo.getImaging()).readBytes(driveInfo.getReadBytes())
|
||||
.readRequests(driveInfo.getReadRequests()).writeBytes(driveInfo.getWriteBytes())
|
||||
.writeRequests(driveInfo.getWriteRequests());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public DriveInfo build() {
|
||||
return new DriveInfo(uuid, name, size, claimType, readers, tags, userMetadata, status, user, claimed,
|
||||
encryptionCipher, imaging, readBytes, readRequests, writeBytes, writeRequests, autoexpanding, bits,
|
||||
description, driveType, encryptionKey, free, installNotes, os, type, url);
|
||||
}
|
||||
}
|
||||
|
||||
private final Boolean autoexpanding;
|
||||
private final Integer bits;
|
||||
private final String description;
|
||||
private final ImmutableSet<String> driveType;
|
||||
private final String encryptionKey;
|
||||
private final Boolean free;
|
||||
private final String installNotes;
|
||||
private final String os;
|
||||
private final DriveType type;
|
||||
private final URI url;
|
||||
|
||||
public DriveInfo(String uuid, String name, long size, ClaimType claimType, Iterable<String> readers,
|
||||
Iterable<String> tags, Map<String, String> userMetadata, DriveStatus status, String user, Set<String> claimed,
|
||||
String encryptionCipher, String imaging, long readBytes, long readRequests, long writeBytes,
|
||||
long writeRequests, Boolean autoexpanding, Integer bits, String description, Iterable<String> driveType,
|
||||
String encryptionKey, Boolean free, String installNotes, String os, DriveType type, URI url) {
|
||||
super(uuid, name, size, claimType, readers, tags, userMetadata, status, user, claimed, encryptionCipher, imaging,
|
||||
readBytes, readRequests, writeBytes, writeRequests);
|
||||
this.autoexpanding = autoexpanding;
|
||||
this.bits = bits;
|
||||
this.description = description;
|
||||
this.driveType = ImmutableSet.copyOf(driveType);
|
||||
this.encryptionKey = encryptionKey;
|
||||
this.free = free;
|
||||
this.installNotes = installNotes;
|
||||
this.os = os;
|
||||
this.type = type;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((autoexpanding == null) ? 0 : autoexpanding.hashCode());
|
||||
result = prime * result + ((bits == null) ? 0 : bits.hashCode());
|
||||
result = prime * result + ((description == null) ? 0 : description.hashCode());
|
||||
result = prime * result + ((driveType == null) ? 0 : driveType.hashCode());
|
||||
result = prime * result + ((encryptionKey == null) ? 0 : encryptionKey.hashCode());
|
||||
result = prime * result + ((free == null) ? 0 : free.hashCode());
|
||||
result = prime * result + ((installNotes == null) ? 0 : installNotes.hashCode());
|
||||
result = prime * result + ((os == null) ? 0 : os.hashCode());
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
result = prime * result + ((url == null) ? 0 : url.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
DriveInfo other = (DriveInfo) obj;
|
||||
if (autoexpanding == null) {
|
||||
if (other.autoexpanding != null)
|
||||
return false;
|
||||
} else if (!autoexpanding.equals(other.autoexpanding))
|
||||
return false;
|
||||
if (bits == null) {
|
||||
if (other.bits != null)
|
||||
return false;
|
||||
} else if (!bits.equals(other.bits))
|
||||
return false;
|
||||
if (description == null) {
|
||||
if (other.description != null)
|
||||
return false;
|
||||
} else if (!description.equals(other.description))
|
||||
return false;
|
||||
if (driveType == null) {
|
||||
if (other.driveType != null)
|
||||
return false;
|
||||
} else if (!driveType.equals(other.driveType))
|
||||
return false;
|
||||
if (encryptionKey == null) {
|
||||
if (other.encryptionKey != null)
|
||||
return false;
|
||||
} else if (!encryptionKey.equals(other.encryptionKey))
|
||||
return false;
|
||||
if (free == null) {
|
||||
if (other.free != null)
|
||||
return false;
|
||||
} else if (!free.equals(other.free))
|
||||
return false;
|
||||
if (installNotes == null) {
|
||||
if (other.installNotes != null)
|
||||
return false;
|
||||
} else if (!installNotes.equals(other.installNotes))
|
||||
return false;
|
||||
if (os == null) {
|
||||
if (other.os != null)
|
||||
return false;
|
||||
} else if (!os.equals(other.os))
|
||||
return false;
|
||||
if (type != other.type)
|
||||
return false;
|
||||
if (url == null) {
|
||||
if (other.url != null)
|
||||
return false;
|
||||
} else if (!url.equals(other.url))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO
|
||||
public Boolean getAutoexpanding() {
|
||||
return autoexpanding;
|
||||
}
|
||||
|
||||
// TODO
|
||||
public Integer getBits() {
|
||||
return bits;
|
||||
}
|
||||
|
||||
// TODO undocumented
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
// TODO
|
||||
public Set<String> getDriveType() {
|
||||
return driveType;
|
||||
}
|
||||
|
||||
// TODO
|
||||
public String getEncryptionKey() {
|
||||
return encryptionKey;
|
||||
}
|
||||
|
||||
// TODO
|
||||
public Boolean getFree() {
|
||||
return free;
|
||||
}
|
||||
|
||||
// TODO
|
||||
public String getInstallNotes() {
|
||||
return installNotes;
|
||||
}
|
||||
|
||||
// TODO
|
||||
public String getOs() {
|
||||
return os;
|
||||
}
|
||||
|
||||
// TODO
|
||||
public DriveType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[size=" + size + ", claimType=" + claimType + ", readers=" + readers + ", uuid=" + uuid + ", name="
|
||||
+ name + ", tags=" + tags + ", userMetadata=" + userMetadata + ", autoexpanding=" + autoexpanding
|
||||
+ ", bits=" + bits + ", description=" + description + ", driveType=" + driveType + ", encryptionKey="
|
||||
+ encryptionKey + ", free=" + free + ", installNotes=" + installNotes + ", os=" + os + ", type=" + type
|
||||
+ ", url=" + url + "]";
|
||||
}
|
||||
|
||||
public URI getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudsigma.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum DriveType {
|
||||
DISK, CDROM, SHARED, UNRECOGNIZED;
|
||||
|
||||
public String value() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value();
|
||||
}
|
||||
|
||||
public static DriveType fromValue(String type) {
|
||||
try {
|
||||
return valueOf(checkNotNull(type, "type").toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudsigma.functions;
|
||||
|
||||
import static org.jclouds.util.Utils.renameKey;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.elasticstack.domain.CreateDriveRequest;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class CreateDriveRequestToMap implements Function<CreateDriveRequest, Map<String, String>> {
|
||||
private final org.jclouds.elasticstack.functions.CreateDriveRequestToMap baseDriveToMap;
|
||||
|
||||
@Inject
|
||||
public CreateDriveRequestToMap(org.jclouds.elasticstack.functions.CreateDriveRequestToMap baseDriveToMap) {
|
||||
this.baseDriveToMap = baseDriveToMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> apply(CreateDriveRequest from) {
|
||||
return Maps.transformEntries(renameKey(baseDriveToMap.apply(from), "tags", "use"),
|
||||
new Maps.EntryTransformer<String, String, String>() {
|
||||
|
||||
@Override
|
||||
public String transformEntry(String arg0, String arg1) {
|
||||
return "use".equals(arg0) ? arg1.replace(' ', ',') : arg1;
|
||||
}
|
||||
|
||||
}); }
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudsigma.functions;
|
||||
|
||||
import static org.jclouds.util.Utils.renameKey;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.elasticstack.domain.DriveData;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class DriveDataToMap implements Function<DriveData, Map<String, String>> {
|
||||
private final org.jclouds.elasticstack.functions.DriveDataToMap baseDriveToMap;
|
||||
|
||||
@Inject
|
||||
public DriveDataToMap(org.jclouds.elasticstack.functions.DriveDataToMap baseDriveToMap) {
|
||||
this.baseDriveToMap = baseDriveToMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> apply(DriveData from) {
|
||||
return Maps.transformEntries(renameKey(baseDriveToMap.apply(from), "tags", "use"),
|
||||
new Maps.EntryTransformer<String, String, String>() {
|
||||
|
||||
@Override
|
||||
public String transformEntry(String arg0, String arg1) {
|
||||
return "use".equals(arg0) ? arg1.replace(' ', ',') : arg1;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudsigma.functions;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.cloudsigma.domain.DriveInfo;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class KeyValuesDelimitedByBlankLinesToDriveInfo implements Function<HttpResponse, DriveInfo> {
|
||||
private final ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet setParser;
|
||||
|
||||
@Inject
|
||||
public KeyValuesDelimitedByBlankLinesToDriveInfo(ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet setParser) {
|
||||
this.setParser = setParser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DriveInfo apply(HttpResponse response) {
|
||||
Set<DriveInfo> drives = setParser.apply(response);
|
||||
if (drives.size() == 0)
|
||||
return null;
|
||||
return Iterables.get(drives, 0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudsigma.functions;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.cloudsigma.domain.DriveInfo;
|
||||
import org.jclouds.elasticstack.functions.ListOfKeyValuesDelimitedByBlankLinesToListOfMaps;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.ReturnStringIf2xx;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet implements Function<HttpResponse, Set<DriveInfo>> {
|
||||
private final ReturnStringIf2xx returnStringIf200;
|
||||
private final ListOfKeyValuesDelimitedByBlankLinesToListOfMaps mapConverter;
|
||||
private final MapToDriveInfo mapToDrive;
|
||||
|
||||
@Inject
|
||||
ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet(ReturnStringIf2xx returnStringIf200,
|
||||
ListOfKeyValuesDelimitedByBlankLinesToListOfMaps mapConverter, MapToDriveInfo mapToDrive) {
|
||||
this.returnStringIf200 = returnStringIf200;
|
||||
this.mapConverter = mapConverter;
|
||||
this.mapToDrive = mapToDrive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<DriveInfo> apply(HttpResponse response) {
|
||||
String text = returnStringIf200.apply(response);
|
||||
if (text == null || text.trim().equals(""))
|
||||
return ImmutableSet.<DriveInfo> of();
|
||||
return ImmutableSet.copyOf(Iterables.transform(mapConverter.apply(text), mapToDrive));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudsigma.functions;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.cloudsigma.domain.DriveInfo;
|
||||
import org.jclouds.cloudsigma.domain.DriveType;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Splitter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class MapToDriveInfo implements Function<Map<String, String>, DriveInfo> {
|
||||
private final org.jclouds.elasticstack.functions.MapToDriveInfo mapToDriveInfo;
|
||||
|
||||
@Inject
|
||||
public MapToDriveInfo(org.jclouds.elasticstack.functions.MapToDriveInfo mapToDriveInfo) {
|
||||
this.mapToDriveInfo = mapToDriveInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DriveInfo apply(Map<String, String> from) {
|
||||
if (from.size() == 0)
|
||||
return null;
|
||||
DriveInfo.Builder builder = DriveInfo.Builder.fromDriveInfo(mapToDriveInfo.apply(from));
|
||||
if (from.containsKey("use"))
|
||||
builder.tags(Splitter.on(',').split(from.get("use")));
|
||||
if (from.containsKey("bits"))
|
||||
builder.bits(new Integer(from.get("bits")));
|
||||
if (from.containsKey("url"))
|
||||
builder.url(URI.create(from.get("url")));
|
||||
builder.encryptionKey(from.get("encryption:key"));
|
||||
builder.description(from.get("description"));
|
||||
builder.installNotes(from.get("install_notes"));
|
||||
builder.os(from.get("os"));
|
||||
if (from.containsKey("drive_type"))
|
||||
builder.driveType(Splitter.on(',').split(from.get("drive_type")));
|
||||
if (from.containsKey("autoexpanding"))
|
||||
builder.autoexpanding(new Boolean(from.get("autoexpanding")));
|
||||
if (from.containsKey("free"))
|
||||
builder.free(new Boolean(from.get("free")));
|
||||
if (from.containsKey("type"))
|
||||
builder.type(DriveType.fromValue(from.get("type")));
|
||||
return builder.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.elasticstack.binders.BindCreateDriveRequestToPlainTextString;
|
||||
import org.jclouds.elasticstack.binders.BindDriveDataToPlainTextString;
|
||||
import org.jclouds.elasticstack.domain.CreateDriveRequest;
|
||||
import org.jclouds.elasticstack.domain.DriveData;
|
||||
import org.jclouds.elasticstack.domain.DriveInfo;
|
||||
import org.jclouds.elasticstack.functions.KeyValuesDelimitedByBlankLinesToDriveInfo;
|
||||
import org.jclouds.elasticstack.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet;
|
||||
import org.jclouds.elasticstack.functions.SplitNewlines;
|
||||
import org.jclouds.http.filters.BasicAuthentication;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to elasticstack via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
* @see ElasticStackClient
|
||||
* @see <a href="TODO: insert URL of provider documentation" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@RequestFilters(BasicAuthentication.class)
|
||||
@Consumes(MediaType.TEXT_PLAIN)
|
||||
public interface CommonElasticStackAsyncClient {
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#listDrives()
|
||||
*/
|
||||
@GET
|
||||
@Path("/drives/list")
|
||||
@ResponseParser(SplitNewlines.class)
|
||||
ListenableFuture<Set<String>> listDrives();
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#listDriveInfo()
|
||||
*/
|
||||
@GET
|
||||
@Path("/drives/info")
|
||||
@ResponseParser(ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet.class)
|
||||
ListenableFuture<Set<? extends DriveInfo>> listDriveInfo();
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#getDriveInfo
|
||||
*/
|
||||
@GET
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
@ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class)
|
||||
@Path("/drives/{uuid}/info")
|
||||
ListenableFuture<? extends DriveInfo> getDriveInfo(@PathParam("uuid") String uuid);
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#createDrive
|
||||
*/
|
||||
@POST
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
@ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class)
|
||||
@Path("/drives/create")
|
||||
ListenableFuture<? extends DriveInfo> createDrive(
|
||||
@BinderParam(BindCreateDriveRequestToPlainTextString.class) CreateDriveRequest createDrive);
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#setDriveData
|
||||
*/
|
||||
@POST
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
@ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class)
|
||||
@Path("/drives/{uuid}/set")
|
||||
ListenableFuture<? extends DriveInfo> setDriveData(@PathParam("uuid") String uuid,
|
||||
@BinderParam(BindDriveDataToPlainTextString.class) DriveData createDrive);
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#destroyDrive
|
||||
*/
|
||||
@POST
|
||||
@Path("/drives/{uuid}/destroy")
|
||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||
ListenableFuture<Void> destroyDrive(@PathParam("uuid") String uuid);
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.elasticstack.domain.CreateDriveRequest;
|
||||
import org.jclouds.elasticstack.domain.DriveData;
|
||||
import org.jclouds.elasticstack.domain.DriveInfo;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to elasticstack.
|
||||
* <p/>
|
||||
*
|
||||
* @see ElasticStackAsyncClient
|
||||
* @see <a href="TODO: insert URL of elasticstack documentation" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
|
||||
public interface CommonElasticStackClient {
|
||||
/**
|
||||
* list of drive uuids in your account
|
||||
*
|
||||
* @return or empty set if no drives are found
|
||||
*/
|
||||
Set<String> listDrives();
|
||||
|
||||
/**
|
||||
* Get all drives info
|
||||
*
|
||||
* @return or empty set if no drives are found
|
||||
*/
|
||||
Set<? extends DriveInfo> listDriveInfo();
|
||||
|
||||
/**
|
||||
* @param uuid
|
||||
* what to get
|
||||
* @return null, if not found
|
||||
*/
|
||||
DriveInfo getDriveInfo(String uuid);
|
||||
|
||||
/**
|
||||
* create a new drive
|
||||
*
|
||||
* @param createDrive
|
||||
* required parameters: name, size
|
||||
* @return newly created drive
|
||||
*/
|
||||
DriveInfo createDrive(CreateDriveRequest createDrive);
|
||||
|
||||
/**
|
||||
* set extra drive data
|
||||
*
|
||||
* @param uuid
|
||||
* what drive to change
|
||||
* @param driveData
|
||||
* what values to change
|
||||
* @return new data
|
||||
*/
|
||||
DriveInfo setDriveData(String uuid, DriveData driveData);
|
||||
|
||||
/**
|
||||
* Destroy a drive
|
||||
*
|
||||
* @param uuid
|
||||
* what to delete
|
||||
*/
|
||||
void destroyDrive(String uuid);
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.elasticstack.binders.BindReadDriveOptionsToPath;
|
||||
import org.jclouds.elasticstack.domain.ImageConversionType;
|
||||
import org.jclouds.elasticstack.functions.ReturnPayload;
|
||||
import org.jclouds.elasticstack.options.ReadDriveOptions;
|
||||
import org.jclouds.http.filters.BasicAuthentication;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to elasticstack via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
* @see ElasticStackClient
|
||||
* @see <a href="TODO: insert URL of provider documentation" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@RequestFilters(BasicAuthentication.class)
|
||||
@Consumes(MediaType.TEXT_PLAIN)
|
||||
public interface ElasticStackAsyncClient extends CommonElasticStackAsyncClient {
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#imageDrive(String,String)
|
||||
*/
|
||||
@POST
|
||||
@Path("/drives/{destination}/image/{source}")
|
||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||
ListenableFuture<Void> imageDrive(@PathParam("source") String source, @PathParam("destination") String destination);
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#imageDrive(String,String,ImageConversionType)
|
||||
*/
|
||||
@POST
|
||||
@Path("/drives/{destination}/image/{source}/{conversion}")
|
||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||
ListenableFuture<Void> imageDrive(@PathParam("source") String source, @PathParam("destination") String destination,
|
||||
@PathParam("conversion") ImageConversionType conversionType);
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#readDrive(String)
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
|
||||
@Path("/drives/{uuid}/read")
|
||||
@ResponseParser(ReturnPayload.class)
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<Payload> readDrive(@PathParam("uuid") String uuid);
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#readDrive(String,ReadDriveOptions)
|
||||
*/
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
|
||||
@Path("/drives/{uuid}/read")
|
||||
@ResponseParser(ReturnPayload.class)
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<Payload> readDrive(@PathParam("uuid") String uuid,
|
||||
@BinderParam(BindReadDriveOptionsToPath.class) ReadDriveOptions options);
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#writeDrive(String, Payload)
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||
@Path("/drives/{uuid}/write")
|
||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||
ListenableFuture<Void> writeDrive(@PathParam("uuid") String uuid, Payload content);
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#writeDrive(String, Payload, long)
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||
@Path("/drives/{uuid}/write/{offset}")
|
||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||
ListenableFuture<Void> writeDrive(@PathParam("uuid") String uuid, Payload content, @PathParam("offset") long offset);
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.elasticstack.domain.ImageConversionType;
|
||||
import org.jclouds.elasticstack.options.ReadDriveOptions;
|
||||
import org.jclouds.io.Payload;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to elasticstack.
|
||||
* <p/>
|
||||
*
|
||||
* @see ElasticStackAsyncClient
|
||||
* @see <a href="TODO: insert URL of elasticstack documentation" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
|
||||
public interface ElasticStackClient extends CommonElasticStackClient {
|
||||
|
||||
/**
|
||||
* Image a drive from another drive. The actual imaging process is asynchronous, with progress
|
||||
* reported via drive info.
|
||||
*
|
||||
* @param source
|
||||
* drive to copy from
|
||||
* @param destination
|
||||
* drive to copy to
|
||||
*/
|
||||
void imageDrive(String source, String destination);
|
||||
|
||||
/**
|
||||
* @see #imageDrive(String, String)
|
||||
* @param conversionType
|
||||
* Supports 'gzip' or 'gunzip' conversions.
|
||||
*/
|
||||
void imageDrive(String source, String destination, ImageConversionType conversionType);
|
||||
|
||||
/**
|
||||
* Read binary data from a drive
|
||||
*
|
||||
* @param uuid
|
||||
* drive to read
|
||||
* @return binary content of the drive.
|
||||
*/
|
||||
Payload readDrive(String uuid);
|
||||
|
||||
/**
|
||||
* @see #readDrive(String)
|
||||
* @param options
|
||||
* controls offset and size of the request
|
||||
*/
|
||||
Payload readDrive(String uuid, ReadDriveOptions options);
|
||||
|
||||
/**
|
||||
* Write binary data to a drive
|
||||
*
|
||||
* @param uuid
|
||||
* drive to write
|
||||
* @param content
|
||||
* what to write.
|
||||
* <ul>
|
||||
* <li>Binary data (Content-Type: application/octet-stream)</li>
|
||||
* <li>Supports raw data or Content-Encoding: gzip</li>
|
||||
* <li>Does not support Transfer-Encoding: chunked</li>
|
||||
* </ul>
|
||||
*/
|
||||
void writeDrive(String uuid, Payload content);
|
||||
|
||||
/**
|
||||
* @see ElasticStackClient#writeDrive(String, Payload)
|
||||
* @param offset
|
||||
* the byte offset in the target drive at which to start writing, not an offset in the
|
||||
* input stream.
|
||||
*/
|
||||
void writeDrive(String uuid, Payload content, long offset);
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.elasticstack.config.ElasticStackRestClientModule;
|
||||
import org.jclouds.rest.RestContextBuilder;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ElasticStackContextBuilder extends
|
||||
RestContextBuilder<ElasticStackClient, ElasticStackAsyncClient> {
|
||||
|
||||
public ElasticStackContextBuilder(Properties props) {
|
||||
super(ElasticStackClient.class, ElasticStackAsyncClient.class, props);
|
||||
}
|
||||
|
||||
protected void addClientModule(List<Module> modules) {
|
||||
modules.add(new ElasticStackRestClientModule());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack;
|
||||
|
||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.PropertiesBuilder;
|
||||
|
||||
/**
|
||||
* Builds properties used in elasticstack Clients
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ElasticStackPropertiesBuilder extends PropertiesBuilder {
|
||||
@Override
|
||||
protected Properties defaultProperties() {
|
||||
Properties properties = super.defaultProperties();
|
||||
properties.setProperty(PROPERTY_API_VERSION, "1.0");
|
||||
return properties;
|
||||
}
|
||||
|
||||
public ElasticStackPropertiesBuilder(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.elasticstack.domain.CreateDriveRequest;
|
||||
import org.jclouds.elasticstack.functions.ListOfMapsToListOfKeyValuesDelimitedByBlankLines;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.Binder;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class BindCreateDriveRequestToPlainTextString implements Binder {
|
||||
private final Function<CreateDriveRequest, Map<String, String>> createDriveRequestToMap;
|
||||
private final ListOfMapsToListOfKeyValuesDelimitedByBlankLines listOfMapsToListOfKeyValuesDelimitedByBlankLines;
|
||||
|
||||
@Inject
|
||||
public BindCreateDriveRequestToPlainTextString(Function<CreateDriveRequest, Map<String, String>> createDriveRequestToMap,
|
||||
ListOfMapsToListOfKeyValuesDelimitedByBlankLines listOfMapsToListOfKeyValuesDelimitedByBlankLines) {
|
||||
this.createDriveRequestToMap = createDriveRequestToMap;
|
||||
this.listOfMapsToListOfKeyValuesDelimitedByBlankLines = listOfMapsToListOfKeyValuesDelimitedByBlankLines;
|
||||
}
|
||||
|
||||
public void bindToRequest(HttpRequest request, Object payload) {
|
||||
checkArgument(payload instanceof CreateDriveRequest, "this binder is only valid for CreateDriveRequest!");
|
||||
CreateDriveRequest create = CreateDriveRequest.class.cast(payload);
|
||||
Map<String, String> map = createDriveRequestToMap.apply(create);
|
||||
request.setPayload(listOfMapsToListOfKeyValuesDelimitedByBlankLines.apply(ImmutableSet.of(map)));
|
||||
request.getPayload().getContentMetadata().setContentType(MediaType.TEXT_PLAIN);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.elasticstack.domain.DriveData;
|
||||
import org.jclouds.elasticstack.functions.ListOfMapsToListOfKeyValuesDelimitedByBlankLines;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.Binder;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class BindDriveDataToPlainTextString implements Binder {
|
||||
private final Function<DriveData, Map<String, String>> createDriveRequestToMap;
|
||||
private final ListOfMapsToListOfKeyValuesDelimitedByBlankLines listOfMapsToListOfKeyValuesDelimitedByBlankLines;
|
||||
|
||||
@Inject
|
||||
public BindDriveDataToPlainTextString(Function<DriveData, Map<String, String>> createDriveRequestToMap,
|
||||
ListOfMapsToListOfKeyValuesDelimitedByBlankLines listOfMapsToListOfKeyValuesDelimitedByBlankLines) {
|
||||
this.createDriveRequestToMap = createDriveRequestToMap;
|
||||
this.listOfMapsToListOfKeyValuesDelimitedByBlankLines = listOfMapsToListOfKeyValuesDelimitedByBlankLines;
|
||||
}
|
||||
|
||||
public void bindToRequest(HttpRequest request, Object payload) {
|
||||
checkArgument(payload instanceof DriveData, "this binder is only valid for DriveData!");
|
||||
DriveData create = DriveData.class.cast(payload);
|
||||
Map<String, String> map = createDriveRequestToMap.apply(create);
|
||||
request.setPayload(listOfMapsToListOfKeyValuesDelimitedByBlankLines.apply(ImmutableSet.of(map)));
|
||||
request.getPayload().getContentMetadata().setContentType(MediaType.TEXT_PLAIN);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
import org.jclouds.elasticstack.options.ReadDriveOptions;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.Binder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class BindReadDriveOptionsToPath implements Binder {
|
||||
private final Provider<UriBuilder> uriBuilderProvider;
|
||||
|
||||
@Inject
|
||||
public BindReadDriveOptionsToPath(Provider<UriBuilder> uriBuilderProvider) {
|
||||
this.uriBuilderProvider = uriBuilderProvider;
|
||||
}
|
||||
|
||||
public void bindToRequest(HttpRequest request, Object payload) {
|
||||
checkArgument(payload instanceof ReadDriveOptions, "this binder is only valid for ReadDriveOptions!");
|
||||
ReadDriveOptions options = ReadDriveOptions.class.cast(payload);
|
||||
if (options.getOffset() != null || options.getSize() != null){
|
||||
UriBuilder builder = uriBuilderProvider.get().uri(request.getEndpoint());
|
||||
if (options.getOffset() != null)
|
||||
builder.path("/"+options.getOffset());
|
||||
if (options.getSize() != null)
|
||||
builder.path("/"+options.getSize());
|
||||
request.setEndpoint(builder.build());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.config;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.elasticstack.ElasticStackAsyncClient;
|
||||
import org.jclouds.elasticstack.ElasticStackClient;
|
||||
import org.jclouds.elasticstack.domain.CreateDriveRequest;
|
||||
import org.jclouds.elasticstack.domain.DriveData;
|
||||
import org.jclouds.elasticstack.functions.CreateDriveRequestToMap;
|
||||
import org.jclouds.elasticstack.functions.DriveDataToMap;
|
||||
import org.jclouds.elasticstack.handlers.ElasticStackErrorHandler;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.annotation.Redirection;
|
||||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Configures the elasticstack connection.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@RequiresHttp
|
||||
@ConfiguresRestClient
|
||||
public class ElasticStackRestClientModule extends RestClientModule<ElasticStackClient, ElasticStackAsyncClient> {
|
||||
|
||||
public ElasticStackRestClientModule() {
|
||||
super(ElasticStackClient.class, ElasticStackAsyncClient.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
bind(new TypeLiteral<Function<CreateDriveRequest, Map<String, String>>>() {
|
||||
}).to(CreateDriveRequestToMap.class);
|
||||
bind(new TypeLiteral<Function<DriveData, Map<String, String>>>() {
|
||||
}).to(DriveDataToMap.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ElasticStackErrorHandler.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ElasticStackErrorHandler.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ElasticStackErrorHandler.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindRetryHandlers() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BlockDevice extends Device {
|
||||
|
||||
private final char index;
|
||||
|
||||
public BlockDevice(String driveUuid, MediaType mediaType, char index) {
|
||||
super(driveUuid, mediaType);
|
||||
checkArgument(index >= 0 && index < 8, "index must be between 0 and 7");
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + index;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
BlockDevice other = (BlockDevice) obj;
|
||||
if (index != other.index)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return String.format("block:%d", index);
|
||||
}
|
||||
|
||||
public char getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[id=" + getId() + ", driveUuid=" + driveUuid + ", mediaType=" + mediaType + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* either 'exclusive' (the default) or 'shared' to allow multiple servers to access a drive
|
||||
* simultaneously
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum ClaimType {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
EXCLUSIVE,
|
||||
/**
|
||||
* allow multiple servers to access a drive simultaneously
|
||||
*/
|
||||
SHARED, UNRECOGNIZED;
|
||||
|
||||
public String value() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value();
|
||||
}
|
||||
|
||||
public static ClaimType fromValue(String claim) {
|
||||
try {
|
||||
return valueOf(checkNotNull(claim, "claim").toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.elasticstack.domain.internal.BaseDrive;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class CreateDriveRequest extends BaseDrive {
|
||||
public static class Builder extends BaseDrive.Builder {
|
||||
|
||||
private Set<String> avoid = ImmutableSet.of();
|
||||
|
||||
@Nullable
|
||||
private String encryptionCipher;
|
||||
|
||||
public Builder avoid(Iterable<String> avoid) {
|
||||
this.avoid = ImmutableSet.copyOf(checkNotNull(avoid, "avoid"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder claimType(ClaimType claimType) {
|
||||
return Builder.class.cast(super.claimType(claimType));
|
||||
}
|
||||
|
||||
public Builder encryptionCipher(String encryptionCipher) {
|
||||
this.encryptionCipher = encryptionCipher;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder name(String name) {
|
||||
return Builder.class.cast(super.name(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder readers(Iterable<String> readers) {
|
||||
return Builder.class.cast(super.readers(readers));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder size(long size) {
|
||||
return Builder.class.cast(super.size(size));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder tags(Iterable<String> tags) {
|
||||
return Builder.class.cast(super.tags(tags));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder userMetadata(Map<String, String> userMetadata) {
|
||||
return Builder.class.cast(super.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
public CreateDriveRequest build() {
|
||||
return new CreateDriveRequest(name, size, claimType, readers, tags, userMetadata, encryptionCipher, avoid);
|
||||
}
|
||||
}
|
||||
|
||||
private final Set<String> avoid;
|
||||
@Nullable
|
||||
private final String encryptionCipher;
|
||||
|
||||
public CreateDriveRequest(String name, long size, @Nullable ClaimType claimType, Iterable<String> readers,
|
||||
Iterable<String> tags, Map<String, String> userMetadata, @Nullable String encryptionCipher,
|
||||
Iterable<String> avoid) {
|
||||
super(null, name, size, claimType, readers, tags, userMetadata);
|
||||
this.encryptionCipher = encryptionCipher;
|
||||
this.avoid = ImmutableSet.copyOf(checkNotNull(avoid, "avoid"));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return list of existing drives to ensure this new drive is created on physical different
|
||||
* hardware than those existing drives
|
||||
*/
|
||||
public Set<String> getAvoid() {
|
||||
return avoid;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return either 'none' or 'aes-xts-plain' (the default)
|
||||
*/
|
||||
@Nullable
|
||||
public String getEncryptionCipher() {
|
||||
return encryptionCipher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((avoid == null) ? 0 : avoid.hashCode());
|
||||
result = prime * result + ((encryptionCipher == null) ? 0 : encryptionCipher.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
CreateDriveRequest other = (CreateDriveRequest) obj;
|
||||
if (avoid == null) {
|
||||
if (other.avoid != null)
|
||||
return false;
|
||||
} else if (!avoid.equals(other.avoid))
|
||||
return false;
|
||||
if (encryptionCipher == null) {
|
||||
if (other.encryptionCipher != null)
|
||||
return false;
|
||||
} else if (!encryptionCipher.equals(other.encryptionCipher))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[name=" + name + ", size=" + size + ", claimType=" + claimType + ", readers=" + readers + ", tags="
|
||||
+ tags + ", userMetadata=" + userMetadata + ", avoid=" + avoid + ", encryptionCipher=" + encryptionCipher
|
||||
+ "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public abstract class Device {
|
||||
protected final String driveUuid;
|
||||
protected final MediaType mediaType;
|
||||
|
||||
public Device(String driveUuid, MediaType mediaType) {
|
||||
this.driveUuid = checkNotNull(driveUuid, "driveUuid");
|
||||
this.mediaType = checkNotNull(mediaType, "mediaType");
|
||||
}
|
||||
|
||||
/**
|
||||
* id generated based on the device bus, unit, and/or index numbers;
|
||||
*/
|
||||
public abstract String getId();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Drive UUID to connect as specified device.
|
||||
*/
|
||||
public String getDriveUuid() {
|
||||
return driveUuid;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return set to 'cdrom' to simulate a cdrom, set to 'disk' or leave unset to simulate a hard
|
||||
* disk.
|
||||
*/
|
||||
public MediaType getMediaType() {
|
||||
return mediaType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((driveUuid == null) ? 0 : driveUuid.hashCode());
|
||||
result = prime * result + ((mediaType == null) ? 0 : mediaType.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Device other = (Device) obj;
|
||||
if (driveUuid == null) {
|
||||
if (other.driveUuid != null)
|
||||
return false;
|
||||
} else if (!driveUuid.equals(other.driveUuid))
|
||||
return false;
|
||||
if (mediaType != other.mediaType)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[driveUuid=" + driveUuid + ", mediaType=" + mediaType + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.elasticstack.domain.internal.BaseDrive;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class DriveData extends BaseDrive {
|
||||
public static class Builder extends BaseDrive.Builder {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder claimType(ClaimType claimType) {
|
||||
return Builder.class.cast(super.claimType(claimType));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder name(String name) {
|
||||
return Builder.class.cast(super.name(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder readers(Iterable<String> readers) {
|
||||
return Builder.class.cast(super.readers(readers));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder size(long size) {
|
||||
return Builder.class.cast(super.size(size));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder tags(Iterable<String> tags) {
|
||||
return Builder.class.cast(super.tags(tags));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder userMetadata(Map<String, String> userMetadata) {
|
||||
return Builder.class.cast(super.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
public DriveData build() {
|
||||
return new DriveData(uuid, name, size, claimType, readers, tags, userMetadata);
|
||||
}
|
||||
}
|
||||
|
||||
public DriveData(@Nullable String uuid, String name, long size, @Nullable ClaimType claimType, Iterable<String> readers,
|
||||
Iterable<String> tags, Map<String, String> userMetadata) {
|
||||
super(uuid, name, size, claimType, readers, tags, userMetadata);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,342 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.elasticstack.domain.internal.BaseDrive;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class DriveInfo extends BaseDrive {
|
||||
public static class Builder extends BaseDrive.Builder {
|
||||
|
||||
protected DriveStatus status;
|
||||
protected String user;
|
||||
protected Set<String> claimed = ImmutableSet.of();
|
||||
@Nullable
|
||||
protected String encryptionCipher;
|
||||
@Nullable
|
||||
protected String imaging;
|
||||
protected long readBytes;
|
||||
protected long readRequests;
|
||||
protected long writeBytes;
|
||||
protected long writeRequests;
|
||||
|
||||
public Builder status(DriveStatus status) {
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder user(String user) {
|
||||
this.user = user;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder claimed(Iterable<String> claimed) {
|
||||
this.claimed = ImmutableSet.copyOf(checkNotNull(claimed, "claimed"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder imaging(String imaging) {
|
||||
this.imaging = imaging;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder readBytes(long readBytes) {
|
||||
this.readBytes = readBytes;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder readRequests(long readRequests) {
|
||||
this.readRequests = readRequests;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder writeBytes(long writeBytes) {
|
||||
this.writeBytes = writeBytes;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder writeRequests(long writeRequests) {
|
||||
this.writeRequests = writeRequests;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder encryptionCipher(String encryptionCipher) {
|
||||
this.encryptionCipher = encryptionCipher;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder claimType(ClaimType claimType) {
|
||||
return Builder.class.cast(super.claimType(claimType));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder readers(Iterable<String> readers) {
|
||||
return Builder.class.cast(super.readers(readers));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder size(long size) {
|
||||
return Builder.class.cast(super.size(size));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder uuid(String uuid) {
|
||||
return Builder.class.cast(super.uuid(uuid));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder name(String name) {
|
||||
return Builder.class.cast(super.name(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder tags(Iterable<String> tags) {
|
||||
return Builder.class.cast(super.tags(tags));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder userMetadata(Map<String, String> userMetadata) {
|
||||
return Builder.class.cast(super.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
public static Builder fromDriveInfo(DriveInfo driveInfo) {
|
||||
return new Builder().uuid(driveInfo.getUuid()).name(driveInfo.getName()).size(driveInfo.getSize())
|
||||
.claimType(driveInfo.getClaimType()).readers(driveInfo.getReaders()).tags(driveInfo.getTags())
|
||||
.userMetadata(driveInfo.getUserMetadata()).status(driveInfo.getStatus()).user(driveInfo.getUser())
|
||||
.claimed(driveInfo.getClaimed()).encryptionCipher(driveInfo.getEncryptionCipher())
|
||||
.imaging(driveInfo.getImaging()).readBytes(driveInfo.getReadBytes())
|
||||
.readRequests(driveInfo.getReadRequests()).writeBytes(driveInfo.getWriteBytes())
|
||||
.writeRequests(driveInfo.getWriteRequests());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public DriveInfo build() {
|
||||
return new DriveInfo(uuid, name, size, claimType, readers, tags, userMetadata, status, user, claimed,
|
||||
encryptionCipher, imaging, readBytes, readRequests, writeBytes, writeRequests);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected final DriveStatus status;
|
||||
protected final String user;
|
||||
protected final Set<String> claimed;
|
||||
@Nullable
|
||||
protected final String encryptionCipher;
|
||||
@Nullable
|
||||
protected final String imaging;
|
||||
protected final long readBytes;
|
||||
protected final long readRequests;
|
||||
protected final long writeBytes;
|
||||
protected final long writeRequests;
|
||||
|
||||
public DriveInfo(String uuid, String name, long size, ClaimType claimType, Iterable<String> readers,
|
||||
Iterable<String> tags, Map<String, String> userMetadata, DriveStatus status, String user, Set<String> claimed,
|
||||
String encryptionCipher, String imaging, long readBytes, long readRequests, long writeBytes, long writeRequests) {
|
||||
super(uuid, name, size, claimType, readers, tags, userMetadata);
|
||||
this.status = status;
|
||||
this.user = user;
|
||||
this.claimed = ImmutableSet.copyOf(claimed);
|
||||
this.encryptionCipher = encryptionCipher;
|
||||
this.imaging = imaging;
|
||||
this.readBytes = readBytes;
|
||||
this.readRequests = readRequests;
|
||||
this.writeBytes = writeBytes;
|
||||
this.writeRequests = writeRequests;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return current status of the drive
|
||||
*/
|
||||
public DriveStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return owner of the drive
|
||||
*/
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return if drive is in use by a server, values are the server uuids
|
||||
*/
|
||||
public Set<String> getClaimed() {
|
||||
return claimed;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return either 'none' or 'aes-xts-plain' (the default)
|
||||
*/
|
||||
@Nullable
|
||||
public String getEncryptionCipher() {
|
||||
return encryptionCipher;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return percentage completed of drive imaging if this is underway, or 'queued' if waiting for
|
||||
* another imaging operation to complete first
|
||||
*/
|
||||
public String getImaging() {
|
||||
return imaging;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Cumulative i/o byte/request count for each drive
|
||||
*/
|
||||
public long getReadBytes() {
|
||||
return readBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Cumulative i/o byte/request count for each drive
|
||||
*/
|
||||
public long getReadRequests() {
|
||||
return readRequests;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Cumulative i/o byte/request count for each drive
|
||||
*/
|
||||
public long getWriteBytes() {
|
||||
return writeBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Cumulative i/o byte/request count for each drive
|
||||
*/
|
||||
public long getWriteRequests() {
|
||||
return writeRequests;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((claimed == null) ? 0 : claimed.hashCode());
|
||||
result = prime * result + ((encryptionCipher == null) ? 0 : encryptionCipher.hashCode());
|
||||
result = prime * result + ((imaging == null) ? 0 : imaging.hashCode());
|
||||
result = prime * result + (int) (readBytes ^ (readBytes >>> 32));
|
||||
result = prime * result + (int) (readRequests ^ (readRequests >>> 32));
|
||||
result = prime * result + ((status == null) ? 0 : status.hashCode());
|
||||
result = prime * result + ((user == null) ? 0 : user.hashCode());
|
||||
result = prime * result + (int) (writeBytes ^ (writeBytes >>> 32));
|
||||
result = prime * result + (int) (writeRequests ^ (writeRequests >>> 32));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
DriveInfo other = (DriveInfo) obj;
|
||||
if (claimed == null) {
|
||||
if (other.claimed != null)
|
||||
return false;
|
||||
} else if (!claimed.equals(other.claimed))
|
||||
return false;
|
||||
if (encryptionCipher == null) {
|
||||
if (other.encryptionCipher != null)
|
||||
return false;
|
||||
} else if (!encryptionCipher.equals(other.encryptionCipher))
|
||||
return false;
|
||||
if (imaging == null) {
|
||||
if (other.imaging != null)
|
||||
return false;
|
||||
} else if (!imaging.equals(other.imaging))
|
||||
return false;
|
||||
if (readBytes != other.readBytes)
|
||||
return false;
|
||||
if (readRequests != other.readRequests)
|
||||
return false;
|
||||
if (status != other.status)
|
||||
return false;
|
||||
if (user == null) {
|
||||
if (other.user != null)
|
||||
return false;
|
||||
} else if (!user.equals(other.user))
|
||||
return false;
|
||||
if (writeBytes != other.writeBytes)
|
||||
return false;
|
||||
if (writeRequests != other.writeRequests)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[size=" + size + ", claimType=" + claimType + ", readers=" + readers + ", uuid=" + uuid + ", name="
|
||||
+ name + ", tags=" + tags + ", userMetadata=" + userMetadata + ", status=" + status + ", user=" + user
|
||||
+ ", claimed=" + claimed + ", encryptionCipher=" + encryptionCipher + ", imaging=" + imaging
|
||||
+ ", readBytes=" + readBytes + ", readRequests=" + readRequests + ", writeBytes=" + writeBytes
|
||||
+ ", writeRequests=" + writeRequests + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum DriveStatus {
|
||||
ACTIVE, INACTIVE, COPYING, IMAGING, UNRECOGNIZED;
|
||||
|
||||
public String value() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value();
|
||||
}
|
||||
|
||||
public static DriveStatus fromValue(String status) {
|
||||
try {
|
||||
return valueOf(checkNotNull(status, "status").toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class IDEDevice extends Device {
|
||||
|
||||
private final char bus;
|
||||
private final char unit;
|
||||
|
||||
public IDEDevice(String driveUuid, MediaType mediaType, char bus, char unit) {
|
||||
super(driveUuid, mediaType);
|
||||
checkArgument(bus == 0 || bus == 1, "bus must be 0 or 1");
|
||||
checkArgument(unit == 0 || unit == 1, "unit must be 0 or 1");
|
||||
this.bus = bus;
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + bus;
|
||||
result = prime * result + unit;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
IDEDevice other = (IDEDevice) obj;
|
||||
if (bus != other.bus)
|
||||
return false;
|
||||
if (unit != other.unit)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return String.format("ide:%d:%d", bus, unit);
|
||||
}
|
||||
|
||||
public char getBus() {
|
||||
return bus;
|
||||
}
|
||||
|
||||
public char getUnit() {
|
||||
return unit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[id=" + getId() + ", driveUuid=" + driveUuid + ", mediaType=" + mediaType + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum ImageConversionType {
|
||||
GZIP, GUNZIP, UNRECOGNIZED;
|
||||
|
||||
public String value() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value();
|
||||
}
|
||||
|
||||
public static ImageConversionType fromValue(String type) {
|
||||
try {
|
||||
return valueOf(checkNotNull(type, "type").toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class Item {
|
||||
public static class Builder {
|
||||
protected String uuid;
|
||||
protected String name;
|
||||
protected Set<String> tags = ImmutableSet.of();
|
||||
protected Map<String, String> userMetadata = ImmutableMap.of();
|
||||
|
||||
public Builder uuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder tags(Iterable<String> tags) {
|
||||
this.tags = ImmutableSet.copyOf(checkNotNull(tags, "tags"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder userMetadata(Map<String, String> userMetadata) {
|
||||
this.userMetadata = ImmutableMap.copyOf(checkNotNull(userMetadata, "userMetadata"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Item build() {
|
||||
return new Item(uuid, name, tags, userMetadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((tags == null) ? 0 : tags.hashCode());
|
||||
result = prime * result + ((userMetadata == null) ? 0 : userMetadata.hashCode());
|
||||
result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Builder other = (Builder) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (tags == null) {
|
||||
if (other.tags != null)
|
||||
return false;
|
||||
} else if (!tags.equals(other.tags))
|
||||
return false;
|
||||
if (userMetadata == null) {
|
||||
if (other.userMetadata != null)
|
||||
return false;
|
||||
} else if (!userMetadata.equals(other.userMetadata))
|
||||
return false;
|
||||
if (uuid == null) {
|
||||
if (other.uuid != null)
|
||||
return false;
|
||||
} else if (!uuid.equals(other.uuid))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected final String uuid;
|
||||
protected final String name;
|
||||
protected final Set<String> tags;
|
||||
protected final Map<String, String> userMetadata;
|
||||
|
||||
public Item(@Nullable String uuid, String name, Iterable<String> tags, Map<String, String> userMetadata) {
|
||||
this.uuid = uuid;
|
||||
this.name = checkNotNull(name, "name");
|
||||
this.tags = ImmutableSet.copyOf(checkNotNull(tags, "tags"));
|
||||
this.userMetadata = ImmutableMap.copyOf(checkNotNull(userMetadata, "userMetadata"));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return uuid of the item.
|
||||
*/
|
||||
@Nullable
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return name of the item
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return list of tags
|
||||
*/
|
||||
public Set<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return user-defined KEY VALUE pairs
|
||||
*/
|
||||
public Map<String, String> getUserMetadata() {
|
||||
return userMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((tags == null) ? 0 : tags.hashCode());
|
||||
result = prime * result + ((userMetadata == null) ? 0 : userMetadata.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Item other = (Item) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (tags == null) {
|
||||
if (other.tags != null)
|
||||
return false;
|
||||
} else if (!tags.equals(other.tags))
|
||||
return false;
|
||||
if (userMetadata == null) {
|
||||
if (other.userMetadata != null)
|
||||
return false;
|
||||
} else if (!userMetadata.equals(other.userMetadata))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[uuid=" + uuid + ", name=" + name + ", tags=" + tags + ", userMetadata=" + userMetadata + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Media type - set to 'cdrom' to simulate a cdrom, set to 'disk' or leave unset to simulate a hard
|
||||
* disk.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum MediaType {
|
||||
DISK, CDROM, UNRECOGNIZED;
|
||||
|
||||
public String value() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value();
|
||||
}
|
||||
|
||||
public static MediaType fromValue(String type) {
|
||||
try {
|
||||
return valueOf(checkNotNull(type, "type").toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum Model {
|
||||
E1000, RTl8139, VIRTIO, UNRECOGNIZED;
|
||||
|
||||
public String value() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value();
|
||||
}
|
||||
|
||||
public static Model fromValue(String model) {
|
||||
try {
|
||||
return valueOf(checkNotNull(model, "model").toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class NIC {
|
||||
private final String dhcp;
|
||||
private final Model model;
|
||||
private final String vlan;
|
||||
private final String mac;
|
||||
|
||||
public NIC(@Nullable String dhcp, Model model, @Nullable String vlan, @Nullable String mac) {
|
||||
this.dhcp = dhcp;
|
||||
this.model = checkNotNull(model, "model");
|
||||
this.vlan = vlan;
|
||||
this.mac = mac;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return The IP address offered by DHCP to network interface 0. If unset, no address is
|
||||
* offered. Set to 'auto' to allocate a temporary IP at boot.
|
||||
*/
|
||||
public String getDhcp() {
|
||||
return dhcp;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Create network interface with given type (use 'e1000' as default value; 'rtl8139' or
|
||||
* 'virtio' are also available).
|
||||
*/
|
||||
public Model getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return The VLAN to which the network interface is attached.
|
||||
*/
|
||||
public String getVlan() {
|
||||
return vlan;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return The MAC address of the network interface. If unset, a randomly generated address is
|
||||
* used. If set, should be unique on the VLAN.
|
||||
*/
|
||||
public String getMac() {
|
||||
return mac;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((dhcp == null) ? 0 : dhcp.hashCode());
|
||||
result = prime * result + ((mac == null) ? 0 : mac.hashCode());
|
||||
result = prime * result + ((model == null) ? 0 : model.hashCode());
|
||||
result = prime * result + ((vlan == null) ? 0 : vlan.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
NIC other = (NIC) obj;
|
||||
if (dhcp == null) {
|
||||
if (other.dhcp != null)
|
||||
return false;
|
||||
} else if (!dhcp.equals(other.dhcp))
|
||||
return false;
|
||||
if (mac == null) {
|
||||
if (other.mac != null)
|
||||
return false;
|
||||
} else if (!mac.equals(other.mac))
|
||||
return false;
|
||||
if (model != other.model)
|
||||
return false;
|
||||
if (vlan == null) {
|
||||
if (other.vlan != null)
|
||||
return false;
|
||||
} else if (!vlan.equals(other.vlan))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[dhcp=" + dhcp + ", model=" + model + ", vlan=" + vlan + ", mac=" + mac + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class SCSIDevice extends Device {
|
||||
|
||||
private final char bus = 0;
|
||||
private final char unit;
|
||||
|
||||
public SCSIDevice(String driveUuid, MediaType mediaType, char unit) {
|
||||
super(driveUuid, mediaType);
|
||||
checkArgument(unit >= 0 && unit < 8, "unit must be between 0 and 7");
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + bus;
|
||||
result = prime * result + unit;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
SCSIDevice other = (SCSIDevice) obj;
|
||||
if (bus != other.bus)
|
||||
return false;
|
||||
if (unit != other.unit)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public char getBus() {
|
||||
return bus;
|
||||
}
|
||||
|
||||
public char getUnit() {
|
||||
return unit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return String.format("scsi:%d:%d", bus, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[id=" + getId() + ", driveUuid=" + driveUuid + ", mediaType=" + mediaType + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,337 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class Server extends Item {
|
||||
//
|
||||
// user UUID
|
||||
// status active|stopped
|
||||
// cpu CPU
|
||||
// smp SMP
|
||||
// mem MEM
|
||||
// bootDeviceIds UUID
|
||||
// description DESCRIPTION
|
||||
// ide:0:0 UUID
|
||||
// ide:0:1 UUID
|
||||
// ide:1:0 UUID
|
||||
// ide:1:1 UUID
|
||||
// nic:0:model NIC_0_MODEL
|
||||
// nic:0:dhcp NIC_0_DHCP
|
||||
// nic:1:model NIC_1_MODEL
|
||||
// nic:1:vlan NIC_1_VLAN
|
||||
// vnc:ip VNC_IP
|
||||
// vnc:password VNC_PASS
|
||||
|
||||
public static class Builder extends Item.Builder {
|
||||
protected int cpu;
|
||||
protected Integer smp;
|
||||
protected int mem;
|
||||
protected boolean persistent;
|
||||
protected Set<? extends Device> devices = ImmutableSet.of();
|
||||
protected Set<String> bootDeviceIds = ImmutableSet.of();
|
||||
protected List<NIC> nics = ImmutableList.of();
|
||||
protected String user;
|
||||
protected VNC vnc;
|
||||
// TODO undocumented
|
||||
protected String description;
|
||||
|
||||
public Builder cpu(int cpu) {
|
||||
this.cpu = cpu;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder smp(Integer smp) {
|
||||
this.smp = smp;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder mem(int mem) {
|
||||
this.mem = mem;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder persistent(boolean persistent) {
|
||||
this.persistent = persistent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder devices(Iterable<? extends Device> devices) {
|
||||
this.devices = ImmutableSet.copyOf(checkNotNull(devices, "devices"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder bootDeviceIds(Iterable<String> bootDeviceIds) {
|
||||
this.bootDeviceIds = ImmutableSet.copyOf(checkNotNull(bootDeviceIds, "bootDeviceIds"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder nics(Iterable<NIC> nics) {
|
||||
this.nics = ImmutableList.copyOf(checkNotNull(nics, "nics"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder user(String user) {
|
||||
this.user = user;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder vnc(VNC vnc) {
|
||||
this.vnc = vnc;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder description(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder uuid(String uuid) {
|
||||
return Builder.class.cast(super.uuid(uuid));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder name(String name) {
|
||||
return Builder.class.cast(super.name(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder tags(Iterable<String> tags) {
|
||||
return Builder.class.cast(super.tags(tags));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder userMetadata(Map<String, String> userMetadata) {
|
||||
return Builder.class.cast(super.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
public Server build() {
|
||||
return new Server(uuid, name, cpu, smp, mem, persistent, devices, tags, bootDeviceIds, userMetadata, nics,
|
||||
user, vnc, description);
|
||||
}
|
||||
}
|
||||
|
||||
protected final int cpu;
|
||||
protected final Integer smp;
|
||||
protected final int mem;
|
||||
protected final boolean persistent;
|
||||
protected final Set<? extends Device> devices;
|
||||
protected final Set<String> bootDeviceIds;
|
||||
@Nullable
|
||||
protected final String user;
|
||||
protected final List<NIC> nics;
|
||||
protected final VNC vnc;
|
||||
@Nullable
|
||||
private final String description;
|
||||
|
||||
public Server(@Nullable String uuid, String name, int cpu, @Nullable Integer smp, int mem, boolean persistent,
|
||||
Iterable<? extends Device> devices, Iterable<String> bootDeviceIds, Iterable<String> tags,
|
||||
Map<String, String> userMetadata, Iterable<NIC> nics, @Nullable String user, VNC vnc, String description) {
|
||||
super(uuid, name, tags, userMetadata);
|
||||
this.cpu = cpu;
|
||||
this.smp = smp;
|
||||
this.mem = mem;
|
||||
this.persistent = persistent;
|
||||
this.devices = ImmutableSet.copyOf(checkNotNull(devices, "devices"));
|
||||
this.bootDeviceIds = ImmutableSet.copyOf(checkNotNull(bootDeviceIds, "bootDeviceIds"));
|
||||
this.nics = ImmutableList.copyOf(checkNotNull(nics, "nics"));
|
||||
this.user = user;
|
||||
this.vnc = checkNotNull(vnc, "vnc");
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return CPU quota in core MHz.
|
||||
*/
|
||||
public int getCpu() {
|
||||
return cpu;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return number of virtual processors or null if calculated based on cpu.
|
||||
*/
|
||||
public Integer getSmp() {
|
||||
return smp;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return virtual memory size in MB.
|
||||
*/
|
||||
public int getMem() {
|
||||
return mem;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return 'true' means that server will revert to a 'stopped' status on server stop or shutdown,
|
||||
* rather than being destroyed automatically.
|
||||
*/
|
||||
public boolean isPersistent() {
|
||||
return persistent;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return set of devices present
|
||||
*/
|
||||
public Set<? extends Device> getDevices() {
|
||||
return devices;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return ids of the devices to boot, e.g. ide:0:0 or ide:1:0
|
||||
* @see Device#getId()
|
||||
*/
|
||||
public Set<String> getBootDeviceIds() {
|
||||
return bootDeviceIds;
|
||||
}
|
||||
|
||||
public List<NIC> getNics() {
|
||||
return nics;
|
||||
}
|
||||
|
||||
// TODO undocumented
|
||||
/**
|
||||
*
|
||||
* @return owner of the server.
|
||||
*/
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public VNC getVnc() {
|
||||
return vnc;
|
||||
}
|
||||
|
||||
// TODO undocumented
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((bootDeviceIds == null) ? 0 : bootDeviceIds.hashCode());
|
||||
result = prime * result + cpu;
|
||||
result = prime * result + ((description == null) ? 0 : description.hashCode());
|
||||
result = prime * result + ((devices == null) ? 0 : devices.hashCode());
|
||||
result = prime * result + mem;
|
||||
result = prime * result + ((nics == null) ? 0 : nics.hashCode());
|
||||
result = prime * result + (persistent ? 1231 : 1237);
|
||||
result = prime * result + ((smp == null) ? 0 : smp.hashCode());
|
||||
result = prime * result + ((user == null) ? 0 : user.hashCode());
|
||||
result = prime * result + ((vnc == null) ? 0 : vnc.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Server other = (Server) obj;
|
||||
if (bootDeviceIds == null) {
|
||||
if (other.bootDeviceIds != null)
|
||||
return false;
|
||||
} else if (!bootDeviceIds.equals(other.bootDeviceIds))
|
||||
return false;
|
||||
if (cpu != other.cpu)
|
||||
return false;
|
||||
if (description == null) {
|
||||
if (other.description != null)
|
||||
return false;
|
||||
} else if (!description.equals(other.description))
|
||||
return false;
|
||||
if (devices == null) {
|
||||
if (other.devices != null)
|
||||
return false;
|
||||
} else if (!devices.equals(other.devices))
|
||||
return false;
|
||||
if (mem != other.mem)
|
||||
return false;
|
||||
if (nics == null) {
|
||||
if (other.nics != null)
|
||||
return false;
|
||||
} else if (!nics.equals(other.nics))
|
||||
return false;
|
||||
if (persistent != other.persistent)
|
||||
return false;
|
||||
if (smp == null) {
|
||||
if (other.smp != null)
|
||||
return false;
|
||||
} else if (!smp.equals(other.smp))
|
||||
return false;
|
||||
if (user == null) {
|
||||
if (other.user != null)
|
||||
return false;
|
||||
} else if (!user.equals(other.user))
|
||||
return false;
|
||||
if (vnc == null) {
|
||||
if (other.vnc != null)
|
||||
return false;
|
||||
} else if (!vnc.equals(other.vnc))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[uuid=" + uuid + ", name=" + name + ", tags=" + tags + ", userMetadata=" + userMetadata + ", cpu=" + cpu
|
||||
+ ", smp=" + smp + ", mem=" + mem + ", persistent=" + persistent + ", devices=" + devices
|
||||
+ ", bootDeviceIds=" + bootDeviceIds + ", user=" + user + ", nics=" + nics + ", vnc=" + vnc
|
||||
+ ", description=" + description + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class VNC {
|
||||
@Nullable
|
||||
private final String ip;
|
||||
@Nullable
|
||||
private final String password;
|
||||
private final boolean tls;
|
||||
|
||||
public VNC(String ip, String password, boolean tls) {
|
||||
this.ip = ip;
|
||||
this.password = password;
|
||||
this.tls = tls;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return IP address for overlay VNC access on port 5900. Set to 'auto', to reuse nic:0:dhcp if
|
||||
* available, or otherwise allocate a temporary IP at boot.
|
||||
*/
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Password for VNC access. If unset, VNC is disabled.
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Set to 'on' to require VeNCrypt-style TLS auth in addition to the password. If this is
|
||||
* unset, only unencrypted VNC is available.
|
||||
*/
|
||||
public boolean isTls() {
|
||||
return tls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((ip == null) ? 0 : ip.hashCode());
|
||||
result = prime * result + ((password == null) ? 0 : password.hashCode());
|
||||
result = prime * result + (tls ? 1231 : 1237);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
VNC other = (VNC) obj;
|
||||
if (ip == null) {
|
||||
if (other.ip != null)
|
||||
return false;
|
||||
} else if (!ip.equals(other.ip))
|
||||
return false;
|
||||
if (password == null) {
|
||||
if (other.password != null)
|
||||
return false;
|
||||
} else if (!password.equals(other.password))
|
||||
return false;
|
||||
if (tls != other.tls)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[ip=" + ip + ", password=" + password + ", tls=" + tls + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.domain.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.elasticstack.domain.ClaimType;
|
||||
import org.jclouds.elasticstack.domain.Item;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BaseDrive extends Item {
|
||||
public static class Builder extends Item.Builder {
|
||||
protected long size;
|
||||
protected ClaimType claimType = ClaimType.EXCLUSIVE;
|
||||
protected Set<String> readers = ImmutableSet.of();
|
||||
|
||||
public Builder claimType(ClaimType claimType) {
|
||||
this.claimType = claimType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder readers(Iterable<String> readers) {
|
||||
this.readers = ImmutableSet.copyOf(checkNotNull(readers, "readers"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder size(long size) {
|
||||
this.size = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder uuid(String uuid) {
|
||||
return Builder.class.cast(super.uuid(uuid));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder name(String name) {
|
||||
return Builder.class.cast(super.name(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder tags(Iterable<String> tags) {
|
||||
return Builder.class.cast(super.tags(tags));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder userMetadata(Map<String, String> userMetadata) {
|
||||
return Builder.class.cast(super.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
public BaseDrive build() {
|
||||
return new BaseDrive(uuid, name, size, claimType, readers, tags, userMetadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((claimType == null) ? 0 : claimType.hashCode());
|
||||
result = prime * result + ((readers == null) ? 0 : readers.hashCode());
|
||||
result = prime * result + (int) (size ^ (size >>> 32));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Builder other = (Builder) obj;
|
||||
if (claimType != other.claimType)
|
||||
return false;
|
||||
if (readers == null) {
|
||||
if (other.readers != null)
|
||||
return false;
|
||||
} else if (!readers.equals(other.readers))
|
||||
return false;
|
||||
if (size != other.size)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected final long size;
|
||||
protected final ClaimType claimType;
|
||||
protected final Set<String> readers;
|
||||
|
||||
public BaseDrive(@Nullable String uuid, String name, long size, @Nullable ClaimType claimType,
|
||||
Iterable<String> readers, Iterable<String> tags, Map<String, String> userMetadata) {
|
||||
super(uuid, name, tags, userMetadata);
|
||||
this.size = size;
|
||||
this.claimType = checkNotNull(claimType, "set claimType to exclusive, not null");
|
||||
this.readers = ImmutableSet.copyOf(checkNotNull(readers, "readers"));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return either 'exclusive' (the default) or 'shared' to allow multiple servers to access a
|
||||
* drive simultaneously
|
||||
*/
|
||||
@Nullable
|
||||
public ClaimType getClaimType() {
|
||||
return claimType;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return list of users allowed to read from a drive or 'ffffffff-ffff-ffff-ffff-ffffffffffff'
|
||||
* for all users
|
||||
*/
|
||||
public Set<String> getReaders() {
|
||||
return readers;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return size of drive in bytes
|
||||
*/
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((claimType == null) ? 0 : claimType.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((readers == null) ? 0 : readers.hashCode());
|
||||
result = prime * result + (int) (size ^ (size >>> 32));
|
||||
result = prime * result + ((tags == null) ? 0 : tags.hashCode());
|
||||
result = prime * result + ((userMetadata == null) ? 0 : userMetadata.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
BaseDrive other = (BaseDrive) obj;
|
||||
if (claimType != other.claimType)
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (readers == null) {
|
||||
if (other.readers != null)
|
||||
return false;
|
||||
} else if (!readers.equals(other.readers))
|
||||
return false;
|
||||
if (size != other.size)
|
||||
return false;
|
||||
if (tags == null) {
|
||||
if (other.tags != null)
|
||||
return false;
|
||||
} else if (!tags.equals(other.tags))
|
||||
return false;
|
||||
if (userMetadata == null) {
|
||||
if (other.userMetadata != null)
|
||||
return false;
|
||||
} else if (!userMetadata.equals(other.userMetadata))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[uuid=" + uuid + ", name=" + name + ", tags=" + tags + ", userMetadata=" + userMetadata + ", size="
|
||||
+ size + ", claimType=" + claimType + ", readers=" + readers + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.elasticstack.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.elasticstack.domain.ClaimType;
|
||||
import org.jclouds.elasticstack.domain.internal.BaseDrive;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class BaseDriveToMap implements Function<BaseDrive, Map<String, String>> {
|
||||
@Override
|
||||
public Map<String, String> apply(BaseDrive from) {
|
||||
checkNotNull(from, "drive");
|
||||
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
||||
builder.put("name", from.getName());
|
||||
builder.put("size", from.getSize() + "");
|
||||
if (from.getClaimType() != ClaimType.EXCLUSIVE)
|
||||
builder.put("claim:type", from.getClaimType().toString());
|
||||
if (from.getReaders().size() != 0)
|
||||
builder.put("readers", Joiner.on(' ').join(from.getReaders()));
|
||||
if (from.getTags().size() != 0)
|
||||
builder.put("tags", Joiner.on(' ').join(from.getTags()));
|
||||
for (Entry<String, String> entry : from.getUserMetadata().entrySet())
|
||||
builder.put("user:" + entry.getKey(), entry.getValue());
|
||||
return builder.build();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue