mirror of https://github.com/apache/jclouds.git
Issue 86 updated to latest azure api release and added more support for queue
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2674 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
e38f58902c
commit
0f6412dfbd
|
@ -42,8 +42,8 @@ import org.jclouds.azure.storage.blob.options.CreateContainerOptions;
|
|||
import org.jclouds.azure.storage.blob.options.ListBlobsOptions;
|
||||
import org.jclouds.azure.storage.blob.xml.AccountNameEnumerationResultsHandler;
|
||||
import org.jclouds.azure.storage.blob.xml.ContainerNameEnumerationResultsHandler;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
|
||||
import org.jclouds.azure.storage.domain.BoundedSet;
|
||||
import org.jclouds.azure.storage.filters.SharedKeyLiteAuthentication;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
|
||||
import org.jclouds.blobstore.attr.ConsistencyModel;
|
||||
|
@ -80,8 +80,8 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@SkipEncoding('/')
|
||||
@RequestFilters(SharedKeyAuthentication.class)
|
||||
@Headers(keys = AzureStorageHeaders.VERSION, values = "2009-07-17")
|
||||
@RequestFilters(SharedKeyLiteAuthentication.class)
|
||||
@Headers(keys = AzureStorageHeaders.VERSION, values = "2009-09-19")
|
||||
@Endpoint(AzureBlob.class)
|
||||
@ConsistencyModel(ConsistencyModels.STRICT)
|
||||
public interface AzureBlobAsyncClient {
|
||||
|
@ -95,7 +95,7 @@ public interface AzureBlobAsyncClient {
|
|||
@XMLResponseParser(AccountNameEnumerationResultsHandler.class)
|
||||
@Path("/")
|
||||
@QueryParams(keys = "comp", values = "list")
|
||||
ListenableFuture<? extends BoundedSortedSet<ListableContainerProperties>> listContainers(
|
||||
ListenableFuture<? extends BoundedSet<ListableContainerProperties>> listContainers(
|
||||
ListOptions... listOptions);
|
||||
|
||||
/**
|
||||
|
@ -161,7 +161,7 @@ public interface AzureBlobAsyncClient {
|
|||
@Path("$root")
|
||||
@ExceptionParser(ReturnTrueOn404.class)
|
||||
@QueryParams(keys = "restype", values = "container")
|
||||
ListenableFuture<Boolean> deleteRootContainer();
|
||||
ListenableFuture<Void> deleteRootContainer();
|
||||
|
||||
/**
|
||||
* @see AzureBlobClient#listBlobs(String, ListBlobsOptions)
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
|
|||
import org.jclouds.azure.storage.blob.domain.ListableContainerProperties;
|
||||
import org.jclouds.azure.storage.blob.options.CreateContainerOptions;
|
||||
import org.jclouds.azure.storage.blob.options.ListBlobsOptions;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.BoundedSet;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
|
@ -57,7 +57,7 @@ public interface AzureBlobClient {
|
|||
* controls the number or type of results requested
|
||||
* @see ListOptions
|
||||
*/
|
||||
BoundedSortedSet<ListableContainerProperties> listContainers(ListOptions... listOptions);
|
||||
BoundedSet<ListableContainerProperties> listContainers(ListOptions... listOptions);
|
||||
|
||||
/**
|
||||
* The Create Container operation creates a new container under the specified account. If the
|
||||
|
@ -138,7 +138,7 @@ public interface AzureBlobClient {
|
|||
* @see deleteContainer(String)
|
||||
* @see createRootContainer(CreateContainerOptions)
|
||||
*/
|
||||
boolean deleteRootContainer();
|
||||
void deleteRootContainer();
|
||||
|
||||
/**
|
||||
* The List Blobs operation enumerates the list of blobs under the specified container.
|
||||
|
|
|
@ -40,13 +40,18 @@ import com.google.inject.Module;
|
|||
* @see AzureBlobAsyncClient
|
||||
*/
|
||||
public class AzureBlobContextFactory {
|
||||
|
||||
public static RestContext<AzureBlobAsyncClient, AzureBlobClient> createContext(
|
||||
Properties properties, Module... modules) {
|
||||
return new AzureBlobContextBuilder(new AzureBlobPropertiesBuilder(properties).build())
|
||||
.withModules(modules).buildContext();
|
||||
}
|
||||
|
||||
public static RestContext<AzureBlobAsyncClient, AzureBlobClient> createContext(
|
||||
Properties properties, String account, String encodedKey, Module... modules) {
|
||||
return new AzureBlobContextBuilder(new AzureBlobPropertiesBuilder(properties)
|
||||
.withCredentials(account, encodedKey).build()).withModules(modules).buildContext();
|
||||
}
|
||||
|
||||
public static RestContext<AzureBlobAsyncClient, AzureBlobClient> createContext(String account,
|
||||
String encodedKey, Module... modules) {
|
||||
return new AzureBlobContextBuilder(new AzureBlobPropertiesBuilder(account, encodedKey)
|
||||
|
|
|
@ -24,7 +24,7 @@ import javax.ws.rs.GET;
|
|||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
|
||||
import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
|
||||
import org.jclouds.azure.storage.filters.SharedKeyLiteAuthentication;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
|
||||
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
||||
import org.jclouds.http.functions.ParseContentMD5FromHeaders;
|
||||
|
@ -43,7 +43,7 @@ import org.jclouds.rest.annotations.SkipEncoding;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@SkipEncoding('/')
|
||||
@RequestFilters(SharedKeyAuthentication.class)
|
||||
@RequestFilters(SharedKeyLiteAuthentication.class)
|
||||
@Headers(keys = AzureStorageHeaders.VERSION, values = "2009-07-17")
|
||||
public interface AzureBlobUtil {
|
||||
|
||||
|
|
|
@ -23,35 +23,64 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.azure.storage.blob.blobstore.functions.AzureBlobToBlob;
|
||||
import org.jclouds.azure.storage.blob.domain.AzureBlob;
|
||||
import org.jclouds.azure.storage.blob.reference.AzureBlobConstants;
|
||||
import org.jclouds.blobstore.binders.BindBlobToPayloadAndUserMetadataToHeadersWithPrefix;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.Binder;
|
||||
|
||||
public class BindAzureBlobToPayload extends BindBlobToPayloadAndUserMetadataToHeadersWithPrefix {
|
||||
@Singleton
|
||||
public class BindAzureBlobToPayload implements Binder {
|
||||
|
||||
private final AzureBlobToBlob azureBlob2Blob;
|
||||
private final String metadataPrefix;
|
||||
private final EncryptionService encryptionService;
|
||||
|
||||
@Inject
|
||||
public BindAzureBlobToPayload(AzureBlobToBlob azureBlob2Blob,
|
||||
public BindAzureBlobToPayload(
|
||||
@Named(AzureBlobConstants.PROPERTY_AZUREBLOB_METADATA_PREFIX) String prefix,
|
||||
EncryptionService encryptionService) {
|
||||
super(prefix, encryptionService);
|
||||
this.azureBlob2Blob = azureBlob2Blob;
|
||||
this.metadataPrefix = prefix;
|
||||
this.encryptionService = encryptionService;
|
||||
}
|
||||
|
||||
public void bindToRequest(HttpRequest request, Object payload) {
|
||||
AzureBlob object = (AzureBlob) payload;
|
||||
checkArgument(object.getProperties().getSize() >= 0, "size must be set");
|
||||
checkArgument(
|
||||
checkNotNull(object.getContentLength(), "object.getContentLength()") <= 64 * 1024 * 1024,
|
||||
"maximum size for put Blob is 64MB");
|
||||
super.bindToRequest(request, azureBlob2Blob.apply(object));
|
||||
checkArgument(object.getProperties().getContentLength() >= 0, "size must be set");
|
||||
request.getHeaders().put("x-ms-blob-type", object.getProperties().getType().toString());
|
||||
|
||||
switch (object.getProperties().getType()) {
|
||||
case PAGE_BLOB:
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, "0");
|
||||
request.getHeaders().put("x-ms-blob-content-length", object.getContentLength() + "");
|
||||
break;
|
||||
case BLOCK_BLOB:
|
||||
checkArgument(
|
||||
checkNotNull(object.getContentLength(), "object.getContentLength()") <= 64 * 1024 * 1024,
|
||||
"maximum size for put Blob is 64MB");
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, object.getContentLength() + "");
|
||||
break;
|
||||
}
|
||||
|
||||
for (String key : object.getProperties().getMetadata().keySet()) {
|
||||
request.getHeaders().put(key.startsWith(metadataPrefix) ? key : metadataPrefix + key,
|
||||
object.getProperties().getMetadata().get(key));
|
||||
}
|
||||
|
||||
request.setPayload(checkNotNull(object.getContent(), "object.getContent()"));
|
||||
request.getHeaders().put(
|
||||
HttpHeaders.CONTENT_TYPE,
|
||||
checkNotNull(object.getProperties().getContentType(),
|
||||
"object.metadata.contentType()"));
|
||||
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, object.getContentLength() + "");
|
||||
|
||||
if (object.getProperties().getContentMD5() != null) {
|
||||
request.getHeaders().put("Content-MD5",
|
||||
encryptionService.toBase64String(object.getProperties().getContentMD5()));
|
||||
}
|
||||
if (object.getProperties().getContentLanguage() != null) {
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_LANGUAGE,
|
||||
object.getProperties().getContentLanguage());
|
||||
|
|
|
@ -22,7 +22,7 @@ import static com.google.common.util.concurrent.Futures.compose;
|
|||
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive;
|
||||
import static org.jclouds.concurrent.internal.ConcurrentUtils.makeListenable;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
|
@ -135,9 +135,9 @@ public class AzureAsyncBlobStore extends BaseAzureBlobStore implements AsyncBlob
|
|||
public ListenableFuture<? extends org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata>> list() {
|
||||
return compose(
|
||||
async.listContainers(),
|
||||
new Function<SortedSet<ListableContainerProperties>, org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata>>() {
|
||||
new Function<Set<ListableContainerProperties>, org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata>>() {
|
||||
public org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata> apply(
|
||||
SortedSet<ListableContainerProperties> from) {
|
||||
Set<ListableContainerProperties> from) {
|
||||
return new ListResponseImpl<StorageMetadata>(Iterables.transform(from,
|
||||
container2ResourceMd), null, null, false);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ package org.jclouds.azure.storage.blob.blobstore;
|
|||
|
||||
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -121,9 +121,9 @@ public class AzureBlobStore extends BaseAzureBlobStore implements BlobStore {
|
|||
}
|
||||
|
||||
public ListResponse<? extends StorageMetadata> list() {
|
||||
return new Function<SortedSet<ListableContainerProperties>, org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata>>() {
|
||||
return new Function<Set<ListableContainerProperties>, org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata>>() {
|
||||
public org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata> apply(
|
||||
SortedSet<ListableContainerProperties> from) {
|
||||
Set<ListableContainerProperties> from) {
|
||||
return new ListResponseImpl<StorageMetadata>(Iterables.transform(from,
|
||||
container2ResourceMd), null, null, false);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ public class BlobMetadataToBlobProperties implements Function<BlobMetadata, Muta
|
|||
to.setName(base.getName());
|
||||
to.setLastModified(base.getLastModified());
|
||||
if (base.getSize() != null)
|
||||
to.setSize(base.getSize());
|
||||
to.setContentLength(base.getSize());
|
||||
if (base.getUserMetadata() != null)
|
||||
to.setMetadata(base.getUserMetadata());
|
||||
return to;
|
||||
|
|
|
@ -23,24 +23,39 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.azure.storage.blob.domain.BlobProperties;
|
||||
import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
||||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
|
||||
import org.jclouds.blobstore.strategy.IsDirectoryStrategy;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class BlobPropertiesToBlobMetadata extends
|
||||
ListableBlobPropertiesToBlobMetadata<BlobProperties> {
|
||||
public class BlobPropertiesToBlobMetadata implements Function<BlobProperties, MutableBlobMetadata> {
|
||||
private final IsDirectoryStrategy isDirectoryStrategy;
|
||||
|
||||
@Inject
|
||||
public BlobPropertiesToBlobMetadata(IsDirectoryStrategy isDirectoryStrategy) {
|
||||
super(isDirectoryStrategy);
|
||||
this.isDirectoryStrategy = isDirectoryStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableBlobMetadata apply(BlobProperties from) {
|
||||
MutableBlobMetadata to = super.apply(from);
|
||||
to.setContentMD5(from.getContentMD5());
|
||||
MutableBlobMetadata to = new MutableBlobMetadataImpl();
|
||||
if (from.getContentMD5() != null)
|
||||
to.setContentMD5(from.getContentMD5());
|
||||
if (from.getContentType() != null)
|
||||
to.setContentType(from.getContentType());
|
||||
to.setUserMetadata(from.getMetadata());
|
||||
to.setETag(from.getETag());
|
||||
to.setLastModified(from.getLastModified());
|
||||
to.setName(from.getName());
|
||||
to.setSize(from.getContentLength());
|
||||
to.setType(StorageType.BLOB);
|
||||
if (isDirectoryStrategy.execute(to)) {
|
||||
to.setType(StorageType.RELATIVE_PATH);
|
||||
}
|
||||
return to;
|
||||
}
|
||||
}
|
|
@ -24,7 +24,6 @@ import javax.inject.Inject;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
|
||||
import org.jclouds.azure.storage.blob.domain.ListableBlobProperties;
|
||||
import org.jclouds.blobstore.domain.ListContainerResponse;
|
||||
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||
import org.jclouds.blobstore.domain.internal.ListContainerResponseImpl;
|
||||
|
@ -39,12 +38,11 @@ import com.google.common.collect.Sets;
|
|||
@Singleton
|
||||
public class ListBlobsResponseToResourceList implements
|
||||
Function<ListBlobsResponse, ListContainerResponse<? extends StorageMetadata>> {
|
||||
private final ListableBlobPropertiesToBlobMetadata<ListableBlobProperties> object2blobMd;
|
||||
private final BlobPropertiesToBlobMetadata object2blobMd;
|
||||
private final CommonPrefixesToResourceMetadata prefix2ResourceMd;
|
||||
|
||||
@Inject
|
||||
public ListBlobsResponseToResourceList(
|
||||
ListableBlobPropertiesToBlobMetadata<ListableBlobProperties> object2blobMd,
|
||||
public ListBlobsResponseToResourceList(BlobPropertiesToBlobMetadata object2blobMd,
|
||||
CommonPrefixesToResourceMetadata prefix2ResourceMd) {
|
||||
this.object2blobMd = object2blobMd;
|
||||
this.prefix2ResourceMd = prefix2ResourceMd;
|
||||
|
@ -53,8 +51,8 @@ public class ListBlobsResponseToResourceList implements
|
|||
public ListContainerResponse<? extends StorageMetadata> apply(ListBlobsResponse from) {
|
||||
SortedSet<StorageMetadata> contents = Sets.newTreeSet(Iterables.concat(Iterables.transform(
|
||||
from, object2blobMd), prefix2ResourceMd.apply(from.getBlobPrefixes())));
|
||||
return new ListContainerResponseImpl<StorageMetadata>(contents, from.getPrefix(), from.getMarker(),
|
||||
from.getMaxResults(), from.size() == from.getMaxResults());
|
||||
return new ListContainerResponseImpl<StorageMetadata>(contents, from.getPrefix(), from
|
||||
.getMarker(), from.getMaxResults(), from.size() == from.getMaxResults());
|
||||
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 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.azure.storage.blob.blobstore.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.ListableBlobProperties;
|
||||
import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
||||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
|
||||
import org.jclouds.blobstore.strategy.IsDirectoryStrategy;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ListableBlobPropertiesToBlobMetadata<T extends ListableBlobProperties> implements
|
||||
Function<T, MutableBlobMetadata> {
|
||||
private final IsDirectoryStrategy isDirectoryStrategy;
|
||||
|
||||
@Inject
|
||||
public ListableBlobPropertiesToBlobMetadata(IsDirectoryStrategy isDirectoryStrategy) {
|
||||
this.isDirectoryStrategy = isDirectoryStrategy;
|
||||
}
|
||||
|
||||
public MutableBlobMetadata apply(T from) {
|
||||
MutableBlobMetadata to = new MutableBlobMetadataImpl();
|
||||
if (from.getContentType() != null)
|
||||
to.setContentType(from.getContentType());
|
||||
to.setETag(from.getETag());
|
||||
to.setLastModified(from.getLastModified());
|
||||
to.setName(from.getName());
|
||||
to.setSize(from.getSize());
|
||||
to.setType(StorageType.BLOB);
|
||||
if (isDirectoryStrategy.execute(to)) {
|
||||
to.setType(StorageType.RELATIVE_PATH);
|
||||
}
|
||||
return to;
|
||||
}
|
||||
}
|
|
@ -23,10 +23,10 @@ import java.util.SortedSet;
|
|||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.BlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
|
||||
import org.jclouds.azure.storage.blob.domain.ListableBlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.MutableBlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.TreeSetListBlobsResponse;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.HashSetListBlobsResponse;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ListContainerResponse;
|
||||
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||
|
@ -52,14 +52,14 @@ public class ResourceToListBlobsResponse implements
|
|||
|
||||
public ListBlobsResponse apply(ListContainerResponse<? extends StorageMetadata> list) {
|
||||
|
||||
Iterable<ListableBlobProperties> contents = Iterables.transform(Iterables.filter(list,
|
||||
Iterable<BlobProperties> contents = Iterables.transform(Iterables.filter(list,
|
||||
new Predicate<StorageMetadata>() {
|
||||
|
||||
public boolean apply(StorageMetadata input) {
|
||||
return input.getType() == StorageType.BLOB;
|
||||
}
|
||||
|
||||
}), new Function<StorageMetadata, ListableBlobProperties>() {
|
||||
}), new Function<StorageMetadata, BlobProperties>() {
|
||||
|
||||
public MutableBlobProperties apply(StorageMetadata from) {
|
||||
return blob2ObjectMd.apply((BlobMetadata) from);
|
||||
|
@ -81,7 +81,7 @@ public class ResourceToListBlobsResponse implements
|
|||
}
|
||||
|
||||
}));
|
||||
return new TreeSetListBlobsResponse(contents, null, list.getPath(), null, list
|
||||
.getMaxResults(),list.getMarker(), "/", commonPrefixes);
|
||||
return new HashSetListBlobsResponse(contents, null, list.getPath(), null, list
|
||||
.getMaxResults(), list.getMarker(), "/", commonPrefixes);
|
||||
}
|
||||
}
|
|
@ -18,10 +18,12 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.blob.domain;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.http.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
|
||||
|
@ -33,6 +35,8 @@ import com.google.inject.internal.Nullable;
|
|||
* />
|
||||
*/
|
||||
public interface AzureBlob extends PayloadEnclosing, Comparable<AzureBlob> {
|
||||
|
||||
|
||||
public interface Factory {
|
||||
AzureBlob create(@Nullable MutableBlobProperties properties);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.blob.domain;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
@ -25,15 +27,48 @@ import java.util.Map;
|
|||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public interface BlobProperties extends ListableBlobProperties {
|
||||
|
||||
/**
|
||||
* This value present in system metadata requests on blobs which were created specifying the
|
||||
* Content-MD5 header. It is not present in container listings.
|
||||
*/
|
||||
byte[] getContentMD5();
|
||||
|
||||
public interface BlobProperties extends Comparable<BlobProperties> {
|
||||
|
||||
Map<String, String> getMetadata();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
BlobType getType();
|
||||
|
||||
URI getUrl();
|
||||
|
||||
String getName();
|
||||
|
||||
Date getLastModified();
|
||||
|
||||
String getETag();
|
||||
|
||||
Long getContentLength();
|
||||
|
||||
/**
|
||||
* This value present in system metadata requests on blobs which were created specifying the
|
||||
* Content-MD5 header.
|
||||
*/
|
||||
byte[] getContentMD5();
|
||||
|
||||
/**
|
||||
*
|
||||
* A standard MIME type describing the format of the contents. If none is provided, the default
|
||||
* is binary/octet-stream.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17"/>
|
||||
*/
|
||||
String getContentType();
|
||||
|
||||
/**
|
||||
* Specifies what content encodings have been applied to the object and thus what decoding
|
||||
* mechanisms must be applied in order to obtain the media-type referenced by the Content-Type
|
||||
* header field.
|
||||
*
|
||||
* @see <a href= "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.11" />
|
||||
*/
|
||||
public String getContentEncoding();
|
||||
|
||||
public String getContentLanguage();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 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.azure.storage.blob.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum BlobType {
|
||||
BLOCK_BLOB, PAGE_BLOB;
|
||||
|
||||
public String value() {
|
||||
return (CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value();
|
||||
}
|
||||
|
||||
public static BlobType fromValue(String type) {
|
||||
return valueOf(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(type,
|
||||
"type")));
|
||||
}
|
||||
}
|
|
@ -18,17 +18,17 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.blob.domain;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.BoundedSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface ListBlobsResponse extends BoundedSortedSet<ListableBlobProperties> {
|
||||
public interface ListBlobsResponse extends BoundedSet<BlobProperties> {
|
||||
|
||||
String getDelimiter();
|
||||
|
||||
SortedSet<String> getBlobPrefixes();
|
||||
Set<String> getBlobPrefixes();
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 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.azure.storage.blob.domain;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public interface ListableBlobProperties extends Comparable<ListableBlobProperties> {
|
||||
URI getUrl();
|
||||
|
||||
String getName();
|
||||
|
||||
Date getLastModified();
|
||||
|
||||
String getETag();
|
||||
|
||||
Long getSize();
|
||||
|
||||
/**
|
||||
*
|
||||
* A standard MIME type describing the format of the contents. If none is provided, the default
|
||||
* is binary/octet-stream.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17"/>
|
||||
*/
|
||||
String getContentType();
|
||||
|
||||
/**
|
||||
* Specifies what content encodings have been applied to the object and thus what decoding
|
||||
* mechanisms must be applied in order to obtain the media-type referenced by the Content-Type
|
||||
* header field.
|
||||
*
|
||||
* @see <a href= "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.11" />
|
||||
*/
|
||||
public String getContentEncoding();
|
||||
|
||||
public String getContentLanguage();
|
||||
|
||||
}
|
|
@ -34,52 +34,52 @@ import com.google.inject.ImplementedBy;
|
|||
@ImplementedBy(MutableBlobPropertiesImpl.class)
|
||||
public interface MutableBlobProperties extends BlobProperties {
|
||||
/**
|
||||
* @see ListableContainerProperties#setUrl
|
||||
* @see ListableContainerProperties#getUrl
|
||||
*/
|
||||
void setUrl(URI url);
|
||||
|
||||
/**
|
||||
* @see ListableContainerProperties#setName
|
||||
* @see ListableContainerProperties#getName
|
||||
*/
|
||||
void setName(String name);
|
||||
|
||||
/**
|
||||
* @see ListableContainerProperties#setLastModified
|
||||
* @see ListableContainerProperties#getLastModified
|
||||
*/
|
||||
void setLastModified(Date lastModified);
|
||||
|
||||
/**
|
||||
* @see ListableContainerProperties#setETag
|
||||
* @see ListableContainerProperties#getETag
|
||||
*/
|
||||
void setETag(String eTag);
|
||||
|
||||
/**
|
||||
* @see ListableContainerProperties#setSize
|
||||
* @see ListableContainerProperties#getContentLength
|
||||
*/
|
||||
void setSize(long size);
|
||||
void setContentLength(long size);
|
||||
|
||||
/**
|
||||
* @see ListableContainerProperties#setContentMD5
|
||||
* @see ListableContainerProperties#getContentMD5
|
||||
*/
|
||||
void setContentMD5(byte[] md5);
|
||||
|
||||
/**
|
||||
* @see ListableContainerProperties#setContentType
|
||||
* @see ListableContainerProperties#getContentType
|
||||
*/
|
||||
void setContentType(String contentType);
|
||||
|
||||
/**
|
||||
* @see ListableContainerProperties#setContentEncoding
|
||||
* @see ListableContainerProperties#getContentEncoding
|
||||
*/
|
||||
void setContentEncoding(String contentEncoding);
|
||||
|
||||
/**
|
||||
* @see ListableContainerProperties#setContentLanguage
|
||||
* @see ListableContainerProperties#getContentLanguage
|
||||
*/
|
||||
void setContentLanguage(String contentLanguage);
|
||||
|
||||
/**
|
||||
* @see ListableContainerProperties#setMetadata
|
||||
* @see ListableContainerProperties#getMetadata
|
||||
*/
|
||||
void setMetadata(Map<String, String> metadata);
|
||||
|
||||
|
|
|
@ -22,10 +22,14 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.ListableBlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobType;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
|
@ -33,31 +37,53 @@ import com.google.inject.internal.Nullable;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ListableBlobPropertiesImpl implements Serializable, ListableBlobProperties {
|
||||
public class BlobPropertiesImpl implements Serializable, BlobProperties {
|
||||
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -4648755473986695062L;
|
||||
|
||||
private final BlobType type;
|
||||
private final String name;
|
||||
private final URI url;
|
||||
private final Date lastModified;
|
||||
private final String eTag;
|
||||
private final long size;
|
||||
private final String contentType;
|
||||
private final byte[] contentMD5;
|
||||
private final String contentEncoding;
|
||||
private final String contentLanguage;
|
||||
private final Map<String, String> metadata = Maps.newHashMap();
|
||||
|
||||
public ListableBlobPropertiesImpl(String name, URI url, Date lastModified, String eTag,
|
||||
long size, String contentType, @Nullable String contentEncoding,
|
||||
@Nullable String contentLanguage) {
|
||||
public BlobPropertiesImpl(BlobType type, String name, URI url, Date lastModified, String eTag,
|
||||
long size, String contentType, @Nullable byte[] contentMD5,
|
||||
@Nullable String contentEncoding, @Nullable String contentLanguage,
|
||||
Map<String, String> metadata) {
|
||||
this.type = checkNotNull(type, "type");
|
||||
this.name = checkNotNull(name, "name");
|
||||
this.url = checkNotNull(url, "url");
|
||||
this.lastModified = checkNotNull(lastModified, "lastModified");
|
||||
this.eTag = checkNotNull(eTag, "eTag");
|
||||
this.size = size;
|
||||
this.contentType = checkNotNull(contentType, "contentType");
|
||||
this.contentMD5 = contentMD5;
|
||||
this.contentEncoding = contentEncoding;
|
||||
this.contentLanguage = contentLanguage;
|
||||
this.metadata.putAll(checkNotNull(metadata, "metadata"));
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public byte[] getContentMD5() {
|
||||
return contentMD5;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public BlobType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,14 +124,14 @@ public class ListableBlobPropertiesImpl implements Serializable, ListableBlobPro
|
|||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public Long getSize() {
|
||||
public Long getContentLength() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public int compareTo(ListableBlobProperties o) {
|
||||
public int compareTo(BlobProperties o) {
|
||||
return (this == o) ? 0 : getName().compareTo(o.getName());
|
||||
}
|
||||
|
||||
|
@ -123,11 +149,14 @@ public class ListableBlobPropertiesImpl implements Serializable, ListableBlobPro
|
|||
int result = 1;
|
||||
result = prime * result + ((contentEncoding == null) ? 0 : contentEncoding.hashCode());
|
||||
result = prime * result + ((contentLanguage == null) ? 0 : contentLanguage.hashCode());
|
||||
result = prime * result + Arrays.hashCode(contentMD5);
|
||||
result = prime * result + ((contentType == null) ? 0 : contentType.hashCode());
|
||||
result = prime * result + ((eTag == null) ? 0 : eTag.hashCode());
|
||||
result = prime * result + ((lastModified == null) ? 0 : lastModified.hashCode());
|
||||
result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + (int) (size ^ (size >>> 32));
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
result = prime * result + ((url == null) ? 0 : url.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
@ -140,7 +169,7 @@ public class ListableBlobPropertiesImpl implements Serializable, ListableBlobPro
|
|||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ListableBlobPropertiesImpl other = (ListableBlobPropertiesImpl) obj;
|
||||
BlobPropertiesImpl other = (BlobPropertiesImpl) obj;
|
||||
if (contentEncoding == null) {
|
||||
if (other.contentEncoding != null)
|
||||
return false;
|
||||
|
@ -151,6 +180,8 @@ public class ListableBlobPropertiesImpl implements Serializable, ListableBlobPro
|
|||
return false;
|
||||
} else if (!contentLanguage.equals(other.contentLanguage))
|
||||
return false;
|
||||
if (!Arrays.equals(contentMD5, other.contentMD5))
|
||||
return false;
|
||||
if (contentType == null) {
|
||||
if (other.contentType != null)
|
||||
return false;
|
||||
|
@ -166,6 +197,11 @@ public class ListableBlobPropertiesImpl implements Serializable, ListableBlobPro
|
|||
return false;
|
||||
} else if (!lastModified.equals(other.lastModified))
|
||||
return false;
|
||||
if (metadata == null) {
|
||||
if (other.metadata != null)
|
||||
return false;
|
||||
} else if (!metadata.equals(other.metadata))
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
|
@ -173,6 +209,11 @@ public class ListableBlobPropertiesImpl implements Serializable, ListableBlobPro
|
|||
return false;
|
||||
if (size != other.size)
|
||||
return false;
|
||||
if (type == null) {
|
||||
if (other.type != null)
|
||||
return false;
|
||||
} else if (!type.equals(other.type))
|
||||
return false;
|
||||
if (url == null) {
|
||||
if (other.url != null)
|
||||
return false;
|
||||
|
@ -181,4 +222,9 @@ public class ListableBlobPropertiesImpl implements Serializable, ListableBlobPro
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
}
|
|
@ -19,38 +19,41 @@
|
|||
package org.jclouds.azure.storage.blob.domain.internal;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.SortedSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.BlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
|
||||
import org.jclouds.azure.storage.blob.domain.ListableBlobProperties;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedTreeSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedHashSet;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public class TreeSetListBlobsResponse extends BoundedTreeSet<ListableBlobProperties> implements
|
||||
public class HashSetListBlobsResponse extends BoundedHashSet<BlobProperties> implements
|
||||
ListBlobsResponse {
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -4475709781001190244L;
|
||||
|
||||
public TreeSetListBlobsResponse(Iterable<ListableBlobProperties> contents, URI url, String prefix,
|
||||
protected final String delimiter;
|
||||
protected final Set<String> blobPrefixes = Sets.newHashSet();
|
||||
|
||||
public HashSetListBlobsResponse(Iterable<BlobProperties> contents, URI url, String prefix,
|
||||
String marker, Integer maxResults, String nextMarker, String delimiter,
|
||||
SortedSet<String> blobPrefixes) {
|
||||
Iterable<String> blobPrefixes) {
|
||||
super(contents, url, prefix, marker, maxResults, nextMarker);
|
||||
this.delimiter = delimiter;
|
||||
this.blobPrefixes = blobPrefixes;
|
||||
Iterables.addAll(this.blobPrefixes, blobPrefixes);
|
||||
}
|
||||
|
||||
protected final String delimiter;
|
||||
protected final SortedSet<String> blobPrefixes;
|
||||
|
||||
public String getDelimiter() {
|
||||
return delimiter;
|
||||
}
|
||||
|
||||
public SortedSet<String> getBlobPrefixes() {
|
||||
public Set<String> getBlobPrefixes() {
|
||||
return blobPrefixes;
|
||||
}
|
||||
}
|
|
@ -24,7 +24,8 @@ import java.util.Arrays;
|
|||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.ListableBlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobType;
|
||||
import org.jclouds.azure.storage.blob.domain.MutableBlobProperties;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
@ -39,6 +40,7 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -4648755473986695062L;
|
||||
|
||||
private BlobType type = BlobType.BLOCK_BLOB;
|
||||
private String name;
|
||||
private URI url;
|
||||
private Date lastModified;
|
||||
|
@ -53,6 +55,20 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
public MutableBlobPropertiesImpl() {
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public BlobType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setType(BlobType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -91,14 +107,14 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public Long getSize() {
|
||||
public Long getContentLength() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public int compareTo(ListableBlobProperties o) {
|
||||
public int compareTo(BlobProperties o) {
|
||||
return (this == o) ? 0 : getName().compareTo(o.getName());
|
||||
}
|
||||
|
||||
|
@ -171,7 +187,7 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setSize(long size) {
|
||||
public void setContentLength(long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
|
@ -211,6 +227,7 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + (int) (size ^ (size >>> 32));
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
result = prime * result + ((url == null) ? 0 : url.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
@ -263,6 +280,11 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
return false;
|
||||
if (size != other.size)
|
||||
return false;
|
||||
if (type == null) {
|
||||
if (other.type != null)
|
||||
return false;
|
||||
} else if (!type.equals(other.type))
|
||||
return false;
|
||||
if (url == null) {
|
||||
if (other.url != null)
|
||||
return false;
|
||||
|
|
|
@ -77,9 +77,9 @@ public class ParseBlobFromHeadersAndHttpContent implements Function<HttpResponse
|
|||
}
|
||||
|
||||
if (contentRange == null && contentLength != null) {
|
||||
object.getProperties().setSize(object.getContentLength());
|
||||
object.getProperties().setContentLength(object.getContentLength());
|
||||
} else if (contentRange != null) {
|
||||
object.getProperties().setSize(
|
||||
object.getProperties().setContentLength(
|
||||
Long.parseLong(contentRange.substring(contentRange.lastIndexOf('/') + 1)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public class ParseBlobPropertiesFromHeaders implements
|
|||
MutableBlobProperties to = blobToBlobProperties.apply(base);
|
||||
if (from.getFirstHeaderOrNull("Content-Range") != null) {
|
||||
String range = from.getFirstHeaderOrNull("Content-Range");
|
||||
to.setSize(Long.parseLong(range.split("/")[1]));
|
||||
to.setContentLength(Long.parseLong(range.split("/")[1]));
|
||||
}
|
||||
to.setContentLanguage(from.getFirstHeaderOrNull(HttpHeaders.CONTENT_LANGUAGE));
|
||||
to.setContentEncoding(from.getFirstHeaderOrNull(HttpHeaders.CONTENT_ENCODING));
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.blob.handlers;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
|
||||
|
@ -72,7 +74,7 @@ public class AzureBlobClientErrorRetryHandler implements HttpRetryHandler {
|
|||
} else if (response.getStatusCode() == 409) {
|
||||
try {
|
||||
AzureStorageError error = utils.parseAzureStorageErrorFromContent(command, response,
|
||||
new String(content));
|
||||
new ByteArrayInputStream(content));
|
||||
if ("ContainerBeingDeleted".equals(error.getCode())) {
|
||||
backoffHandler.imposeBackoffExponentialDelay(100L, 3, command.getFailureCount(),
|
||||
command.toString());
|
||||
|
|
|
@ -26,8 +26,8 @@ import javax.inject.Inject;
|
|||
|
||||
import org.jclouds.azure.storage.blob.domain.ListableContainerProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.ListableContainerPropertiesImpl;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedTreeSet;
|
||||
import org.jclouds.azure.storage.domain.BoundedSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedHashSet;
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
|
||||
|
@ -42,7 +42,7 @@ import com.google.common.collect.Sets;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class AccountNameEnumerationResultsHandler extends
|
||||
ParseSax.HandlerWithResult<BoundedSortedSet<ListableContainerProperties>> {
|
||||
ParseSax.HandlerWithResult<BoundedSet<ListableContainerProperties>> {
|
||||
|
||||
private SortedSet<ListableContainerProperties> containerMetadata = Sets.newTreeSet();
|
||||
private String prefix;
|
||||
|
@ -62,8 +62,8 @@ public class AccountNameEnumerationResultsHandler extends
|
|||
this.dateParser = dateParser;
|
||||
}
|
||||
|
||||
public BoundedSortedSet<ListableContainerProperties> getResult() {
|
||||
return new BoundedTreeSet<ListableContainerProperties>(containerMetadata, currentUrl, prefix,
|
||||
public BoundedSet<ListableContainerProperties> getResult() {
|
||||
return new BoundedHashSet<ListableContainerProperties>(containerMetadata, currentUrl, prefix,
|
||||
marker, maxResults, nextMarker);
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ public class AccountNameEnumerationResultsHandler extends
|
|||
currentETag = null;
|
||||
} else if (qName.equals("Url")) {
|
||||
currentUrl = URI.create(currentText.toString().trim());
|
||||
} else if (qName.equals("LastModified")) {
|
||||
} else if (qName.equals("Last-Modified")) {
|
||||
currentLastModified = dateParser.rfc822DateParse(currentText.toString().trim());
|
||||
} else if (qName.equals("Etag")) {
|
||||
currentETag = currentText.toString().trim();
|
||||
|
|
|
@ -20,20 +20,24 @@ package org.jclouds.azure.storage.blob.xml;
|
|||
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
import java.util.SortedSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.BlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobType;
|
||||
import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
|
||||
import org.jclouds.azure.storage.blob.domain.ListableBlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.ListableBlobPropertiesImpl;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.TreeSetListBlobsResponse;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.BlobPropertiesImpl;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.HashSetListBlobsResponse;
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
|
@ -46,8 +50,7 @@ import com.google.common.collect.Sets;
|
|||
*/
|
||||
public class ContainerNameEnumerationResultsHandler extends
|
||||
ParseSax.HandlerWithResult<ListBlobsResponse> {
|
||||
|
||||
private SortedSet<ListableBlobProperties> blobMetadata = Sets.newTreeSet();
|
||||
private Set<BlobProperties> blobMetadata = Sets.newLinkedHashSet();
|
||||
private String prefix;
|
||||
private String marker;
|
||||
private int maxResults;
|
||||
|
@ -59,6 +62,7 @@ public class ContainerNameEnumerationResultsHandler extends
|
|||
|
||||
private StringBuilder currentText = new StringBuilder();
|
||||
|
||||
private final EncryptionService encryptionService;
|
||||
private final DateService dateParser;
|
||||
private String delimiter;
|
||||
private String currentName;
|
||||
|
@ -66,17 +70,23 @@ public class ContainerNameEnumerationResultsHandler extends
|
|||
private String currentContentType;
|
||||
private String currentContentEncoding;
|
||||
private String currentContentLanguage;
|
||||
private BlobType currentBlobType;
|
||||
private boolean inBlob;
|
||||
private boolean inBlobPrefix;
|
||||
private SortedSet<String> blobPrefixes = Sets.newTreeSet();
|
||||
private boolean inBlobMetadata;
|
||||
private Set<String> blobPrefixes = Sets.newHashSet();
|
||||
private byte[] currentContentMD5;
|
||||
private Map<String, String> currentMetadata = Maps.newHashMap();
|
||||
|
||||
@Inject
|
||||
public ContainerNameEnumerationResultsHandler(DateService dateParser) {
|
||||
public ContainerNameEnumerationResultsHandler(EncryptionService encryptionService,
|
||||
DateService dateParser) {
|
||||
this.encryptionService = encryptionService;
|
||||
this.dateParser = dateParser;
|
||||
}
|
||||
|
||||
public ListBlobsResponse getResult() {
|
||||
return new TreeSetListBlobsResponse(blobMetadata, containerUrl, prefix, marker, maxResults,
|
||||
return new HashSetListBlobsResponse(blobMetadata, containerUrl, prefix, marker, maxResults,
|
||||
nextMarker, delimiter, blobPrefixes);
|
||||
}
|
||||
|
||||
|
@ -89,14 +99,22 @@ public class ContainerNameEnumerationResultsHandler extends
|
|||
} else if (qName.equals("BlobPrefix")) {
|
||||
inBlob = false;
|
||||
inBlobPrefix = true;
|
||||
} else if (qName.equals("Metadata")) {
|
||||
inBlob = true;
|
||||
inBlobMetadata = true;
|
||||
} else if (qName.equals("EnumerationResults")) {
|
||||
containerUrl = URI.create(attributes.getValue("ContainerName").toString().trim());
|
||||
}
|
||||
}
|
||||
|
||||
public void endElement(String uri, String name, String qName) {
|
||||
if (inBlobMetadata && !qName.equals("Metadata")) {
|
||||
currentMetadata.put(qName, currentText.toString().trim());
|
||||
}
|
||||
if (qName.equals("MaxResults")) {
|
||||
maxResults = Integer.parseInt(currentText.toString().trim());
|
||||
} else if (qName.equals("Metadata")) {
|
||||
inBlobMetadata = false;
|
||||
} else if (qName.equals("Marker")) {
|
||||
marker = currentText.toString().trim();
|
||||
marker = (marker.equals("")) ? null : marker;
|
||||
|
@ -109,11 +127,15 @@ public class ContainerNameEnumerationResultsHandler extends
|
|||
} else if (qName.equals("NextMarker")) {
|
||||
nextMarker = currentText.toString().trim();
|
||||
nextMarker = (nextMarker.equals("")) ? null : nextMarker;
|
||||
} else if (qName.equals("BlobType")) {
|
||||
currentBlobType = BlobType.fromValue(currentText.toString().trim());
|
||||
} else if (qName.equals("Blob")) {
|
||||
ListableBlobProperties md = new ListableBlobPropertiesImpl(currentName, currentUrl,
|
||||
BlobProperties md = new BlobPropertiesImpl(currentBlobType, currentName, currentUrl,
|
||||
currentLastModified, currentETag, currentSize, currentContentType,
|
||||
currentContentEncoding, currentContentLanguage);
|
||||
currentContentMD5, currentContentEncoding, currentContentLanguage,
|
||||
currentMetadata);
|
||||
blobMetadata.add(md);
|
||||
currentBlobType = null;
|
||||
currentName = null;
|
||||
currentUrl = null;
|
||||
currentLastModified = null;
|
||||
|
@ -122,9 +144,11 @@ public class ContainerNameEnumerationResultsHandler extends
|
|||
currentContentType = null;
|
||||
currentContentEncoding = null;
|
||||
currentContentLanguage = null;
|
||||
currentContentMD5 = null;
|
||||
currentMetadata = Maps.newHashMap();
|
||||
} else if (qName.equals("Url")) {
|
||||
currentUrl = HttpUtils.createUri(currentText.toString().trim());
|
||||
} else if (qName.equals("LastModified")) {
|
||||
} else if (qName.equals("Last-Modified")) {
|
||||
currentLastModified = dateParser.rfc822DateParse(currentText.toString().trim());
|
||||
} else if (qName.equals("Etag")) {
|
||||
currentETag = currentText.toString().trim();
|
||||
|
@ -133,15 +157,17 @@ public class ContainerNameEnumerationResultsHandler extends
|
|||
currentName = currentText.toString().trim();
|
||||
else if (inBlobPrefix)
|
||||
blobPrefixes.add(currentText.toString().trim());
|
||||
} else if (qName.equals("Size")) {
|
||||
} else if (qName.equals("Content-Length")) {
|
||||
currentSize = Long.parseLong(currentText.toString().trim());
|
||||
} else if (qName.equals("ContentType")) {
|
||||
} else if (qName.equals("Content-MD5")) {
|
||||
currentContentMD5 = encryptionService.fromBase64String(currentText.toString().trim());
|
||||
} else if (qName.equals("Content-Type")) {
|
||||
currentContentType = currentText.toString().trim();
|
||||
} else if (qName.equals("ContentEncoding")) {
|
||||
} else if (qName.equals("Content-Encoding")) {
|
||||
currentContentEncoding = currentText.toString().trim();
|
||||
if (currentContentEncoding.equals(""))
|
||||
currentContentEncoding = null;
|
||||
} else if (qName.equals("ContentLanguage")) {
|
||||
} else if (qName.equals("Content-Language")) {
|
||||
currentContentLanguage = currentText.toString().trim();
|
||||
if (currentContentLanguage.equals(""))
|
||||
currentContentLanguage = null;
|
||||
|
|
|
@ -19,14 +19,14 @@
|
|||
package org.jclouds.azure.storage.domain;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.SortedSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public interface BoundedSortedSet<T> extends SortedSet<T> {
|
||||
public interface BoundedSet<T> extends Set<T> {
|
||||
URI getUrl();
|
||||
|
||||
String getPrefix();
|
|
@ -19,9 +19,9 @@
|
|||
package org.jclouds.azure.storage.domain.internal;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.TreeSet;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.BoundedSet;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
|
@ -30,7 +30,7 @@ import com.google.common.collect.Iterables;
|
|||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public class BoundedTreeSet<T> extends TreeSet<T> implements BoundedSortedSet<T> {
|
||||
public class BoundedHashSet<T> extends HashSet<T> implements BoundedSet<T> {
|
||||
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -7133632087734650835L;
|
||||
|
@ -40,7 +40,7 @@ public class BoundedTreeSet<T> extends TreeSet<T> implements BoundedSortedSet<T>
|
|||
protected final Integer maxResults;
|
||||
protected final String nextMarker;
|
||||
|
||||
public BoundedTreeSet(Iterable<T> contents, URI url, String prefix, String marker,
|
||||
public BoundedHashSet(Iterable<T> contents, URI url, String prefix, String marker,
|
||||
Integer maxResults, String nextMarker) {
|
||||
Iterables.addAll(this, contents);
|
||||
this.url = url;
|
|
@ -54,7 +54,7 @@ import com.google.common.annotations.VisibleForTesting;
|
|||
*
|
||||
*/
|
||||
@Singleton
|
||||
public class SharedKeyAuthentication implements HttpRequestFilter {
|
||||
public class SharedKeyLiteAuthentication implements HttpRequestFilter {
|
||||
private final String[] firstHeadersToSign = new String[] { "Content-MD5",
|
||||
HttpHeaders.CONTENT_TYPE, HttpHeaders.DATE };
|
||||
|
||||
|
@ -68,7 +68,7 @@ public class SharedKeyAuthentication implements HttpRequestFilter {
|
|||
Logger signatureLog = Logger.NULL;
|
||||
|
||||
@Inject
|
||||
public SharedKeyAuthentication(SignatureWire signatureWire,
|
||||
public SharedKeyLiteAuthentication(SignatureWire signatureWire,
|
||||
@Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT) String account,
|
||||
@Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY) String encodedKey,
|
||||
@TimeStamp Provider<String> timeStampProvider, EncryptionService encryptionService) {
|
||||
|
@ -105,7 +105,7 @@ public class SharedKeyAuthentication implements HttpRequestFilter {
|
|||
if (signatureWire.enabled())
|
||||
signatureWire.input(Utils.toInputStream(signature));
|
||||
request.getHeaders().replaceValues(HttpHeaders.AUTHORIZATION,
|
||||
Collections.singletonList("SharedKey " + account + ":" + signature));
|
||||
Collections.singletonList("SharedKeyLite " + account + ":" + signature));
|
||||
}
|
||||
|
||||
public String signString(String toSign) {
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.handlers;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
@ -30,9 +32,10 @@ import org.jclouds.http.HttpErrorHandler;
|
|||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.util.Utils;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.io.Closeables;
|
||||
|
||||
/**
|
||||
* This will parse and set an appropriate exception on the command object.
|
||||
|
@ -53,15 +56,16 @@ public class ParseAzureStorageErrorFromXmlContent implements HttpErrorHandler {
|
|||
}
|
||||
|
||||
public void handleError(HttpCommand command, HttpResponse response) {
|
||||
String content;
|
||||
byte[] content;
|
||||
try {
|
||||
content = response.getContent() != null ? Utils.toStringAndClose(response.getContent())
|
||||
content = response.getContent() != null ? ByteStreams.toByteArray(response.getContent())
|
||||
: null;
|
||||
if (content != null) {
|
||||
String message = new String(content);
|
||||
try {
|
||||
if (content.indexOf('<') >= 0) {
|
||||
if (message.indexOf('<') >= 0) {
|
||||
AzureStorageError error = utils.parseAzureStorageErrorFromContent(command,
|
||||
response, content);
|
||||
response, new ByteArrayInputStream(content));
|
||||
AzureStorageResponseException ex = new AzureStorageResponseException(command,
|
||||
response, error);
|
||||
if (error.getCode().equals("ContainerNotFound")) {
|
||||
|
@ -70,10 +74,10 @@ public class ParseAzureStorageErrorFromXmlContent implements HttpErrorHandler {
|
|||
command.setException(ex);
|
||||
}
|
||||
} else {
|
||||
command.setException(new HttpResponseException(command, response, content));
|
||||
command.setException(new HttpResponseException(command, response, message));
|
||||
}
|
||||
} catch (Exception he) {
|
||||
command.setException(new HttpResponseException(command, response, content));
|
||||
command.setException(new HttpResponseException(command, response, message));
|
||||
Throwables.propagateIfPossible(he);
|
||||
}
|
||||
} else {
|
||||
|
@ -82,7 +86,8 @@ public class ParseAzureStorageErrorFromXmlContent implements HttpErrorHandler {
|
|||
} catch (Exception e) {
|
||||
command.setException(new HttpResponseException(command, response));
|
||||
Throwables.propagateIfPossible(e);
|
||||
} finally {
|
||||
Closeables.closeQuietly(response.getContent());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -22,18 +22,22 @@ import java.util.concurrent.ExecutionException;
|
|||
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
|
||||
import org.jclouds.azure.storage.AzureQueue;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
|
||||
import org.jclouds.azure.storage.domain.BoundedSet;
|
||||
import org.jclouds.azure.storage.filters.SharedKeyLiteAuthentication;
|
||||
import org.jclouds.azure.storage.options.CreateOptions;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.azure.storage.queue.binders.BindToXmlStringPayload;
|
||||
import org.jclouds.azure.storage.queue.domain.QueueMetadata;
|
||||
import org.jclouds.azure.storage.queue.options.PutMessageOptions;
|
||||
import org.jclouds.azure.storage.queue.xml.AccountNameEnumerationResultsHandler;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.Endpoint;
|
||||
import org.jclouds.rest.annotations.Headers;
|
||||
import org.jclouds.rest.annotations.QueryParams;
|
||||
|
@ -64,8 +68,8 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@SkipEncoding('/')
|
||||
@RequestFilters(SharedKeyAuthentication.class)
|
||||
@Headers(keys = AzureStorageHeaders.VERSION, values = "2009-07-17")
|
||||
@RequestFilters(SharedKeyLiteAuthentication.class)
|
||||
@Headers(keys = AzureStorageHeaders.VERSION, values = "2009-09-19")
|
||||
@Endpoint(AzureQueue.class)
|
||||
public interface AzureQueueAsyncClient {
|
||||
|
||||
|
@ -76,15 +80,13 @@ public interface AzureQueueAsyncClient {
|
|||
@XMLResponseParser(AccountNameEnumerationResultsHandler.class)
|
||||
@Path("/")
|
||||
@QueryParams(keys = "comp", values = "list")
|
||||
ListenableFuture<? extends BoundedSortedSet<QueueMetadata>> listQueues(
|
||||
ListOptions... listOptions);
|
||||
ListenableFuture<? extends BoundedSet<QueueMetadata>> listQueues(ListOptions... listOptions);
|
||||
|
||||
/**
|
||||
* @see AzureQueueClient#createQueue
|
||||
*/
|
||||
@PUT
|
||||
@Path("{queue}")
|
||||
@QueryParams(keys = "restype", values = "queue")
|
||||
ListenableFuture<Boolean> createQueue(@PathParam("queue") String queue, CreateOptions... options);
|
||||
|
||||
/**
|
||||
|
@ -92,7 +94,20 @@ public interface AzureQueueAsyncClient {
|
|||
*/
|
||||
@DELETE
|
||||
@Path("{queue}")
|
||||
@QueryParams(keys = "restype", values = "queue")
|
||||
ListenableFuture<Boolean> deleteQueue(@PathParam("queue") String queue);
|
||||
ListenableFuture<Void> deleteQueue(@PathParam("queue") String queue);
|
||||
|
||||
/**
|
||||
* @see AzureQueueClient#putMessage
|
||||
*/
|
||||
@POST
|
||||
@Path("{queue}/messages")
|
||||
ListenableFuture<Void> putMessage(@PathParam("queue") String queue,
|
||||
@BinderParam(BindToXmlStringPayload.class) String message, PutMessageOptions... options);
|
||||
|
||||
/**
|
||||
* @see AzureQueueClient#clearMessages
|
||||
*/
|
||||
@DELETE
|
||||
@Path("{queue}/messages")
|
||||
ListenableFuture<Void> clearMessages(@PathParam("queue") String queue);
|
||||
}
|
||||
|
|
|
@ -21,12 +21,11 @@ package org.jclouds.azure.storage.queue;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.ws.rs.PathParam;
|
||||
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.BoundedSet;
|
||||
import org.jclouds.azure.storage.options.CreateOptions;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.azure.storage.queue.domain.QueueMetadata;
|
||||
import org.jclouds.azure.storage.queue.options.PutMessageOptions;
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
@ -64,7 +63,7 @@ public interface AzureQueueClient {
|
|||
* controls the number or type of results requested
|
||||
* @see ListOptions
|
||||
*/
|
||||
BoundedSortedSet<QueueMetadata> listQueues(ListOptions... listOptions);
|
||||
BoundedSet<QueueMetadata> listQueues(ListOptions... listOptions);
|
||||
|
||||
/**
|
||||
* The Create Queue operation creates a new queue under the specified account.
|
||||
|
@ -83,7 +82,7 @@ public interface AzureQueueClient {
|
|||
* @see CreateQueueOptions
|
||||
*
|
||||
*/
|
||||
boolean createQueue(@PathParam("queue") String queue, CreateOptions... options);
|
||||
boolean createQueue(String queue, CreateOptions... options);
|
||||
|
||||
/**
|
||||
* The Delete Queue operation permanently deletes the specified queue.
|
||||
|
@ -94,6 +93,34 @@ public interface AzureQueueClient {
|
|||
* collection.
|
||||
*
|
||||
*/
|
||||
boolean deleteQueue(@PathParam("queue") String queue);
|
||||
void deleteQueue(String queue);
|
||||
|
||||
/**
|
||||
* The Put Message operation adds a new message to the back of the message queue. A message may
|
||||
* be up to 8 KB in size and must be in a format that can be included in an XML request with
|
||||
* UTF-8 encoding.
|
||||
*
|
||||
* <p/>
|
||||
*
|
||||
* The message time-to-live specifies how long a message will remain in the queue, from the time
|
||||
* it is added to the time it is retrieved and deleted. If a message is not retrieved before the
|
||||
* time-to-live interval expires, the message is removed from the queue.
|
||||
*
|
||||
* If the message is too large, the service returns status code 400 (Bad Request).
|
||||
*
|
||||
*/
|
||||
void putMessage(String queue, String message, PutMessageOptions... options);
|
||||
|
||||
/**
|
||||
* The Clear Messages operation deletes all messages from the specified queue.
|
||||
*
|
||||
* <p/>
|
||||
* If a queue contains a large number of messages, Clear Messages may time out before all
|
||||
* messages have been deleted. In this case the Queue service will return status code 500
|
||||
* (Internal Server Error), with the additional error code OperationTimedOut. If the operation
|
||||
* times out, the client should continue to retry Clear Messages until it succeeds, to ensure
|
||||
* that all messages have been deleted.
|
||||
*/
|
||||
@Timeout(duration = 10, timeUnit = TimeUnit.MINUTES)
|
||||
void clearMessages(String queue);
|
||||
}
|
||||
|
|
|
@ -41,20 +41,26 @@ import com.google.inject.Module;
|
|||
*/
|
||||
public class AzureQueueContextFactory {
|
||||
|
||||
public static RestContext<AzureQueueAsyncClient, AzureQueueClient> createContext(Properties properties,
|
||||
Module... modules) {
|
||||
public static RestContext<AzureQueueAsyncClient, AzureQueueClient> createContext(
|
||||
Properties properties, Module... modules) {
|
||||
return new AzureQueueContextBuilder(new AzureQueuePropertiesBuilder(properties).build())
|
||||
.withModules(modules).buildContext();
|
||||
}
|
||||
|
||||
public static RestContext<AzureQueueAsyncClient, AzureQueueClient> createContext(String account, String encodedKey,
|
||||
Module... modules) {
|
||||
public static RestContext<AzureQueueAsyncClient, AzureQueueClient> createContext(
|
||||
Properties properties, String account, String encodedKey, Module... modules) {
|
||||
return new AzureQueueContextBuilder(new AzureQueuePropertiesBuilder(properties)
|
||||
.withCredentials(account, encodedKey).build()).withModules(modules).buildContext();
|
||||
}
|
||||
|
||||
public static RestContext<AzureQueueAsyncClient, AzureQueueClient> createContext(String account,
|
||||
String encodedKey, Module... modules) {
|
||||
return new AzureQueueContextBuilder(new AzureQueuePropertiesBuilder(account, encodedKey)
|
||||
.build()).withModules(modules).buildContext();
|
||||
}
|
||||
|
||||
public static RestContext<AzureQueueAsyncClient, AzureQueueClient> createContext(URI endpoint, String account,
|
||||
String encodedKey, Module... modules) {
|
||||
public static RestContext<AzureQueueAsyncClient, AzureQueueClient> createContext(URI endpoint,
|
||||
String account, String encodedKey, Module... modules) {
|
||||
return new AzureQueueContextBuilder(new AzureQueuePropertiesBuilder(account, encodedKey)
|
||||
.withEndpoint(endpoint).build()).withModules(modules).buildContext();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 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.azure.storage.queue.binders;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.binders.BindToStringPayload;
|
||||
|
||||
/**
|
||||
* Adds an payload to a request.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class BindToXmlStringPayload extends BindToStringPayload {
|
||||
public void bindToRequest(HttpRequest request, Object payload) {
|
||||
super.bindToRequest(request, new StringBuilder().append("<QueueMessage><MessageText>")
|
||||
.append(payload).append("</MessageText></QueueMessage>").toString());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 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.azure.storage.queue.options;
|
||||
|
||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||
|
||||
/**
|
||||
* Contains options supported in the REST API for the Create Container operation. <h2>
|
||||
* Usage</h2> The recommended way to instantiate a PutMessageOptions object is to statically
|
||||
* import PutMessageOptions.* and invoke a static creation method followed by an instance
|
||||
* mutator (if needed):
|
||||
* <p/>
|
||||
* <code>
|
||||
* import static org.jclouds.azure.storage.queue.options.PutMessageOptions.Builder.*
|
||||
* import org.jclouds.azure.storage.queue.AzureQueueClient;
|
||||
* <p/>
|
||||
* AzureQueueClient connection = // get connection
|
||||
* connection.putMessage("containerName", withTTL());
|
||||
* <code> *
|
||||
*
|
||||
* @see <a href="http://msdn.microsoft.com/en-us/library/dd179466.aspx" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class PutMessageOptions extends BaseHttpRequestOptions {
|
||||
public static final PutMessageOptions NONE = new PutMessageOptions();
|
||||
|
||||
/**
|
||||
* Specifies the time-to-live interval for the message, in seconds. The maximum time-to-live
|
||||
* allowed is 7 days. If this parameter is omitted, the default time-to-live is 7 days.
|
||||
*/
|
||||
public PutMessageOptions withTTL(int seconds) {
|
||||
this.queryParameters.put("messagettl", seconds + "");
|
||||
return this;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
* @see PutMessageOptions#withTTL
|
||||
*/
|
||||
public static PutMessageOptions withTTL(int seconds) {
|
||||
PutMessageOptions options = new PutMessageOptions();
|
||||
return options.withTTL(seconds);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -19,16 +19,17 @@
|
|||
package org.jclouds.azure.storage.queue.xml;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedTreeSet;
|
||||
import org.jclouds.azure.storage.domain.BoundedSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedHashSet;
|
||||
import org.jclouds.azure.storage.queue.domain.QueueMetadata;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Parses the following XML document:
|
||||
* <p/>
|
||||
|
@ -38,9 +39,9 @@ import org.jclouds.http.functions.ParseSax;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class AccountNameEnumerationResultsHandler extends
|
||||
ParseSax.HandlerWithResult<BoundedSortedSet<QueueMetadata>> {
|
||||
ParseSax.HandlerWithResult<BoundedSet<QueueMetadata>> {
|
||||
|
||||
private SortedSet<QueueMetadata> metadata = new TreeSet<QueueMetadata>();
|
||||
private Set<QueueMetadata> metadata = Sets.newLinkedHashSet();
|
||||
private URI currentUrl;
|
||||
private String prefix;
|
||||
private String marker;
|
||||
|
@ -54,8 +55,8 @@ public class AccountNameEnumerationResultsHandler extends
|
|||
public AccountNameEnumerationResultsHandler() {
|
||||
}
|
||||
|
||||
public BoundedSortedSet<QueueMetadata> getResult() {
|
||||
return new BoundedTreeSet<QueueMetadata>(metadata, currentUrl, prefix, marker, maxResults,
|
||||
public BoundedSet<QueueMetadata> getResult() {
|
||||
return new BoundedHashSet<QueueMetadata>(metadata, currentUrl, prefix, marker, maxResults,
|
||||
nextMarker);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,14 +18,13 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.util;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.azure.storage.domain.AzureStorageError;
|
||||
import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
|
||||
import org.jclouds.azure.storage.filters.SharedKeyLiteAuthentication;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
|
||||
import org.jclouds.azure.storage.xml.ErrorHandler;
|
||||
import org.jclouds.http.HttpCommand;
|
||||
|
@ -42,8 +41,8 @@ import org.jclouds.http.functions.ParseSax;
|
|||
public class AzureStorageUtils {
|
||||
|
||||
@Inject
|
||||
SharedKeyAuthentication signer;
|
||||
|
||||
SharedKeyLiteAuthentication signer;
|
||||
|
||||
@Inject
|
||||
ParseSax.Factory factory;
|
||||
|
||||
|
@ -52,21 +51,13 @@ public class AzureStorageUtils {
|
|||
|
||||
public AzureStorageError parseAzureStorageErrorFromContent(HttpCommand command,
|
||||
HttpResponse response, InputStream content) throws HttpException {
|
||||
AzureStorageError error = (AzureStorageError) factory.create(errorHandlerProvider.get())
|
||||
.parse(content);
|
||||
AzureStorageError error = factory.create(errorHandlerProvider.get()).parse(content);
|
||||
error.setRequestId(response.getFirstHeaderOrNull(AzureStorageHeaders.REQUEST_ID));
|
||||
if ("AuthenticationFailed".equals(error.getCode())) {
|
||||
error.setStringSigned(signer.createStringToSign(command.getRequest()));
|
||||
error.setSignature(signer.signString(error.getStringSigned()));
|
||||
}
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
public AzureStorageError parseAzureStorageErrorFromContent(HttpCommand command,
|
||||
HttpResponse response, String content) throws HttpException {
|
||||
return parseAzureStorageErrorFromContent(command, response, new ByteArrayInputStream(content
|
||||
.getBytes()));
|
||||
}
|
||||
|
||||
}
|
|
@ -69,12 +69,12 @@ import com.google.inject.Key;
|
|||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code AzureBlobClient}
|
||||
* Tests behavior of {@code AzureBlobAsyncClient}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "azureblob.AzureBlobClientTest")
|
||||
public class AzureBlobClientTest {
|
||||
@Test(groups = "unit", testName = "azureblob.AzureBlobAsyncClientTest")
|
||||
public class AzureBlobAsyncClientTest {
|
||||
|
||||
public void testListContainers() throws SecurityException, NoSuchMethodException {
|
||||
Method method = AzureBlobAsyncClient.class.getMethod("listContainers", Array.newInstance(
|
||||
|
@ -88,7 +88,7 @@ public class AzureBlobClientTest {
|
|||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(), ParseSax.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor
|
||||
|
@ -111,7 +111,7 @@ public class AzureBlobClientTest {
|
|||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(), ParseSax.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor
|
||||
|
@ -131,7 +131,7 @@ public class AzureBlobClientTest {
|
|||
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
||||
assertEquals(httpMethod.getHeaders().size(), 2);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(httpMethod.getHeaders().get("Content-Length"), Collections.singletonList("0"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
ReturnTrueIf2xx.class);
|
||||
|
@ -152,7 +152,7 @@ public class AzureBlobClientTest {
|
|||
assertEquals(httpMethod.getMethod(), HttpMethod.DELETE);
|
||||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
ReturnVoidIf2xx.class);
|
||||
// TODO check generic type of response parser
|
||||
|
@ -174,7 +174,7 @@ public class AzureBlobClientTest {
|
|||
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
||||
assertEquals(httpMethod.getHeaders().size(), 4);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-meta-foo"), Collections.singletonList("bar"));
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-prop-publicaccess"), Collections
|
||||
.singletonList("true"));
|
||||
|
@ -199,7 +199,7 @@ public class AzureBlobClientTest {
|
|||
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
||||
assertEquals(httpMethod.getHeaders().size(), 2);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(httpMethod.getHeaders().get("Content-Length"), Collections.singletonList("0"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
ReturnTrueIf2xx.class);
|
||||
|
@ -220,9 +220,9 @@ public class AzureBlobClientTest {
|
|||
assertEquals(httpMethod.getMethod(), HttpMethod.DELETE);
|
||||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
ReturnTrueIf2xx.class);
|
||||
ReturnVoidIf2xx.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor
|
||||
.createExceptionParserOrThrowResourceNotFoundOn404IfNoAnnotation(method).getClass(),
|
||||
|
@ -241,7 +241,7 @@ public class AzureBlobClientTest {
|
|||
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
||||
assertEquals(httpMethod.getHeaders().size(), 4);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-meta-foo"), Collections.singletonList("bar"));
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-prop-publicaccess"), Collections
|
||||
.singletonList("true"));
|
||||
|
@ -266,7 +266,7 @@ public class AzureBlobClientTest {
|
|||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(), ParseSax.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor
|
||||
|
@ -286,7 +286,7 @@ public class AzureBlobClientTest {
|
|||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(), ParseSax.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor
|
||||
|
@ -305,7 +305,7 @@ public class AzureBlobClientTest {
|
|||
assertEquals(httpMethod.getMethod(), HttpMethod.HEAD);
|
||||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
ParseContainerPropertiesFromHeaders.class);
|
||||
assertEquals(processor
|
||||
|
@ -327,7 +327,7 @@ public class AzureBlobClientTest {
|
|||
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||
.singletonList("0"));
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-meta-key"), Collections.singletonList("value"));
|
||||
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
|
@ -348,7 +348,7 @@ public class AzureBlobClientTest {
|
|||
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
||||
assertEquals(httpMethod.getHeaders().size(), 3);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||
.singletonList("0"));
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-meta-key"), Collections.singletonList("value"));
|
|
@ -26,7 +26,7 @@ import java.lang.reflect.UndeclaredThrowableException;
|
|||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.SortedSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.azure.storage.AzureStorageResponseException;
|
||||
import org.jclouds.azure.storage.blob.domain.AzureBlob;
|
||||
|
@ -34,8 +34,9 @@ import org.jclouds.azure.storage.blob.domain.BlobProperties;
|
|||
import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
|
||||
import org.jclouds.azure.storage.blob.domain.ListableContainerProperties;
|
||||
import org.jclouds.azure.storage.blob.options.CreateContainerOptions;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.BoundedSet;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
import org.jclouds.encryption.internal.JCEEncryptionService;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
|
@ -46,6 +47,7 @@ import org.testng.annotations.BeforeGroups;
|
|||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.inject.internal.Iterables;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code AzureBlobClient}
|
||||
|
@ -70,8 +72,7 @@ public class AzureBlobClientLiveTest {
|
|||
|
||||
@Test
|
||||
public void testListContainers() throws Exception {
|
||||
|
||||
SortedSet<ListableContainerProperties> response = connection.listContainers();
|
||||
Set<ListableContainerProperties> response = connection.listContainers();
|
||||
assert null != response;
|
||||
long initialContainerCount = response.size();
|
||||
assertTrue(initialContainerCount >= 0);
|
||||
|
@ -97,7 +98,7 @@ public class AzureBlobClientLiveTest {
|
|||
throw e;
|
||||
}
|
||||
}
|
||||
SortedSet<ListableContainerProperties> response = connection.listContainers();
|
||||
Set<ListableContainerProperties> response = connection.listContainers();
|
||||
assert null != response;
|
||||
long containerCount = response.size();
|
||||
assertTrue(containerCount >= 1);
|
||||
|
@ -132,9 +133,16 @@ public class AzureBlobClientLiveTest {
|
|||
public void testCreatePublicRootContainer() throws Exception {
|
||||
try {
|
||||
connection.deleteRootContainer();
|
||||
} catch (AzureStorageResponseException e) {
|
||||
sleepIfWaitingForDeleteToFinish(e);
|
||||
} catch (ContainerNotFoundException e) {
|
||||
Thread.sleep(5000);
|
||||
} catch (AzureStorageResponseException htpe) {
|
||||
if (htpe.getResponse().getStatusCode() == 409) {// TODO look for specific message
|
||||
Thread.sleep(5000);
|
||||
} else {
|
||||
throw htpe;
|
||||
}
|
||||
}
|
||||
|
||||
boolean created = false;
|
||||
while (!created) {
|
||||
try {
|
||||
|
@ -153,18 +161,10 @@ public class AzureBlobClientLiveTest {
|
|||
"https://%s.blob.core.windows.net/%%24root", account)));
|
||||
}
|
||||
|
||||
private void sleepIfWaitingForDeleteToFinish(AzureStorageResponseException e)
|
||||
throws InterruptedException {
|
||||
if (e.getResponse().getStatusCode() == 409) {
|
||||
Thread.sleep(5000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListContainersWithOptions() throws Exception {
|
||||
|
||||
BoundedSortedSet<ListableContainerProperties> response = connection
|
||||
BoundedSet<ListableContainerProperties> response = connection
|
||||
.listContainers(ListOptions.Builder.prefix(privateContainer).maxResults(1));
|
||||
assert null != response;
|
||||
long initialContainerCount = response.size();
|
||||
|
@ -175,7 +175,7 @@ public class AzureBlobClientLiveTest {
|
|||
|
||||
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "testCreatePublicRootContainer" })
|
||||
public void testDeleteRootContainer() throws Exception {
|
||||
assert connection.deleteRootContainer();
|
||||
connection.deleteRootContainer();
|
||||
// TODO loop for up to 30 seconds checking if they are really gone
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ public class AzureBlobClientLiveTest {
|
|||
public void testListOwnedContainers() throws Exception {
|
||||
|
||||
// Test default listing
|
||||
SortedSet<ListableContainerProperties> response = connection.listContainers();
|
||||
Set<ListableContainerProperties> response = connection.listContainers();
|
||||
// assertEquals(response.size(), initialContainerCount + 2);// if the containers already
|
||||
// exist, this will fail
|
||||
|
||||
|
@ -192,12 +192,12 @@ public class AzureBlobClientLiveTest {
|
|||
response = connection.listContainers(ListOptions.Builder.prefix(
|
||||
privateContainer.substring(0, privateContainer.length() - 1)).maxResults(1));
|
||||
assertEquals(response.size(), 1);
|
||||
assertEquals(response.first().getName(), privateContainer);
|
||||
assertEquals(Iterables.getOnlyElement(response).getName(), privateContainer);
|
||||
|
||||
response = connection.listContainers(ListOptions.Builder.prefix(publicContainer)
|
||||
.maxResults(1));
|
||||
assertEquals(response.size(), 1);
|
||||
assertEquals(response.first().getName(), publicContainer);
|
||||
assertEquals(Iterables.getOnlyElement(response).getName(), publicContainer);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -30,5 +30,4 @@ import org.testng.annotations.Test;
|
|||
@Test(groups = { "integration", "live" }, testName = "azureblob.AzureBlobIntegrationTest")
|
||||
public class AzureBlobIntegrationTest extends
|
||||
BaseBlobIntegrationTest<AzureBlobAsyncClient, AzureBlobClient> {
|
||||
|
||||
}
|
|
@ -42,8 +42,8 @@ import org.jclouds.azure.storage.blob.domain.ListableContainerProperties;
|
|||
import org.jclouds.azure.storage.blob.domain.internal.ListableContainerPropertiesImpl;
|
||||
import org.jclouds.azure.storage.blob.options.CreateContainerOptions;
|
||||
import org.jclouds.azure.storage.blob.options.ListBlobsOptions;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedTreeSet;
|
||||
import org.jclouds.azure.storage.domain.BoundedSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedHashSet;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.blobstore.attr.ConsistencyModel;
|
||||
import org.jclouds.blobstore.attr.ConsistencyModels;
|
||||
|
@ -112,7 +112,7 @@ public class StubAzureBlobAsyncClient implements AzureBlobAsyncClient {
|
|||
return immediateFuture(null);
|
||||
}
|
||||
|
||||
public ListenableFuture<Boolean> deleteRootContainer() {
|
||||
public ListenableFuture<Void> deleteRootContainer() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
@ -149,9 +149,9 @@ public class StubAzureBlobAsyncClient implements AzureBlobAsyncClient {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public ListenableFuture<? extends BoundedSortedSet<ListableContainerProperties>> listContainers(
|
||||
public ListenableFuture<? extends BoundedSet<ListableContainerProperties>> listContainers(
|
||||
ListOptions... listOptions) {
|
||||
return immediateFuture(new BoundedTreeSet<ListableContainerProperties>(Iterables.transform(
|
||||
return immediateFuture(new BoundedHashSet<ListableContainerProperties>(Iterables.transform(
|
||||
blobStore.getContainerToBlobs().keySet(),
|
||||
new Function<String, ListableContainerProperties>() {
|
||||
public ListableContainerProperties apply(String name) {
|
||||
|
|
|
@ -26,8 +26,8 @@ import java.util.SortedSet;
|
|||
|
||||
import org.jclouds.azure.storage.blob.domain.ListableContainerProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.ListableContainerPropertiesImpl;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedTreeSet;
|
||||
import org.jclouds.azure.storage.domain.BoundedSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedHashSet;
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
|
@ -65,11 +65,11 @@ public class AccountNameEnumerationResultsHandlerTest extends BaseHandlerTest {
|
|||
contents.add(new ListableContainerPropertiesImpl(URI
|
||||
.create("http://myaccount.blob.core.windows.net/textfiles"), dateService
|
||||
.rfc822DateParse("Wed, 15 Aug 2008 20:39:39 GMT"), "0x8CACB9BD7BACAC3"));
|
||||
BoundedSortedSet<ListableContainerProperties> list = new BoundedTreeSet<ListableContainerProperties>(
|
||||
BoundedSet<ListableContainerProperties> list = new BoundedHashSet<ListableContainerProperties>(
|
||||
contents, URI.create("http://myaccount.blob.core.windows.net/"), null, null, 3,
|
||||
"video");
|
||||
|
||||
BoundedSortedSet<ListableContainerProperties> result = (BoundedSortedSet<ListableContainerProperties>) factory
|
||||
BoundedSet<ListableContainerProperties> result = (BoundedSet<ListableContainerProperties>) factory
|
||||
.create(injector.getInstance(AccountNameEnumerationResultsHandler.class)).parse(is);
|
||||
|
||||
assertEquals(result, list);
|
||||
|
@ -87,10 +87,10 @@ public class AccountNameEnumerationResultsHandlerTest extends BaseHandlerTest {
|
|||
.create("http://myaccount.blob.core.windows.net/textfiles"), dateService
|
||||
.rfc822DateParse("Wed, 15 Aug 2008 20:39:39 GMT"), "0x8CACB9BD7BACAC3"));
|
||||
InputStream is = getClass().getResourceAsStream("/blob/test_list_containers_options.xml");
|
||||
BoundedSortedSet<ListableContainerProperties> list = new BoundedTreeSet<ListableContainerProperties>(
|
||||
BoundedSet<ListableContainerProperties> list = new BoundedHashSet<ListableContainerProperties>(
|
||||
contents, URI.create("http://myaccount.blob.core.windows.net"), "prefix", "marker",
|
||||
1, "video");
|
||||
BoundedSortedSet<ListableContainerProperties> result = (BoundedSortedSet<ListableContainerProperties>) factory
|
||||
BoundedSet<ListableContainerProperties> result = (BoundedSet<ListableContainerProperties>) factory
|
||||
.create(injector.getInstance(AccountNameEnumerationResultsHandler.class)).parse(is);
|
||||
assertEquals(result, list);
|
||||
}
|
||||
|
|
|
@ -22,17 +22,19 @@ import static org.testng.Assert.assertEquals;
|
|||
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.SortedSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.BlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobType;
|
||||
import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
|
||||
import org.jclouds.azure.storage.blob.domain.ListableBlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.ListableBlobPropertiesImpl;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.TreeSetListBlobsResponse;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.BlobPropertiesImpl;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.HashSetListBlobsResponse;
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
|
@ -54,21 +56,22 @@ public class ContainerNameEnumerationResultsHandlerTest extends BaseHandlerTest
|
|||
|
||||
public void testApplyInputStream() {
|
||||
InputStream is = getClass().getResourceAsStream("/blob/test_list_blobs.xml");
|
||||
SortedSet<ListableBlobProperties> contents = Sets.newTreeSet();
|
||||
contents.add(new ListableBlobPropertiesImpl("blob1.txt", URI
|
||||
Set<BlobProperties> contents = Sets.newTreeSet();
|
||||
contents.add(new BlobPropertiesImpl(BlobType.BLOCK_BLOB, "blob1.txt", URI
|
||||
.create("http://myaccount.blob.core.windows.net/mycontainer/blob1.txt"), dateService
|
||||
.rfc822DateParse("Thu, 18 Sep 2008 18:41:57 GMT"), "0x8CAE7D55D050B8B", 8,
|
||||
"text/plain; charset=UTF-8", null, null));
|
||||
contents.add(new ListableBlobPropertiesImpl("blob2.txt", URI
|
||||
"text/plain; charset=UTF-8", null, null, null, ImmutableMap.<String, String> of()));
|
||||
contents.add(new BlobPropertiesImpl(BlobType.BLOCK_BLOB, "blob2.txt", URI
|
||||
.create("http://myaccount.blob.core.windows.net/mycontainer/blob2.txt"), dateService
|
||||
.rfc822DateParse("Thu, 18 Sep 2008 18:41:57 GMT"), "0x8CAE7D55CF6C339", 14,
|
||||
"text/plain; charset=UTF-8", null, null));
|
||||
contents.add(new ListableBlobPropertiesImpl("newblob1.txt", URI
|
||||
"text/plain; charset=UTF-8", null, null, null, ImmutableMap.<String, String> of()));
|
||||
contents.add(new BlobPropertiesImpl(BlobType.PAGE_BLOB, "newblob1.txt", URI
|
||||
.create("http://myaccount.blob.core.windows.net/mycontainer/newblob1.txt"),
|
||||
dateService.rfc822DateParse("Thu, 18 Sep 2008 18:41:57 GMT"), "0x8CAE7D55CF6C339",
|
||||
25, "text/plain; charset=UTF-8", null, null));
|
||||
25, "text/plain; charset=UTF-8", null, null, null, ImmutableMap
|
||||
.<String, String> of()));
|
||||
|
||||
ListBlobsResponse list = new TreeSetListBlobsResponse(contents, URI
|
||||
ListBlobsResponse list = new HashSetListBlobsResponse(contents, URI
|
||||
.create("http://myaccount.blob.core.windows.net/mycontainer"),
|
||||
|
||||
"myfolder/", null, 4, "newblob2.txt", "/", Sets.<String> newTreeSet());
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 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.azure.storage.filters;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.util.concurrent.Executors.sameThreadExecutor;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.jclouds.azure.storage.AzureBlob;
|
||||
import org.jclouds.azure.storage.config.AzureStorageRestClientModule;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.rest.RestClientFactory;
|
||||
import org.jclouds.rest.annotations.Endpoint;
|
||||
import org.jclouds.rest.annotations.QueryParams;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.config.RestModule;
|
||||
import org.jclouds.util.Jsr330;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
/**
|
||||
* Tests behavior of {@code JaxrsAnnotationProcessor}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", testName = "azure.SharedKeyAuthenticationLiveTest")
|
||||
public class SharedKeyAuthenticationLiveTest {
|
||||
|
||||
@RequestFilters(SharedKeyAuthentication.class)
|
||||
@Endpoint(AzureBlob.class)
|
||||
public interface IntegrationTestClient {
|
||||
|
||||
@GET
|
||||
@Path("/")
|
||||
@QueryParams(keys = "comp", values = "list")
|
||||
ListenableFuture<String> authenticate();
|
||||
|
||||
}
|
||||
|
||||
private Injector injector;
|
||||
private IntegrationTestClient client;
|
||||
private String uri;
|
||||
|
||||
@Test
|
||||
public void testAuthentication() throws Exception {
|
||||
String response = client.authenticate().get(10, TimeUnit.SECONDS);
|
||||
assertTrue(response.contains(uri), String.format("expected %s to contain %s", response, uri));
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
void setupFactory() {
|
||||
final String account = checkNotNull(System.getProperty("jclouds.test.user"),
|
||||
"jclouds.test.user");
|
||||
final String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||
uri = "http://" + account + ".blob.core.windows.net";
|
||||
injector = Guice.createInjector(
|
||||
new AbstractModule() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(URI.class).annotatedWith(AzureBlob.class).toInstance(URI.create(uri));
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT))
|
||||
.to(account);
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY))
|
||||
.to(key);
|
||||
bindConstant()
|
||||
.annotatedWith(
|
||||
Jsr330
|
||||
.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_SESSIONINTERVAL))
|
||||
.to(1l);
|
||||
}
|
||||
|
||||
}, new AzureStorageRestClientModule(), new RestModule(), new Log4JLoggingModule(),
|
||||
new ExecutorServiceModule(sameThreadExecutor()),
|
||||
new JavaUrlHttpCommandExecutorServiceModule());
|
||||
RestClientFactory factory = injector.getInstance(RestClientFactory.class);
|
||||
client = factory.create(IntegrationTestClient.class);
|
||||
}
|
||||
}
|
|
@ -42,13 +42,17 @@ import com.google.inject.AbstractModule;
|
|||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
@Test(groups = "unit", testName = "azurestorage.SharedKeyAuthenticationTest")
|
||||
public class SharedKeyAuthenticationTest {
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "azurestorage.SharedKeyLiteAuthenticationTest")
|
||||
public class SharedKeyLiteAuthenticationTest {
|
||||
|
||||
private static final String KEY = Base64.encodeBytes("bar".getBytes());
|
||||
private static final String ACCOUNT = "foo";
|
||||
private Injector injector;
|
||||
private SharedKeyAuthentication filter;
|
||||
private SharedKeyLiteAuthentication filter;
|
||||
|
||||
@DataProvider(parallel = true)
|
||||
public Object[][] dataProvider() {
|
||||
|
@ -145,7 +149,7 @@ public class SharedKeyAuthenticationTest {
|
|||
}
|
||||
|
||||
});
|
||||
filter = injector.getInstance(SharedKeyAuthentication.class);
|
||||
filter = injector.getInstance(SharedKeyLiteAuthentication.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -18,51 +18,52 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.queue;
|
||||
|
||||
import static com.google.common.util.concurrent.Executors.sameThreadExecutor;
|
||||
import static org.jclouds.azure.storage.options.CreateOptions.Builder.withMetadata;
|
||||
import static org.jclouds.azure.storage.options.ListOptions.Builder.maxResults;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
|
||||
import org.jclouds.azure.storage.AzureQueue;
|
||||
import org.jclouds.azure.storage.config.AzureStorageRestClientModule;
|
||||
import org.jclouds.azure.storage.filters.SharedKeyLiteAuthentication;
|
||||
import org.jclouds.azure.storage.options.CreateOptions;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.azure.storage.queue.options.PutMessageOptions;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.encryption.internal.Base64;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
||||
import org.jclouds.http.functions.ReturnVoidIf2xx;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.logging.Logger.LoggerFactory;
|
||||
import org.jclouds.rest.config.RestModule;
|
||||
import org.jclouds.rest.RestClientTest;
|
||||
import org.jclouds.rest.functions.ThrowResourceNotFoundOn404;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||
import org.jclouds.util.Jsr330;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code AzureQueueClient}
|
||||
* Tests behavior of {@code AzureQueueAsyncClient}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "cloudservers.AzureQueueClientTest")
|
||||
public class AzureQueueClientTest {
|
||||
@Test(groups = "unit", testName = "azurequeue.AzureQueueAsyncClientTest")
|
||||
public class AzureQueueAsyncClientTest extends RestClientTest<AzureQueueAsyncClient> {
|
||||
private static final Class<? extends ListOptions[]> listOptionsVarargsClass = new ListOptions[] {}
|
||||
.getClass();
|
||||
private static final Class<? extends CreateOptions[]> createOptionsVarargsClass = new CreateOptions[] {}
|
||||
|
@ -79,7 +80,7 @@ public class AzureQueueClientTest {
|
|||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(), ParseSax.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor
|
||||
|
@ -101,7 +102,7 @@ public class AzureQueueClientTest {
|
|||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(), ParseSax.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor
|
||||
|
@ -117,11 +118,11 @@ public class AzureQueueClientTest {
|
|||
new Object[] { "queue" });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/queue");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=queue");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), null);
|
||||
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
||||
assertEquals(httpMethod.getHeaders().size(), 2);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(httpMethod.getHeaders().get("Content-Length"), Collections.singletonList("0"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
ReturnTrueIf2xx.class);
|
||||
|
@ -131,26 +132,6 @@ public class AzureQueueClientTest {
|
|||
ThrowResourceNotFoundOn404.class);
|
||||
}
|
||||
|
||||
public void testDeleteQueue() throws SecurityException, NoSuchMethodException {
|
||||
Method method = AzureQueueAsyncClient.class.getMethod("deleteQueue", String.class);
|
||||
|
||||
GeneratedHttpRequest<AzureQueueAsyncClient> httpMethod = processor.createRequest(method,
|
||||
new Object[] { "queue" });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/queue");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=queue");
|
||||
assertEquals(httpMethod.getMethod(), HttpMethod.DELETE);
|
||||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
ReturnTrueIf2xx.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor
|
||||
.createExceptionParserOrThrowResourceNotFoundOn404IfNoAnnotation(method).getClass(),
|
||||
ThrowResourceNotFoundOn404.class);
|
||||
}
|
||||
|
||||
public void testCreateQueueOptions() throws SecurityException, NoSuchMethodException {
|
||||
Method method = AzureQueueAsyncClient.class.getMethod("createQueue", String.class,
|
||||
createOptionsVarargsClass);
|
||||
|
@ -159,11 +140,11 @@ public class AzureQueueClientTest {
|
|||
new Object[] { "queue", withMetadata(ImmutableMultimap.of("foo", "bar")) });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/queue");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=queue");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), null);
|
||||
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
||||
assertEquals(httpMethod.getHeaders().size(), 3);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-meta-foo"), Collections.singletonList("bar"));
|
||||
assertEquals(httpMethod.getHeaders().get("Content-Length"), Collections.singletonList("0"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
|
@ -174,9 +155,96 @@ public class AzureQueueClientTest {
|
|||
ThrowResourceNotFoundOn404.class);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
void setupFactory() {
|
||||
Injector injector = Guice.createInjector(new AbstractModule() {
|
||||
public void testDeleteQueue() throws SecurityException, NoSuchMethodException {
|
||||
Method method = AzureQueueAsyncClient.class.getMethod("deleteQueue", String.class);
|
||||
|
||||
GeneratedHttpRequest<AzureQueueAsyncClient> httpMethod = processor.createRequest(method,
|
||||
new Object[] { "queue" });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/queue");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), null);
|
||||
assertEquals(httpMethod.getMethod(), HttpMethod.DELETE);
|
||||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-09-19"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
ReturnVoidIf2xx.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor
|
||||
.createExceptionParserOrThrowResourceNotFoundOn404IfNoAnnotation(method).getClass(),
|
||||
ThrowResourceNotFoundOn404.class);
|
||||
}
|
||||
|
||||
public void testPutMessage() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = AzureQueueAsyncClient.class.getMethod("putMessage", String.class,
|
||||
String.class, Array.newInstance(PutMessageOptions.class, 0).getClass());
|
||||
GeneratedHttpRequest<AzureQueueAsyncClient> httpMethod = processor.createRequest(method,
|
||||
"queue", "message");
|
||||
|
||||
assertRequestLineEquals(httpMethod, "POST http://localhost:8080/queue/messages HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod,
|
||||
"Content-Length: 63\nContent-Type: application/unknown\nx-ms-version: 2009-09-19\n");
|
||||
assertPayloadEquals(httpMethod,
|
||||
"<QueueMessage><MessageText>message</MessageText></QueueMessage>");
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
|
||||
assertSaxResponseParserClassEquals(method, null);
|
||||
assertExceptionParserClassEquals(method, null);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
public void testPutMessageOptions() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = AzureQueueAsyncClient.class.getMethod("putMessage", String.class,
|
||||
String.class, Array.newInstance(PutMessageOptions.class, 0).getClass());
|
||||
GeneratedHttpRequest<AzureQueueAsyncClient> httpMethod = processor.createRequest(method,
|
||||
"queue", "message", PutMessageOptions.Builder.withTTL(3));
|
||||
|
||||
assertRequestLineEquals(httpMethod,
|
||||
"POST http://localhost:8080/queue/messages?messagettl=3 HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod,
|
||||
"Content-Length: 63\nContent-Type: application/unknown\nx-ms-version: 2009-09-19\n");
|
||||
assertPayloadEquals(httpMethod,
|
||||
"<QueueMessage><MessageText>message</MessageText></QueueMessage>");
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
|
||||
assertSaxResponseParserClassEquals(method, null);
|
||||
assertExceptionParserClassEquals(method, null);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
public void testClearMessages() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = AzureQueueAsyncClient.class.getMethod("clearMessages", String.class);
|
||||
GeneratedHttpRequest<AzureQueueAsyncClient> httpMethod = processor.createRequest(method,
|
||||
"queue");
|
||||
|
||||
assertRequestLineEquals(httpMethod, "DELETE http://localhost:8080/queue/messages HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod, "x-ms-version: 2009-09-19\n");
|
||||
assertPayloadEquals(httpMethod, null);
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
|
||||
assertSaxResponseParserClassEquals(method, null);
|
||||
assertExceptionParserClassEquals(method, null);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkFilters(GeneratedHttpRequest<AzureQueueAsyncClient> httpMethod) {
|
||||
assertEquals(httpMethod.getFilters().size(), 1);
|
||||
assertEquals(httpMethod.getFilters().get(0).getClass(), SharedKeyLiteAuthentication.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TypeLiteral<RestAnnotationProcessor<AzureQueueAsyncClient>> createTypeLiteral() {
|
||||
return new TypeLiteral<RestAnnotationProcessor<AzureQueueAsyncClient>>() {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Module createModule() {
|
||||
return new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(URI.class).annotatedWith(AzureQueue.class).toInstance(
|
||||
|
@ -195,12 +263,14 @@ public class AzureQueueClientTest {
|
|||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_SESSIONINTERVAL)).to(
|
||||
1l);
|
||||
}
|
||||
}, new AzureStorageRestClientModule(), new RestModule(), new ExecutorServiceModule(
|
||||
sameThreadExecutor()), new JavaUrlHttpCommandExecutorServiceModule());
|
||||
processor = injector.getInstance(Key
|
||||
.get(new TypeLiteral<RestAnnotationProcessor<AzureQueueAsyncClient>>() {
|
||||
}));
|
||||
}
|
||||
|
||||
RestAnnotationProcessor<AzureQueueAsyncClient> processor;
|
||||
@SuppressWarnings("unused")
|
||||
@Provides
|
||||
@TimeStamp
|
||||
@Singleton
|
||||
String provideTS() {
|
||||
return "timestamp";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -23,10 +23,11 @@ import static org.testng.Assert.assertTrue;
|
|||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.BoundedSet;
|
||||
import org.jclouds.azure.storage.options.CreateOptions;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.azure.storage.queue.domain.QueueMetadata;
|
||||
import org.jclouds.azure.storage.queue.options.PutMessageOptions;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
|
@ -61,7 +62,7 @@ public class AzureQueueClientLiveTest {
|
|||
@Test
|
||||
public void testListQueues() throws Exception {
|
||||
|
||||
BoundedSortedSet<QueueMetadata> response = connection.listQueues();
|
||||
BoundedSet<QueueMetadata> response = connection.listQueues();
|
||||
assert null != response;
|
||||
long initialQueueCount = response.size();
|
||||
assertTrue(initialQueueCount >= 0);
|
||||
|
@ -86,17 +87,16 @@ public class AzureQueueClientLiveTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
BoundedSortedSet<QueueMetadata> response = connection.listQueues();
|
||||
BoundedSet<QueueMetadata> response = connection.listQueues();
|
||||
assert null != response;
|
||||
long queueCount = response.size();
|
||||
assertTrue(queueCount >= 1);
|
||||
// TODO ... check to see the queue actually exists
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "testCreateQueue" })
|
||||
public void testListQueuesWithOptions() throws Exception {
|
||||
|
||||
BoundedSortedSet<QueueMetadata> response = connection.listQueues(ListOptions.Builder.prefix(
|
||||
BoundedSet<QueueMetadata> response = connection.listQueues(ListOptions.Builder.prefix(
|
||||
privateQueue).maxResults(1));
|
||||
assert null != response;
|
||||
long initialQueueCount = response.size();
|
||||
|
@ -104,10 +104,17 @@ public class AzureQueueClientLiveTest {
|
|||
assertEquals(privateQueue, response.getPrefix());
|
||||
assertEquals(1, response.getMaxResults());
|
||||
}
|
||||
|
||||
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "testCreateQueue" })
|
||||
public void testPutMessage() throws Exception {
|
||||
connection.putMessage(privateQueue,"holycow",PutMessageOptions.Builder.withTTL(4));
|
||||
// TODO loop for up to 30 seconds checking if they are really gone
|
||||
}
|
||||
|
||||
|
||||
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "testPutMessage" })
|
||||
public void testDeleteQueue() throws Exception {
|
||||
assert connection.deleteQueue(privateQueue);
|
||||
connection.clearMessages(privateQueue);
|
||||
connection.deleteQueue(privateQueue);
|
||||
// TODO loop for up to 30 seconds checking if they are really gone
|
||||
}
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedTreeSet;
|
||||
import org.jclouds.azure.storage.domain.BoundedSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedHashSet;
|
||||
import org.jclouds.azure.storage.queue.domain.QueueMetadata;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -41,24 +41,24 @@ public class AccountNameEnumerationResultsHandlerTest extends BaseHandlerTest {
|
|||
|
||||
public void testApplyInputStream() {
|
||||
InputStream is = getClass().getResourceAsStream("/queue/test_list_queues.xml");
|
||||
BoundedSortedSet<QueueMetadata> list = new BoundedTreeSet<QueueMetadata>(ImmutableSortedSet.of(
|
||||
BoundedSet<QueueMetadata> list = new BoundedHashSet<QueueMetadata>(ImmutableSortedSet.of(
|
||||
new QueueMetadata("q1", URI.create("http://myaccount.queue.core.windows.net/q1")),
|
||||
new QueueMetadata("q2", URI.create("http://myaccount.queue.core.windows.net/q2")),
|
||||
new QueueMetadata("q3", URI.create("http://myaccount.queue.core.windows.net/q3"))),
|
||||
URI.create("http://myaccount.queue.core.windows.net"), "q", null, 3, "q4");
|
||||
BoundedSortedSet<QueueMetadata> result = (BoundedSortedSet<QueueMetadata>) factory.create(
|
||||
BoundedSet<QueueMetadata> result = (BoundedSet<QueueMetadata>) factory.create(
|
||||
injector.getInstance(AccountNameEnumerationResultsHandler.class)).parse(is);
|
||||
assertEquals(result, list);
|
||||
}
|
||||
|
||||
public void testApplyInputStreamWithOptions() {
|
||||
InputStream is = getClass().getResourceAsStream("/queue/test_list_queues_options.xml");
|
||||
BoundedSortedSet<QueueMetadata> list = new BoundedTreeSet<QueueMetadata>(ImmutableSortedSet.of(
|
||||
BoundedSet<QueueMetadata> list = new BoundedHashSet<QueueMetadata>(ImmutableSortedSet.of(
|
||||
new QueueMetadata("q4", URI.create("http://myaccount.queue.core.windows.net/q4")),
|
||||
new QueueMetadata("q5", URI.create("http://myaccount.queue.core.windows.net/q5"))),
|
||||
URI.create("http://myaccount.queue.core.windows.net"), "q", "q4", 3, null);
|
||||
|
||||
BoundedSortedSet<QueueMetadata> result = (BoundedSortedSet<QueueMetadata>) factory.create(
|
||||
BoundedSet<QueueMetadata> result = (BoundedSet<QueueMetadata>) factory.create(
|
||||
injector.getInstance(AccountNameEnumerationResultsHandler.class)).parse(is);
|
||||
|
||||
assertEquals(result, list);
|
||||
|
|
|
@ -30,22 +30,24 @@
|
|||
<Blob>
|
||||
<Name>blob1.txt</Name>
|
||||
<Url>http://myaccount.blob.core.windows.net/mycontainer/blob1.txt</Url>
|
||||
<LastModified>Thu, 18 Sep 2008 18:41:57 GMT</LastModified>
|
||||
<Last-Modified>Thu, 18 Sep 2008 18:41:57 GMT</Last-Modified>
|
||||
<Etag>0x8CAE7D55D050B8B</Etag>
|
||||
<Size>8</Size>
|
||||
<ContentType>text/plain; charset=UTF-8</ContentType>
|
||||
<ContentEncoding />
|
||||
<ContentLanguage />
|
||||
<Content-Length>8</Content-Length>
|
||||
<Content-Type>text/plain; charset=UTF-8</Content-Type>
|
||||
<BlobType>BlockBlob</BlobType>
|
||||
<Content-Encoding />
|
||||
<Content-Language />
|
||||
</Blob>
|
||||
<Blob>
|
||||
<Name>blob2.txt</Name>
|
||||
<Url>http://myaccount.blob.core.windows.net/mycontainer/blob2.txt</Url>
|
||||
<LastModified>Thu, 18 Sep 2008 18:41:57 GMT</LastModified>
|
||||
<Last-Modified>Thu, 18 Sep 2008 18:41:57 GMT</Last-Modified>
|
||||
<Etag>0x8CAE7D55CF6C339</Etag>
|
||||
<Size>14</Size>
|
||||
<ContentType>text/plain; charset=UTF-8</ContentType>
|
||||
<ContentEncoding />
|
||||
<ContentLanguage />
|
||||
<Content-Length>14</Content-Length>
|
||||
<Content-Type>text/plain; charset=UTF-8</Content-Type>
|
||||
<BlobType>BlockBlob</BlobType>
|
||||
<Content-Encoding />
|
||||
<Content-Language />
|
||||
</Blob>
|
||||
<BlobPrefix>
|
||||
<Name>myfolder/</Name>
|
||||
|
@ -53,12 +55,13 @@
|
|||
<Blob>
|
||||
<Name>newblob1.txt</Name>
|
||||
<Url>http://myaccount.blob.core.windows.net/mycontainer/newblob1.txt</Url>
|
||||
<LastModified>Thu, 18 Sep 2008 18:41:57 GMT</LastModified>
|
||||
<Last-Modified>Thu, 18 Sep 2008 18:41:57 GMT</Last-Modified>
|
||||
<Etag>0x8CAE7D55CF6C339</Etag>
|
||||
<Size>25</Size>
|
||||
<ContentType>text/plain; charset=UTF-8</ContentType>
|
||||
<ContentEncoding />
|
||||
<ContentLanguage />
|
||||
<Content-Length>25</Content-Length>
|
||||
<Content-Type>text/plain; charset=UTF-8</Content-Type>
|
||||
<BlobType>PageBlob</BlobType>
|
||||
<Content-Encoding />
|
||||
<Content-Language />
|
||||
</Blob>
|
||||
</Blobs>
|
||||
<NextMarker>newblob2.txt</NextMarker>
|
||||
|
|
|
@ -29,17 +29,17 @@
|
|||
<Containers>
|
||||
<Container>
|
||||
<Url>http://myaccount.blob.core.windows.net/audio</Url>
|
||||
<LastModified>Wed, 13 Aug 2008 20:39:39 GMT</LastModified>
|
||||
<Last-Modified>Wed, 13 Aug 2008 20:39:39 GMT</Last-Modified>
|
||||
<Etag>0x8CACB9BD7C6B1B2</Etag>
|
||||
</Container>
|
||||
<Container>
|
||||
<Url>http://myaccount.blob.core.windows.net/images</Url>
|
||||
<LastModified>Wed, 14 Aug 2008 20:39:39 GMT</LastModified>
|
||||
<Last-Modified>Wed, 14 Aug 2008 20:39:39 GMT</Last-Modified>
|
||||
<Etag>0x8CACB9BD7C1EEEC</Etag>
|
||||
</Container>
|
||||
<Container>
|
||||
<Url>http://myaccount.blob.core.windows.net/textfiles</Url>
|
||||
<LastModified>Wed, 15 Aug 2008 20:39:39 GMT</LastModified>
|
||||
<Last-Modified>Wed, 15 Aug 2008 20:39:39 GMT</Last-Modified>
|
||||
<Etag>0x8CACB9BD7BACAC3</Etag>
|
||||
</Container>
|
||||
</Containers>
|
||||
|
|
|
@ -31,17 +31,17 @@
|
|||
<Containers>
|
||||
<Container>
|
||||
<Url>http://myaccount.blob.core.windows.net/audio</Url>
|
||||
<LastModified>Wed, 13 Aug 2008 20:39:39 GMT</LastModified>
|
||||
<Last-Modified>Wed, 13 Aug 2008 20:39:39 GMT</Last-Modified>
|
||||
<Etag>0x8CACB9BD7C6B1B2</Etag>
|
||||
</Container>
|
||||
<Container>
|
||||
<Url>http://myaccount.blob.core.windows.net/images</Url>
|
||||
<LastModified>Wed, 14 Aug 2008 20:39:39 GMT</LastModified>
|
||||
<Last-Modified>Wed, 14 Aug 2008 20:39:39 GMT</Last-Modified>
|
||||
<Etag>0x8CACB9BD7C1EEEC</Etag>
|
||||
</Container>
|
||||
<Container>
|
||||
<Url>http://myaccount.blob.core.windows.net/textfiles</Url>
|
||||
<LastModified>Wed, 15 Aug 2008 20:39:39 GMT</LastModified>
|
||||
<Last-Modified>Wed, 15 Aug 2008 20:39:39 GMT</Last-Modified>
|
||||
<Etag>0x8CACB9BD7BACAC3</Etag>
|
||||
</Container>
|
||||
</Containers>
|
||||
|
|
|
@ -1,32 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
Copyright (C) 2009 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
|
||||
====================================================================
|
||||
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.
|
||||
====================================================================
|
||||
|
||||
-->
|
||||
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.
|
||||
====================================================================
|
||||
-->
|
||||
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||
|
||||
<!--
|
||||
For more configuration infromation and examples see the Apache Log4j
|
||||
website: http://logging.apache.org/log4j/
|
||||
-->
|
||||
<!--
|
||||
For more configuration infromation and examples see the Apache
|
||||
Log4j website: http://logging.apache.org/log4j/
|
||||
-->
|
||||
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
|
||||
debug="false">
|
||||
debug="false">
|
||||
|
||||
<!-- A time/date based rolling appender -->
|
||||
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||
|
@ -43,68 +42,68 @@
|
|||
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||
|
||||
<!--
|
||||
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
|
||||
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
|
||||
%m%n"/>
|
||||
The full pattern: Date MS Priority [Category]
|
||||
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||
-->
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- A time/date based rolling appender -->
|
||||
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||
<param name="File" value="target/test-data/jclouds.log" />
|
||||
<param name="Append" value="true" />
|
||||
<!-- A time/date based rolling appender -->
|
||||
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||
<param name="File" value="target/test-data/jclouds.log" />
|
||||
<param name="Append" value="true" />
|
||||
|
||||
<!-- Rollover at midnight each day -->
|
||||
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||
<!-- Rollover at midnight each day -->
|
||||
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||
|
||||
<param name="Threshold" value="TRACE" />
|
||||
<param name="Threshold" value="TRACE" />
|
||||
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||
|
||||
<!--
|
||||
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
|
||||
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
|
||||
%m%n"/>
|
||||
-->
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
|
||||
<appender-ref ref="FILE" />
|
||||
</appender>
|
||||
<!--
|
||||
The full pattern: Date MS Priority [Category]
|
||||
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||
-->
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
|
||||
<appender-ref ref="FILE" />
|
||||
</appender>
|
||||
|
||||
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
|
||||
<appender-ref ref="WIREFILE" />
|
||||
</appender>
|
||||
|
||||
<!-- ================ -->
|
||||
<!-- Limit categories -->
|
||||
<!-- ================ -->
|
||||
</appender>
|
||||
|
||||
<category name="org.jclouds">
|
||||
<priority value="DEBUG" />
|
||||
<!-- ================ -->
|
||||
<!-- Limit categories -->
|
||||
<!-- ================ -->
|
||||
|
||||
<category name="org.jclouds">
|
||||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNC" />
|
||||
</category>
|
||||
|
||||
</category>
|
||||
|
||||
<category name="jclouds.http.headers">
|
||||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNCWIRE" />
|
||||
</category><!--
|
||||
</category>
|
||||
|
||||
<category name="jclouds.http.wire">
|
||||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNCWIRE" />
|
||||
</category>
|
||||
|
||||
--><!-- ======================= -->
|
||||
<!-- Setup the Root category -->
|
||||
<!-- ======================= -->
|
||||
|
||||
<root>
|
||||
<priority value="WARN" />
|
||||
</root>
|
||||
<!-- ======================= -->
|
||||
<!-- Setup the Root category -->
|
||||
<!-- ======================= -->
|
||||
|
||||
<root>
|
||||
<priority value="WARN" />
|
||||
</root>
|
||||
|
||||
</log4j:configuration>
|
|
@ -45,7 +45,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
|
|||
public void containerDoesntExist() {
|
||||
assert !context.getBlobStore().containerExists("forgetaboutit");
|
||||
assert !context.getBlobStore().containerExists(
|
||||
"bog.cloudcachestorefunctionalintegrationtest-first");
|
||||
"cloudcachestorefunctionalintegrationtest-first");
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" })
|
||||
|
|
|
@ -40,12 +40,12 @@ import java.util.concurrent.TimeoutException;
|
|||
|
||||
import org.jclouds.aws.s3.S3PropertiesBuilder;
|
||||
import org.jclouds.aws.s3.blobstore.S3BlobStoreContextBuilder;
|
||||
import org.jclouds.aws.s3.blobstore.S3BlobStoreContextFactory;
|
||||
import org.jclouds.azure.storage.blob.AzureBlobPropertiesBuilder;
|
||||
import org.jclouds.azure.storage.blob.blobstore.AzureBlobStoreContextBuilder;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.BlobStoreContextFactory;
|
||||
import org.jclouds.rackspace.cloudfiles.CloudFilesPropertiesBuilder;
|
||||
import org.jclouds.rackspace.cloudfiles.blobstore.CloudFilesBlobStoreContextBuilder;
|
||||
import org.jclouds.rackspace.cloudfiles.blobstore.CloudFilesBlobStoreContextFactory;
|
||||
import org.jclouds.twitter.TwitterPropertiesBuilder;
|
||||
import org.jclouds.util.Utils;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
|
@ -53,7 +53,7 @@ import org.testng.annotations.BeforeTest;
|
|||
import org.testng.annotations.Parameters;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* Starts up the Google App Engine for Java Development environment and deploys an application which
|
||||
|
@ -66,7 +66,7 @@ public class TweetStoreLiveTest {
|
|||
|
||||
GoogleDevServer server;
|
||||
private URL url;
|
||||
private ImmutableSet<BlobStoreContext<? extends Object, ? extends Object>> contexts;
|
||||
private Iterable<BlobStoreContext<? extends Object, ? extends Object>> contexts;
|
||||
private String container;
|
||||
|
||||
@BeforeTest
|
||||
|
@ -79,11 +79,10 @@ public class TweetStoreLiveTest {
|
|||
.getProperty(PROPERTY_TWEETSTORE_CONTAINER), PROPERTY_TWEETSTORE_CONTAINER));
|
||||
props.setProperty(PROPERTY_BLOBSTORE_CONTEXTBUILDERS,
|
||||
// WATCH THIS.. when adding a new context, you must update the string
|
||||
// String.format("%s,%s,%s", S3BlobStoreContextBuilder.class.getName(),
|
||||
// CloudFilesBlobStoreContextBuilder.class.getName(),
|
||||
// AzureBlobStoreContextBuilder.class.getName()));
|
||||
String.format("%s,%s", S3BlobStoreContextBuilder.class.getName(),
|
||||
CloudFilesBlobStoreContextBuilder.class.getName()));
|
||||
String.format("%s,%s,%s", S3BlobStoreContextBuilder.class.getName(),
|
||||
CloudFilesBlobStoreContextBuilder.class.getName(),
|
||||
AzureBlobStoreContextBuilder.class.getName()));
|
||||
|
||||
props = new TwitterPropertiesBuilder(props).withCredentials(
|
||||
checkNotNull(System.getProperty(PROPERTY_TWITTER_USER), PROPERTY_TWITTER_USER),
|
||||
System.getProperty(PROPERTY_TWITTER_PASSWORD, PROPERTY_TWITTER_PASSWORD)).build();
|
||||
|
@ -110,22 +109,22 @@ public class TweetStoreLiveTest {
|
|||
|
||||
@BeforeClass
|
||||
void clearAndCreateContainers() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
TimeoutException, IOException {
|
||||
container = checkNotNull(System.getProperty(PROPERTY_TWEETSTORE_CONTAINER));
|
||||
BlobStoreContext<?, ?> s3Context = S3BlobStoreContextFactory.createContext(checkNotNull(
|
||||
System.getProperty(PROPERTY_AWS_ACCESSKEYID), PROPERTY_AWS_ACCESSKEYID), System
|
||||
BlobStoreContextFactory factory = new BlobStoreContextFactory();
|
||||
BlobStoreContext<?, ?> s3Context = factory.createContext("s3", checkNotNull(System
|
||||
.getProperty(PROPERTY_AWS_ACCESSKEYID), PROPERTY_AWS_ACCESSKEYID), System
|
||||
.getProperty(PROPERTY_AWS_SECRETACCESSKEY, PROPERTY_AWS_SECRETACCESSKEY));
|
||||
|
||||
BlobStoreContext<?, ?> cfContext = CloudFilesBlobStoreContextFactory.createContext(
|
||||
checkNotNull(System.getProperty(PROPERTY_RACKSPACE_USER), PROPERTY_RACKSPACE_USER),
|
||||
System.getProperty(PROPERTY_RACKSPACE_KEY, PROPERTY_RACKSPACE_KEY));
|
||||
BlobStoreContext<?, ?> cfContext = factory.createContext("cloudfiles", checkNotNull(System
|
||||
.getProperty(PROPERTY_RACKSPACE_USER), PROPERTY_RACKSPACE_USER), System.getProperty(
|
||||
PROPERTY_RACKSPACE_KEY, PROPERTY_RACKSPACE_KEY));
|
||||
|
||||
// BlobStoreContext<?, ?> azContext = AzureBlobStoreContextFactory.createContext(checkNotNull(
|
||||
// System.getProperty(PROPERTY_AZURESTORAGE_ACCOUNT), PROPERTY_AZURESTORAGE_ACCOUNT),
|
||||
// System.getProperty(PROPERTY_AZURESTORAGE_KEY, PROPERTY_AZURESTORAGE_KEY));
|
||||
//
|
||||
// this.contexts = ImmutableSet.of(s3Context, cfContext, azContext);
|
||||
this.contexts = ImmutableSet.of(s3Context, cfContext);
|
||||
BlobStoreContext<?, ?> azContext = factory.createContext("azureblob", checkNotNull(System
|
||||
.getProperty(PROPERTY_AZURESTORAGE_ACCOUNT), PROPERTY_AZURESTORAGE_ACCOUNT), System
|
||||
.getProperty(PROPERTY_AZURESTORAGE_KEY, PROPERTY_AZURESTORAGE_KEY));
|
||||
|
||||
this.contexts = ImmutableList.of(s3Context, cfContext, azContext);
|
||||
boolean deleted = false;
|
||||
for (BlobStoreContext<?, ?> context : contexts) {
|
||||
if (context.getBlobStore().containerExists(container)) {
|
||||
|
@ -135,8 +134,8 @@ public class TweetStoreLiveTest {
|
|||
}
|
||||
}
|
||||
if (deleted) {
|
||||
System.err.println("sleeping 30 seconds to allow containers to clear");
|
||||
Thread.sleep(30000);
|
||||
System.err.println("sleeping 60 seconds to allow containers to clear");
|
||||
Thread.sleep(60000);
|
||||
}
|
||||
for (BlobStoreContext<?, ?> context : contexts) {
|
||||
System.err.printf("creating container %s at %s%n", container, context.getEndPoint());
|
||||
|
@ -164,8 +163,7 @@ public class TweetStoreLiveTest {
|
|||
public void testPrimeContainers() throws IOException, InterruptedException {
|
||||
URL gurl = new URL(url, "/store/do");
|
||||
|
||||
for (String context : new String[] { "S3", "CloudFiles" }) {
|
||||
// for (String context : new String[] { "S3", "Azure", "CloudFiles" }) {
|
||||
for (String context : new String[] { "S3", "Azure", "CloudFiles" }) {
|
||||
System.out.println("storing at context: " + context);
|
||||
HttpURLConnection connection = (HttpURLConnection) gurl.openConnection();
|
||||
connection.addRequestProperty("X-AppEngine-QueueName", "twitter");
|
||||
|
@ -176,8 +174,8 @@ public class TweetStoreLiveTest {
|
|||
connection.disconnect();
|
||||
}
|
||||
|
||||
System.err.println("sleeping 10 seconds to allow for eventual consistency delay");
|
||||
Thread.sleep(10000);
|
||||
System.err.println("sleeping 20 seconds to allow for eventual consistency delay");
|
||||
Thread.sleep(20000);
|
||||
for (BlobStoreContext<?, ?> context : contexts) {
|
||||
assert context.createInputStreamMap(container).size() > 0 : context.getEndPoint();
|
||||
}
|
||||
|
|
|
@ -40,12 +40,12 @@ import java.util.concurrent.TimeoutException;
|
|||
|
||||
import org.jclouds.aws.s3.S3PropertiesBuilder;
|
||||
import org.jclouds.aws.s3.blobstore.S3BlobStoreContextBuilder;
|
||||
import org.jclouds.aws.s3.blobstore.S3BlobStoreContextFactory;
|
||||
import org.jclouds.azure.storage.blob.AzureBlobPropertiesBuilder;
|
||||
import org.jclouds.azure.storage.blob.blobstore.AzureBlobStoreContextBuilder;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.BlobStoreContextFactory;
|
||||
import org.jclouds.rackspace.cloudfiles.CloudFilesPropertiesBuilder;
|
||||
import org.jclouds.rackspace.cloudfiles.blobstore.CloudFilesBlobStoreContextBuilder;
|
||||
import org.jclouds.rackspace.cloudfiles.blobstore.CloudFilesBlobStoreContextFactory;
|
||||
import org.jclouds.twitter.TwitterPropertiesBuilder;
|
||||
import org.jclouds.util.Utils;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
|
@ -53,7 +53,7 @@ import org.testng.annotations.BeforeTest;
|
|||
import org.testng.annotations.Parameters;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* Starts up the Google App Engine for Java Development environment and deploys an application which
|
||||
|
@ -66,7 +66,7 @@ public class TweetStoreLiveTest {
|
|||
|
||||
GoogleDevServer server;
|
||||
private URL url;
|
||||
private ImmutableSet<BlobStoreContext<? extends Object, ? extends Object>> contexts;
|
||||
private Iterable<BlobStoreContext<? extends Object, ? extends Object>> contexts;
|
||||
private String container;
|
||||
|
||||
@BeforeTest
|
||||
|
@ -79,14 +79,9 @@ public class TweetStoreLiveTest {
|
|||
.getProperty(PROPERTY_TWEETSTORE_CONTAINER), PROPERTY_TWEETSTORE_CONTAINER));
|
||||
props.setProperty(PROPERTY_BLOBSTORE_CONTEXTBUILDERS,
|
||||
// WATCH THIS.. when adding a new context, you must update the string
|
||||
// String.format("%s,%s,%s", S3BlobStoreContextBuilder.class.getName(),
|
||||
// CloudFilesBlobStoreContextBuilder.class.getName(),
|
||||
// AzureBlobStoreContextBuilder.class.getName()));
|
||||
String.format("%s,%s", S3BlobStoreContextBuilder.class.getName(),
|
||||
CloudFilesBlobStoreContextBuilder.class.getName()));
|
||||
props = new TwitterPropertiesBuilder(props).withCredentials(
|
||||
checkNotNull(System.getProperty(PROPERTY_TWITTER_USER), PROPERTY_TWITTER_USER),
|
||||
System.getProperty(PROPERTY_TWITTER_PASSWORD, PROPERTY_TWITTER_PASSWORD)).build();
|
||||
String.format("%s,%s,%s", S3BlobStoreContextBuilder.class.getName(),
|
||||
CloudFilesBlobStoreContextBuilder.class.getName(),
|
||||
AzureBlobStoreContextBuilder.class.getName()));
|
||||
|
||||
props = new TwitterPropertiesBuilder(props).withCredentials(
|
||||
checkNotNull(System.getProperty(PROPERTY_TWITTER_USER), PROPERTY_TWITTER_USER),
|
||||
|
@ -114,22 +109,22 @@ public class TweetStoreLiveTest {
|
|||
|
||||
@BeforeClass
|
||||
void clearAndCreateContainers() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
TimeoutException, IOException {
|
||||
container = checkNotNull(System.getProperty(PROPERTY_TWEETSTORE_CONTAINER));
|
||||
BlobStoreContext<?, ?> s3Context = S3BlobStoreContextFactory.createContext(checkNotNull(
|
||||
System.getProperty(PROPERTY_AWS_ACCESSKEYID), PROPERTY_AWS_ACCESSKEYID), System
|
||||
BlobStoreContextFactory factory = new BlobStoreContextFactory();
|
||||
BlobStoreContext<?, ?> s3Context = factory.createContext("s3", checkNotNull(System
|
||||
.getProperty(PROPERTY_AWS_ACCESSKEYID), PROPERTY_AWS_ACCESSKEYID), System
|
||||
.getProperty(PROPERTY_AWS_SECRETACCESSKEY, PROPERTY_AWS_SECRETACCESSKEY));
|
||||
|
||||
BlobStoreContext<?, ?> cfContext = CloudFilesBlobStoreContextFactory.createContext(
|
||||
checkNotNull(System.getProperty(PROPERTY_RACKSPACE_USER), PROPERTY_RACKSPACE_USER),
|
||||
System.getProperty(PROPERTY_RACKSPACE_KEY, PROPERTY_RACKSPACE_KEY));
|
||||
BlobStoreContext<?, ?> cfContext = factory.createContext("cloudfiles", checkNotNull(System
|
||||
.getProperty(PROPERTY_RACKSPACE_USER), PROPERTY_RACKSPACE_USER), System.getProperty(
|
||||
PROPERTY_RACKSPACE_KEY, PROPERTY_RACKSPACE_KEY));
|
||||
|
||||
// BlobStoreContext<?, ?> azContext = AzureBlobStoreContextFactory.createContext(checkNotNull(
|
||||
// System.getProperty(PROPERTY_AZURESTORAGE_ACCOUNT), PROPERTY_AZURESTORAGE_ACCOUNT),
|
||||
// System.getProperty(PROPERTY_AZURESTORAGE_KEY, PROPERTY_AZURESTORAGE_KEY));
|
||||
//
|
||||
// this.contexts = ImmutableSet.of(s3Context, cfContext, azContext);
|
||||
this.contexts = ImmutableSet.of(s3Context, cfContext);
|
||||
BlobStoreContext<?, ?> azContext = factory.createContext("azureblob", checkNotNull(System
|
||||
.getProperty(PROPERTY_AZURESTORAGE_ACCOUNT), PROPERTY_AZURESTORAGE_ACCOUNT), System
|
||||
.getProperty(PROPERTY_AZURESTORAGE_KEY, PROPERTY_AZURESTORAGE_KEY));
|
||||
|
||||
this.contexts = ImmutableList.of(s3Context, cfContext, azContext);
|
||||
boolean deleted = false;
|
||||
for (BlobStoreContext<?, ?> context : contexts) {
|
||||
if (context.getBlobStore().containerExists(container)) {
|
||||
|
@ -139,8 +134,8 @@ public class TweetStoreLiveTest {
|
|||
}
|
||||
}
|
||||
if (deleted) {
|
||||
System.err.println("sleeping 30 seconds to allow containers to clear");
|
||||
Thread.sleep(30000);
|
||||
System.err.println("sleeping 60 seconds to allow containers to clear");
|
||||
Thread.sleep(60000);
|
||||
}
|
||||
for (BlobStoreContext<?, ?> context : contexts) {
|
||||
System.err.printf("creating container %s at %s%n", container, context.getEndPoint());
|
||||
|
@ -168,8 +163,7 @@ public class TweetStoreLiveTest {
|
|||
public void testPrimeContainers() throws IOException, InterruptedException {
|
||||
URL gurl = new URL(url, "/store/do");
|
||||
|
||||
for (String context : new String[] { "S3", "CloudFiles" }) {
|
||||
// for (String context : new String[] { "S3", "Azure", "CloudFiles" }) {
|
||||
for (String context : new String[] { "S3", "Azure", "CloudFiles" }) {
|
||||
System.out.println("storing at context: " + context);
|
||||
HttpURLConnection connection = (HttpURLConnection) gurl.openConnection();
|
||||
connection.addRequestProperty("X-AppEngine-QueueName", "twitter");
|
||||
|
@ -180,8 +174,8 @@ public class TweetStoreLiveTest {
|
|||
connection.disconnect();
|
||||
}
|
||||
|
||||
System.err.println("sleeping 10 seconds to allow for eventual consistency delay");
|
||||
Thread.sleep(10000);
|
||||
System.err.println("sleeping 20 seconds to allow for eventual consistency delay");
|
||||
Thread.sleep(20000);
|
||||
for (BlobStoreContext<?, ?> context : contexts) {
|
||||
assert context.createInputStreamMap(container).size() > 0 : context.getEndPoint();
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
<packaging>pom</packaging>
|
||||
<name>jclouds demos project</name>
|
||||
<modules>
|
||||
<module>speedtest-azurequeue</module>
|
||||
<module>gae-tweetstore</module>
|
||||
<module>gae-tweetstore-spring</module>
|
||||
</modules>
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
====
|
||||
|
||||
Copyright (C) 2009 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.
|
||||
====================================================================
|
||||
====
|
||||
#
|
||||
# this is a simple example command line client that creates a queue, then tracks performance of it
|
||||
# 1. execute 'mvn install' to build the sample
|
||||
# 2. invoke the jar, passing your azure credentials and the bucket you wish to create
|
||||
# ex.
|
||||
# java -jar target/jclouds-speedtest-azurequeue-jar-with-dependencies.jar accountName encodedKey queueName messageCount
|
|
@ -0,0 +1,88 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2009 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.
|
||||
====================================================================
|
||||
|
||||
-->
|
||||
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<artifactId>jclouds-demos-project</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jclouds-speedtest-azurequeue</artifactId>
|
||||
<name>tests speed of azurequeue</name>
|
||||
<description>creates a queue and then tests performance against it</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-enterprise</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-azure</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>org.jclouds.azure.azurequeue.SpeedTest</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>org.jclouds.azure.azurequeue.SpeedTest</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,151 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 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.azure.azurequeue;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.azure.storage.queue.AzureQueueAsyncClient;
|
||||
import org.jclouds.azure.storage.queue.AzureQueueClient;
|
||||
import org.jclouds.azure.storage.queue.AzureQueueContextFactory;
|
||||
import org.jclouds.azure.storage.queue.domain.QueueMetadata;
|
||||
import org.jclouds.enterprise.config.EnterpriseConfigurationModule;
|
||||
import org.jclouds.logging.config.NullLoggingModule;
|
||||
import org.jclouds.rest.RestContext;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* This the Main class of an Application that tests your response time to amazon AzureQueue.
|
||||
*
|
||||
* Usage is: java org.jclouds.aws.sqs.SpeedTest \"account\" \"encodedKey\" \"queueName\"
|
||||
* \"messageCount\"
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class SpeedTest {
|
||||
|
||||
public static int PARAMETERS = 4;
|
||||
public static String INVALID_SYNTAX = "Invalid number of parameters. Syntax is: \"account\" \"encodedKey\" \"queueName\" \"messageCount\" ";
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
|
||||
if (args.length < PARAMETERS)
|
||||
throw new IllegalArgumentException(INVALID_SYNTAX);
|
||||
|
||||
boolean isEnterprise = System.getProperties().containsKey("jclouds.enterprise");
|
||||
// Args
|
||||
String account = args[0];
|
||||
String encodedKey = args[1];
|
||||
String queueName = args[2];
|
||||
int messageCount = Integer.parseInt(args[3]);
|
||||
|
||||
RestContext<AzureQueueAsyncClient, AzureQueueClient> context = isEnterprise ? AzureQueueContextFactory
|
||||
.createContext(System.getProperties(), account, encodedKey, new NullLoggingModule(),
|
||||
new EnterpriseConfigurationModule())
|
||||
: AzureQueueContextFactory.createContext(System.getProperties(), account,
|
||||
encodedKey, new NullLoggingModule());
|
||||
|
||||
try {
|
||||
if (purgeQueues(queueName, context)) {
|
||||
System.out.printf("pausing 60 seconds before recreating queues%n");
|
||||
Thread.sleep(60 * 1000);
|
||||
}
|
||||
createQueue(queueName, context);
|
||||
runTests(queueName, messageCount, isEnterprise ? "enterprise" : "default", context);
|
||||
} finally {
|
||||
purgeQueues(queueName, context);
|
||||
// Close connectons
|
||||
context.close();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void runTests(String queueName, int messageCount, String contextName,
|
||||
RestContext<AzureQueueAsyncClient, AzureQueueClient> context)
|
||||
throws InterruptedException {
|
||||
String message = "1";
|
||||
long timeOut = messageCount * 200; // minimum rate should be at least 5/second
|
||||
|
||||
int complete = 0;
|
||||
int errors = 0;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
// fire off all the messages for the test
|
||||
Set<ListenableFuture<Void>> responses = Sets.newHashSet();
|
||||
for (int i = 0; i < messageCount; i++) {
|
||||
responses.add(context.getAsyncApi().putMessage(queueName, message));
|
||||
}
|
||||
|
||||
do {
|
||||
Set<ListenableFuture<Void>> retries = Sets.newHashSet();
|
||||
for (ListenableFuture<Void> response : responses) {
|
||||
try {
|
||||
response.get(100, TimeUnit.MILLISECONDS);
|
||||
complete++;
|
||||
} catch (ExecutionException e) {
|
||||
System.err.println(e.getMessage());
|
||||
errors++;
|
||||
} catch (TimeoutException e) {
|
||||
retries.add(response);
|
||||
}
|
||||
}
|
||||
responses = Sets.newHashSet(retries);
|
||||
} while (responses.size() > 0 && System.currentTimeMillis() < start + timeOut);
|
||||
long duration = System.currentTimeMillis() - start;
|
||||
if (duration > timeOut)
|
||||
System.out.printf("TIMEOUT: context: %s, rate: %f messages/second%n", contextName,
|
||||
((double) complete) / (duration / 1000.0));
|
||||
else
|
||||
System.out.printf("COMPLETE: context: %s, rate: %f messages/second%n", contextName,
|
||||
((double) complete) / (duration / 1000.0));
|
||||
System.gc();
|
||||
System.out.println("pausing 5 seconds before the next run");
|
||||
Thread.sleep(5000);// let the network quiet down
|
||||
}
|
||||
|
||||
private static void createQueue(String queueName,
|
||||
RestContext<AzureQueueAsyncClient, AzureQueueClient> nullLoggingDefaultContext) {
|
||||
System.out.printf("creating queue: %s%n", queueName);
|
||||
nullLoggingDefaultContext.getApi().createQueue(queueName);
|
||||
}
|
||||
|
||||
private static boolean purgeQueues(String queueName,
|
||||
RestContext<AzureQueueAsyncClient, AzureQueueClient> nullLoggingDefaultContext) {
|
||||
boolean deleted = false;
|
||||
try {
|
||||
SortedSet<QueueMetadata> result = Sets.newTreeSet(nullLoggingDefaultContext.getApi()
|
||||
.listQueues(ListOptions.Builder.prefix(queueName)));
|
||||
if (result.size() >= 1) {
|
||||
nullLoggingDefaultContext.getApi().deleteQueue(result.last().getName());
|
||||
System.out.printf("deleted queue: %s%n", queueName);
|
||||
deleted = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
return deleted;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue