mirror of https://github.com/apache/jclouds.git
Issue 86: added blobstore support for azure
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2016 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
bcd1c2343a
commit
0c7ac791dc
|
@ -36,10 +36,10 @@ import javax.ws.rs.PathParam;
|
|||
|
||||
import org.jclouds.azure.storage.AzureBlob;
|
||||
import org.jclouds.azure.storage.blob.binders.BindAzureBlobToEntity;
|
||||
import org.jclouds.azure.storage.blob.blobstore.functions.BlobName;
|
||||
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.functions.BlobName;
|
||||
import org.jclouds.azure.storage.blob.functions.ParseBlobFromHeadersAndHttpContent;
|
||||
import org.jclouds.azure.storage.blob.functions.ParseBlobPropertiesFromHeaders;
|
||||
import org.jclouds.azure.storage.blob.functions.ParseContainerPropertiesFromHeaders;
|
||||
|
@ -48,7 +48,7 @@ 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.BoundedList;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
|
||||
|
@ -56,6 +56,7 @@ import org.jclouds.blobstore.binders.BindMapToHeadersWithPrefix;
|
|||
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
|
||||
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
||||
import org.jclouds.http.functions.ParseETagHeader;
|
||||
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||
import org.jclouds.http.functions.ReturnTrueOn404;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
|
@ -98,7 +99,8 @@ public interface AzureBlobClient {
|
|||
@XMLResponseParser(AccountNameEnumerationResultsHandler.class)
|
||||
@Path("/")
|
||||
@QueryParams(keys = "comp", values = "list")
|
||||
BoundedList<ListableContainerProperties> listContainers(ListOptions... listOptions);
|
||||
Future<? extends BoundedSortedSet<ListableContainerProperties>> listContainers(
|
||||
ListOptions... listOptions);
|
||||
|
||||
/**
|
||||
* The Create Container operation creates a new container under the specified account. If the
|
||||
|
@ -127,6 +129,15 @@ public interface AzureBlobClient {
|
|||
@ResponseParser(ParseContainerPropertiesFromHeaders.class)
|
||||
ListableContainerProperties getContainerProperties(@PathParam("container") String container);
|
||||
|
||||
/**
|
||||
* Issues a HEAD command to determine if the container exists or not.
|
||||
*/
|
||||
@HEAD
|
||||
@Path("{container}")
|
||||
@QueryParams(keys = "restype", values = "container")
|
||||
@ExceptionParser(ReturnFalseOn404.class)
|
||||
boolean containerExists(@PathParam("container") String container);
|
||||
|
||||
/**
|
||||
* The Set Container Metadata operation sets one or more user-defined name/value pairs for the
|
||||
* specified container. <h4>Remarks</h4>
|
||||
|
@ -290,9 +301,7 @@ public interface AzureBlobClient {
|
|||
* The Get Blob Properties operation returns all user-defined metadata, standard HTTP properties,
|
||||
* and system properties for the blob. It does not return the content of the blob.
|
||||
*/
|
||||
@GET
|
||||
@Headers(keys = "Range", values = "bytes=0-0")
|
||||
// should use HEAD, this is a hack per http://code.google.com/p/jclouds/issues/detail?id=92
|
||||
@HEAD
|
||||
@ResponseParser(ParseBlobPropertiesFromHeaders.class)
|
||||
@ExceptionParser(ThrowKeyNotFoundOn404.class)
|
||||
@Path("{container}/{name}")
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.blobstore.options.ListOptions.Builder.recursive;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.azure.storage.blob.blobstore.functions.AzureBlobToBlob;
|
||||
import org.jclouds.azure.storage.blob.blobstore.functions.BlobPropertiesToBlobMetadata;
|
||||
import org.jclouds.azure.storage.blob.blobstore.functions.BlobToAzureBlob;
|
||||
import org.jclouds.azure.storage.blob.blobstore.functions.BlobToHttpGetOptions;
|
||||
import org.jclouds.azure.storage.blob.blobstore.functions.ContainerToResourceMetadata;
|
||||
import org.jclouds.azure.storage.blob.blobstore.functions.ListBlobsResponseToResourceList;
|
||||
import org.jclouds.azure.storage.blob.blobstore.functions.ListOptionsToListBlobsOptions;
|
||||
import org.jclouds.azure.storage.blob.domain.AzureBlob;
|
||||
import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
|
||||
import org.jclouds.azure.storage.blob.domain.ListableContainerProperties;
|
||||
import org.jclouds.azure.storage.blob.options.ListBlobsOptions;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.attr.ConsistencyModel;
|
||||
import org.jclouds.blobstore.attr.ConsistencyModels;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.BoundedSortedSet;
|
||||
import org.jclouds.blobstore.domain.ResourceMetadata;
|
||||
import org.jclouds.blobstore.options.ListOptions;
|
||||
import org.jclouds.blobstore.strategy.ClearListStrategy;
|
||||
import org.jclouds.concurrent.FutureFunctionWrapper;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.logging.Logger.LoggerFactory;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
@ConsistencyModel(ConsistencyModels.STRICT)
|
||||
public class AzureBlobStore implements BlobStore {
|
||||
private final AzureBlobClient connection;
|
||||
private final Blob.Factory blobFactory;
|
||||
private final LoggerFactory logFactory;
|
||||
private final ClearListStrategy clearContainerStrategy;
|
||||
private final BlobPropertiesToBlobMetadata object2BlobMd;
|
||||
private final AzureBlobToBlob object2Blob;
|
||||
private final BlobToAzureBlob blob2Object;
|
||||
private final ListOptionsToListBlobsOptions container2ContainerListOptions;
|
||||
private final BlobToHttpGetOptions blob2ObjectGetOptions;
|
||||
private final ContainerToResourceMetadata container2ResourceMd;
|
||||
private final ListBlobsResponseToResourceList container2ResourceList;
|
||||
private final ExecutorService service;
|
||||
|
||||
@Inject
|
||||
private AzureBlobStore(AzureBlobClient connection, Blob.Factory blobFactory, LoggerFactory logFactory,
|
||||
ClearListStrategy clearContainerStrategy, BlobPropertiesToBlobMetadata object2BlobMd,
|
||||
AzureBlobToBlob object2Blob, BlobToAzureBlob blob2Object,
|
||||
ListOptionsToListBlobsOptions container2ContainerListOptions,
|
||||
BlobToHttpGetOptions blob2ObjectGetOptions,
|
||||
ContainerToResourceMetadata container2ResourceMd, ListBlobsResponseToResourceList container2ResourceList,
|
||||
ExecutorService service) {
|
||||
this.connection = checkNotNull(connection, "connection");
|
||||
this.blobFactory = checkNotNull(blobFactory, "blobFactory");
|
||||
this.logFactory = checkNotNull(logFactory, "logFactory");
|
||||
this.clearContainerStrategy = checkNotNull(clearContainerStrategy, "clearContainerStrategy");
|
||||
this.object2BlobMd = checkNotNull(object2BlobMd, "object2BlobMd");
|
||||
this.object2Blob = checkNotNull(object2Blob, "object2Blob");
|
||||
this.blob2Object = checkNotNull(blob2Object, "blob2Object");
|
||||
this.container2ContainerListOptions = checkNotNull(container2ContainerListOptions,
|
||||
"container2ContainerListOptions");
|
||||
this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions");
|
||||
this.container2ResourceMd = checkNotNull(container2ResourceMd, "container2ResourceMd");
|
||||
this.container2ResourceList = checkNotNull(container2ResourceList, "container2ResourceList");
|
||||
this.service = checkNotNull(service, "service");
|
||||
}
|
||||
|
||||
protected <F, T> Future<T> wrapFuture(Future<? extends F> future, Function<F, T> function) {
|
||||
return new FutureFunctionWrapper<F, T>(future, function, logFactory.getLogger(function
|
||||
.getClass().getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation uses the AzureBlob HEAD Object command to return the result
|
||||
*/
|
||||
public BlobMetadata blobMetadata(String container, String key) {
|
||||
return object2BlobMd.apply(connection.getBlobProperties(container, key));
|
||||
}
|
||||
|
||||
public Future<Void> clearContainer(final String container) {
|
||||
return service.submit(new Callable<Void>() {
|
||||
|
||||
public Void call() throws Exception {
|
||||
clearContainerStrategy.execute(container, recursive());
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public Future<Boolean> createContainer(String container) {
|
||||
return connection.createContainer(container);
|
||||
}
|
||||
|
||||
public Future<Void> deleteContainer(final String container) {
|
||||
return connection.deleteContainer(container);
|
||||
|
||||
}
|
||||
|
||||
public boolean exists(String container) {
|
||||
return connection.containerExists(container);
|
||||
}
|
||||
|
||||
public Future<Blob> getBlob(String container, String key,
|
||||
org.jclouds.blobstore.options.GetOptions... optionsList) {
|
||||
GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList);
|
||||
Future<AzureBlob> returnVal = connection.getBlob(container, key, httpOptions);
|
||||
return wrapFuture(returnVal, object2Blob);
|
||||
}
|
||||
|
||||
public Future<? extends SortedSet<? extends ResourceMetadata>> list() {
|
||||
return wrapFuture(connection.listContainers(),
|
||||
new Function<SortedSet<ListableContainerProperties>, SortedSet<? extends ResourceMetadata>>() {
|
||||
public SortedSet<? extends ResourceMetadata> apply(SortedSet<ListableContainerProperties> from) {
|
||||
return Sets.newTreeSet(Iterables.transform(from, container2ResourceMd));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Future<? extends BoundedSortedSet<? extends ResourceMetadata>> list(String container,
|
||||
ListOptions... optionsList) {
|
||||
ListBlobsOptions httpOptions = container2ContainerListOptions.apply(optionsList);
|
||||
Future<ListBlobsResponse> returnVal = connection.listBlobs(container, httpOptions);
|
||||
return wrapFuture(returnVal, container2ResourceList);
|
||||
}
|
||||
|
||||
public Future<String> putBlob(String container, Blob blob) {
|
||||
return connection.putBlob(container, blob2Object.apply(blob));
|
||||
}
|
||||
|
||||
public Future<Void> removeBlob(String container, String key) {
|
||||
return connection.deleteBlob(container, key);
|
||||
}
|
||||
|
||||
public Blob newBlob() {
|
||||
return blobFactory.create(null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.azure.storage.blob.blobstore.config.AzureBlobStoreContextModule;
|
||||
import org.jclouds.azure.storage.blob.config.AzureBlobRestClientModule;
|
||||
import org.jclouds.blobstore.BlobStoreContextBuilder;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Creates {@link AzureBlobStoreContext} or {@link Injector} instances based on the most commonly
|
||||
* requested arguments.
|
||||
* <p/>
|
||||
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||
*
|
||||
* @author Adrian Cole, Andrew Newdigate
|
||||
* @see AzureBlobStoreContext
|
||||
*/
|
||||
public class AzureBlobStoreContextBuilder extends BlobStoreContextBuilder<AzureBlobClient> {
|
||||
|
||||
public AzureBlobStoreContextBuilder(Properties props) {
|
||||
super(new TypeLiteral<AzureBlobClient>() {
|
||||
}, props);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureBlobStoreContextBuilder withExecutorService(ExecutorService service) {
|
||||
return (AzureBlobStoreContextBuilder) super.withExecutorService(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureBlobStoreContextBuilder withModules(Module... modules) {
|
||||
return (AzureBlobStoreContextBuilder) super.withModules(modules);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
modules.add(new AzureBlobStoreContextModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addClientModule(List<Module> modules) {
|
||||
modules.add(new AzureBlobRestClientModule());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* Creates {@link AzureBlobStoreContext} instances based on the most commonly requested
|
||||
* arguments.
|
||||
* <p/>
|
||||
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||
*
|
||||
* @author Adrian Cole, Andrew Newdigate
|
||||
* @see AzureBlobStoreContext
|
||||
*/
|
||||
public class AzureBlobStoreContextFactory {
|
||||
public static BlobStoreContext<AzureBlobClient> createContext(Properties properties,
|
||||
Module... modules) {
|
||||
return new AzureBlobStoreContextBuilder(new AzureBlobStorePropertiesBuilder(
|
||||
properties).build()).withModules(modules).buildContext();
|
||||
}
|
||||
|
||||
public static BlobStoreContext<AzureBlobClient> createContext(String user,
|
||||
String encodedKey, Module... modules) {
|
||||
return new AzureBlobStoreContextBuilder(new AzureBlobStorePropertiesBuilder(
|
||||
user, encodedKey).build()).withModules(modules).buildContext();
|
||||
}
|
||||
|
||||
public static BlobStoreContext<AzureBlobClient> createContext(URI endpoint,
|
||||
String user, String encodedKey, Module... modules) {
|
||||
return new AzureBlobStoreContextBuilder(new AzureBlobStorePropertiesBuilder(
|
||||
user, encodedKey).withEndpoint(endpoint).build()).withModules(
|
||||
modules).buildContext();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobPropertiesBuilder;
|
||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||
|
||||
/**
|
||||
* Builds properties used in AzureBlob Blob Stores
|
||||
*
|
||||
* @author Adrian Cole, Andrew Newdigate
|
||||
*/
|
||||
public class AzureBlobStorePropertiesBuilder extends AzureBlobPropertiesBuilder {
|
||||
|
||||
public AzureBlobStorePropertiesBuilder(String id, String secret) {
|
||||
super(id, secret);
|
||||
}
|
||||
|
||||
public AzureBlobStorePropertiesBuilder(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* longest time a single synchronous operation can take before throwing an exception.
|
||||
*/
|
||||
public AzureBlobStorePropertiesBuilder withRequestTimeout(long milliseconds) {
|
||||
properties.setProperty(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT, Long
|
||||
.toString(milliseconds));
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.azure.storage.AzureBlob;
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.azure.storage.blob.blobstore.AzureBlobStore;
|
||||
import org.jclouds.azure.storage.blob.blobstore.strategy.FindMD5InBlobProperties;
|
||||
import org.jclouds.azure.storage.blob.config.AzureBlobModule;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
import org.jclouds.blobstore.BlobMap;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.InputStreamMap;
|
||||
import org.jclouds.blobstore.config.BlobStoreMapModule;
|
||||
import org.jclouds.blobstore.config.BlobStoreObjectModule;
|
||||
import org.jclouds.blobstore.internal.BlobStoreContextImpl;
|
||||
import org.jclouds.blobstore.strategy.ContainsValueInListStrategy;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
* Configures the {@link AzureBlobStoreContext}; requires {@link AzureBlobStore} bound.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class AzureBlobStoreContextModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(new BlobStoreObjectModule());
|
||||
install(new BlobStoreMapModule());
|
||||
install(new AzureBlobModule());
|
||||
bind(BlobStore.class).to(AzureBlobStore.class).asEagerSingleton();
|
||||
bind(ContainsValueInListStrategy.class).to(FindMD5InBlobProperties.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
BlobStoreContext<AzureBlobClient> provideContext(BlobMap.Factory blobMapFactory,
|
||||
InputStreamMap.Factory inputStreamMapFactory, Closer closer, BlobStore blobStore,
|
||||
AzureBlobClient defaultApi, @AzureBlob URI endPoint,
|
||||
@Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT) String account) {
|
||||
return new BlobStoreContextImpl<AzureBlobClient>(blobMapFactory, inputStreamMapFactory,
|
||||
closer, blobStore, defaultApi, endPoint, account);
|
||||
}
|
||||
|
||||
}
|
|
@ -4,29 +4,18 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.azure.storage.blob.domain.BlobProperties;
|
||||
import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class BlobPropertiesToBlobMetadata implements Function<BlobProperties, MutableBlobMetadata> {
|
||||
public class BlobPropertiesToBlobMetadata extends
|
||||
ListableBlobPropertiesToBlobMetadata<BlobProperties> {
|
||||
@Override
|
||||
public MutableBlobMetadata apply(BlobProperties from) {
|
||||
MutableBlobMetadata to = new MutableBlobMetadataImpl();
|
||||
MutableBlobMetadata to = super.apply(from);
|
||||
to.setContentMD5(from.getContentMD5());
|
||||
if (from.getContentType() != null)
|
||||
to.setContentType(from.getContentType());
|
||||
to.setETag(from.getETag());
|
||||
to.setName(from.getName());
|
||||
to.setSize(from.getSize());
|
||||
to.setType(ResourceType.BLOB);
|
||||
to.setUserMetadata(from.getMetadata());
|
||||
if (from.getContentType() != null && from.getContentType().equals("application/directory")) {
|
||||
to.setType(ResourceType.RELATIVE_PATH);
|
||||
}
|
||||
return to;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package org.jclouds.azure.storage.blob.blobstore.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.AzureBlob;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class BlobToAzureBlob implements Function<Blob, AzureBlob> {
|
||||
private final BlobMetadataToBlobProperties blob2ObjectMd;
|
||||
private final AzureBlob.Factory objectProvider;
|
||||
|
||||
@Inject
|
||||
BlobToAzureBlob(BlobMetadataToBlobProperties blob2ObjectMd, AzureBlob.Factory objectProvider) {
|
||||
this.blob2ObjectMd = blob2ObjectMd;
|
||||
this.objectProvider = objectProvider;
|
||||
}
|
||||
|
||||
public AzureBlob apply(Blob from) {
|
||||
AzureBlob object = objectProvider.create(blob2ObjectMd.apply(from.getMetadata()));
|
||||
if (from.getContentLength() != null)
|
||||
object.setContentLength(from.getContentLength());
|
||||
object.setData(from.getData());
|
||||
object.setAllHeaders(from.getAllHeaders());
|
||||
return object;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.Singleton;
|
||||
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class BlobToHttpGetOptions implements
|
||||
Function<org.jclouds.blobstore.options.GetOptions[], GetOptions> {
|
||||
public GetOptions apply(org.jclouds.blobstore.options.GetOptions[] from) {
|
||||
GetOptions httpOptions = new GetOptions();
|
||||
if (from.length != 0) {
|
||||
if (from[0].getIfMatch() != null) {
|
||||
httpOptions.ifETagMatches(from[0].getIfMatch());
|
||||
}
|
||||
if (from[0].getIfModifiedSince() != null) {
|
||||
httpOptions.ifModifiedSince(from[0].getIfModifiedSince());
|
||||
}
|
||||
if (from[0].getIfNoneMatch() != null) {
|
||||
httpOptions.ifETagDoesntMatch(from[0].getIfNoneMatch());
|
||||
}
|
||||
if (from[0].getIfUnmodifiedSince() != null) {
|
||||
httpOptions.ifUnmodifiedSince(from[0].getIfUnmodifiedSince());
|
||||
}
|
||||
for (String range : from[0].getRanges()) {
|
||||
String[] firstLast = range.split("\\-");
|
||||
httpOptions.range(Long.parseLong(firstLast[0]), Long.parseLong(firstLast[1]));
|
||||
}
|
||||
}
|
||||
return httpOptions;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.Singleton;
|
||||
|
||||
import org.jclouds.blobstore.domain.MutableResourceMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableResourceMetadataImpl;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class CommonPrefixesToResourceMetadata implements
|
||||
Function<Iterable<String>, Iterable<ResourceMetadata>> {
|
||||
public Iterable<ResourceMetadata> apply(
|
||||
|
||||
Iterable<String> prefixes) {
|
||||
return Iterables.transform(prefixes, new Function<String, ResourceMetadata>() {
|
||||
public ResourceMetadata apply(String from) {
|
||||
MutableResourceMetadata returnVal = new MutableResourceMetadataImpl();
|
||||
returnVal.setType(ResourceType.RELATIVE_PATH);
|
||||
returnVal.setName(from);
|
||||
return returnVal;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.Singleton;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.ListableContainerProperties;
|
||||
import org.jclouds.blobstore.domain.MutableResourceMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableResourceMetadataImpl;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ContainerToResourceMetadata implements Function<ListableContainerProperties, ResourceMetadata> {
|
||||
public ResourceMetadata apply(ListableContainerProperties from) {
|
||||
MutableResourceMetadata to = new MutableResourceMetadataImpl();
|
||||
to.setName(from.getName());
|
||||
to.setETag(from.getETag());
|
||||
to.setLastModified(from.getLastModified());
|
||||
to.setLocation(from.getUrl());
|
||||
to.setType(ResourceType.CONTAINER);
|
||||
return to;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.Singleton;
|
||||
|
||||
import org.jclouds.azure.storage.blob.options.ListBlobsOptions;
|
||||
import org.jclouds.blobstore.options.ListOptions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ListBlobsOptionsToListOptions implements Function<ListBlobsOptions[], ListOptions> {
|
||||
public ListOptions apply(ListBlobsOptions[] optionsList) {
|
||||
ListOptions options = new ListOptions();
|
||||
if (optionsList.length != 0) {
|
||||
if (optionsList[0].getDelimiter() == null) {
|
||||
options.recursive();
|
||||
} else if (!optionsList[0].getDelimiter().equals("/")) {
|
||||
throw new IllegalArgumentException("only '/' is allowed as a blobstore delimiter");
|
||||
}
|
||||
if (optionsList[0].getMarker() != null) {
|
||||
options.afterMarker(optionsList[0].getMarker());
|
||||
}
|
||||
if (optionsList[0].getMaxResults() != null) {
|
||||
options.maxResults(optionsList[0].getMaxResults());
|
||||
}
|
||||
if (optionsList[0].getPrefix() != null) {
|
||||
options.underPath(optionsList[0].getPrefix());
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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 java.util.SortedSet;
|
||||
|
||||
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.BoundedSortedSet;
|
||||
import org.jclouds.blobstore.domain.ResourceMetadata;
|
||||
import org.jclouds.blobstore.domain.internal.BoundedTreeSet;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ListBlobsResponseToResourceList implements
|
||||
Function<ListBlobsResponse, BoundedSortedSet<? extends ResourceMetadata>> {
|
||||
private final ListableBlobPropertiesToBlobMetadata<ListableBlobProperties> object2blobMd;
|
||||
private final CommonPrefixesToResourceMetadata prefix2ResourceMd;
|
||||
|
||||
@Inject
|
||||
public ListBlobsResponseToResourceList(
|
||||
ListableBlobPropertiesToBlobMetadata<ListableBlobProperties> object2blobMd,
|
||||
CommonPrefixesToResourceMetadata prefix2ResourceMd) {
|
||||
this.object2blobMd = object2blobMd;
|
||||
this.prefix2ResourceMd = prefix2ResourceMd;
|
||||
}
|
||||
|
||||
public BoundedSortedSet<? extends ResourceMetadata> apply(ListBlobsResponse from) {
|
||||
SortedSet<ResourceMetadata> contents = Sets.newTreeSet(Iterables.concat(Iterables.transform(
|
||||
from, object2blobMd), prefix2ResourceMd.apply(from.getBlobPrefixes())));
|
||||
return new BoundedTreeSet<ResourceMetadata>(contents, from.getPrefix(), from.getMarker(),
|
||||
from.getMaxResults(), from.size() == from.getMaxResults());
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.Singleton;
|
||||
|
||||
import org.jclouds.azure.storage.blob.options.ListBlobsOptions;
|
||||
import org.jclouds.blobstore.options.ListOptions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ListOptionsToListBlobsOptions implements Function<ListOptions[], ListBlobsOptions> {
|
||||
public ListBlobsOptions apply(ListOptions[] optionsList) {
|
||||
ListBlobsOptions httpOptions = new ListBlobsOptions();
|
||||
if (optionsList.length != 0) {
|
||||
if (!optionsList[0].isRecursive()) {
|
||||
httpOptions.delimiter("/");
|
||||
}
|
||||
if (optionsList[0].getPath() != null) {
|
||||
httpOptions.prefix(optionsList[0].getPath());
|
||||
}
|
||||
if (optionsList[0].getMarker() != null) {
|
||||
httpOptions.marker(optionsList[0].getMarker());
|
||||
}
|
||||
if (optionsList[0].getMaxResults() != null) {
|
||||
httpOptions.maxResults(optionsList[0].getMaxResults());
|
||||
}
|
||||
}
|
||||
return httpOptions;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package org.jclouds.azure.storage.blob.blobstore.functions;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.ListableBlobProperties;
|
||||
import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ListableBlobPropertiesToBlobMetadata<T extends ListableBlobProperties> implements
|
||||
Function<T, MutableBlobMetadata> {
|
||||
public MutableBlobMetadata apply(T from) {
|
||||
MutableBlobMetadata to = new MutableBlobMetadataImpl();
|
||||
if (from.getContentType() != null)
|
||||
to.setContentType(from.getContentType());
|
||||
to.setETag(from.getETag());
|
||||
to.setName(from.getName());
|
||||
to.setSize(from.getSize());
|
||||
to.setType(ResourceType.BLOB);
|
||||
if (from.getContentType() != null && from.getContentType().equals("application/directory")) {
|
||||
to.setType(ResourceType.RELATIVE_PATH);
|
||||
}
|
||||
return to;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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 java.util.SortedSet;
|
||||
|
||||
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.azure.storage.blob.domain.MutableBlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.TreeSetListBlobsResponse;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.BoundedSortedSet;
|
||||
import org.jclouds.blobstore.domain.ResourceMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceType;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ResourceToListBlobsResponse implements
|
||||
Function<BoundedSortedSet<? extends ResourceMetadata>, ListBlobsResponse> {
|
||||
private final BlobMetadataToBlobProperties blob2ObjectMd;
|
||||
|
||||
@Inject
|
||||
public ResourceToListBlobsResponse(BlobMetadataToBlobProperties blob2ObjectMd) {
|
||||
this.blob2ObjectMd = blob2ObjectMd;
|
||||
}
|
||||
|
||||
public ListBlobsResponse apply(BoundedSortedSet<? extends ResourceMetadata> list) {
|
||||
|
||||
Iterable<ListableBlobProperties> contents = Iterables.transform(Iterables.filter(list,
|
||||
new Predicate<ResourceMetadata>() {
|
||||
|
||||
public boolean apply(ResourceMetadata input) {
|
||||
return input.getType() == ResourceType.BLOB;
|
||||
}
|
||||
|
||||
}), new Function<ResourceMetadata, ListableBlobProperties>() {
|
||||
|
||||
public MutableBlobProperties apply(ResourceMetadata from) {
|
||||
return blob2ObjectMd.apply((BlobMetadata) from);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
SortedSet<String> commonPrefixes = Sets.newTreeSet(Iterables.transform(Iterables.filter(list,
|
||||
new Predicate<ResourceMetadata>() {
|
||||
|
||||
public boolean apply(ResourceMetadata input) {
|
||||
return input.getType() == ResourceType.RELATIVE_PATH;
|
||||
}
|
||||
|
||||
}), new Function<ResourceMetadata, String>() {
|
||||
|
||||
public String apply(ResourceMetadata from) {
|
||||
return from.getName();
|
||||
}
|
||||
|
||||
}));
|
||||
return new TreeSetListBlobsResponse(contents, null, list.getPath(), null, list
|
||||
.getMaxResults(),list.getMarker(), "/", commonPrefixes);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package org.jclouds.azure.storage.blob.blobstore.strategy;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobProperties;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.functions.ObjectMD5;
|
||||
import org.jclouds.blobstore.internal.BlobRuntimeException;
|
||||
import org.jclouds.blobstore.options.ListOptions;
|
||||
import org.jclouds.blobstore.strategy.ContainsValueInListStrategy;
|
||||
import org.jclouds.blobstore.strategy.ListBlobMetadataStrategy;
|
||||
import org.jclouds.util.Utils;
|
||||
|
||||
/**
|
||||
* Searches Content-MD5 tag for the value associated with the value
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class FindMD5InBlobProperties implements ContainsValueInListStrategy {
|
||||
|
||||
protected final ObjectMD5 objectMD5;
|
||||
protected final ListBlobMetadataStrategy getAllBlobMetadata;
|
||||
private final AzureBlobClient client;
|
||||
|
||||
@Inject
|
||||
private FindMD5InBlobProperties(ObjectMD5 objectMD5,
|
||||
ListBlobMetadataStrategy getAllBlobMetadata, AzureBlobClient client) {
|
||||
this.objectMD5 = objectMD5;
|
||||
this.getAllBlobMetadata = getAllBlobMetadata;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public boolean execute(String containerName, Object value, ListOptions options) {
|
||||
try {
|
||||
byte[] toSearch = objectMD5.apply(value);
|
||||
for (BlobMetadata metadata : getAllBlobMetadata.execute(containerName, options)) {
|
||||
BlobProperties properties = client.getBlobProperties(containerName, metadata.getName());
|
||||
if (Arrays.equals(toSearch, properties.getContentMD5()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
throw new BlobRuntimeException(String.format(
|
||||
"Error searching for ETAG of value: [%2$s] in container:%1$s", containerName,
|
||||
value), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -25,13 +25,13 @@ package org.jclouds.azure.storage.blob.domain;
|
|||
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.jclouds.azure.storage.domain.BoundedList;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface ListBlobsResponse extends BoundedList<ListableBlobProperties> {
|
||||
public interface ListBlobsResponse extends BoundedSortedSet<ListableBlobProperties> {
|
||||
|
||||
String getDelimiter();
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ public class TreeSetListBlobsResponse extends BoundedTreeSet<ListableBlobPropert
|
|||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -4475709781001190244L;
|
||||
|
||||
public TreeSetListBlobsResponse(SortedSet<ListableBlobProperties> contents, URI url, String prefix,
|
||||
public TreeSetListBlobsResponse(Iterable<ListableBlobProperties> contents, URI url, String prefix,
|
||||
String marker, Integer maxResults, String nextMarker, String delimiter,
|
||||
SortedSet<String> blobPrefixes) {
|
||||
super(contents, url, prefix, marker, maxResults, nextMarker);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package org.jclouds.azure.storage.blob.blobstore.functions;
|
||||
package org.jclouds.azure.storage.blob.functions;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.AzureBlob;
|
||||
|
|
@ -61,6 +61,10 @@ public class ParseBlobPropertiesFromHeaders implements
|
|||
public MutableBlobProperties apply(HttpResponse from) {
|
||||
BlobMetadata base = blobMetadataParser.apply(from);
|
||||
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.setContentLanguage(from.getFirstHeaderOrNull(HttpHeaders.CONTENT_LANGUAGE));
|
||||
to.setContentEncoding(from.getFirstHeaderOrNull(HttpHeaders.CONTENT_ENCODING));
|
||||
return to;
|
||||
|
|
|
@ -57,6 +57,10 @@ public class ListBlobsOptions extends ListOptions {
|
|||
return this;
|
||||
}
|
||||
|
||||
public String getDelimiter() {
|
||||
return this.getFirstQueryOrNull("delimiter");
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,7 +30,7 @@ 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.BoundedList;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedTreeSet;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.util.DateService;
|
||||
|
@ -47,7 +47,7 @@ import com.google.common.collect.Sets;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class AccountNameEnumerationResultsHandler extends
|
||||
ParseSax.HandlerWithResult<BoundedList<ListableContainerProperties>> {
|
||||
ParseSax.HandlerWithResult<BoundedSortedSet<ListableContainerProperties>> {
|
||||
|
||||
private SortedSet<ListableContainerProperties> containerMetadata = Sets.newTreeSet();
|
||||
private String prefix;
|
||||
|
@ -67,7 +67,7 @@ public class AccountNameEnumerationResultsHandler extends
|
|||
this.dateParser = dateParser;
|
||||
}
|
||||
|
||||
public BoundedList<ListableContainerProperties> getResult() {
|
||||
public BoundedSortedSet<ListableContainerProperties> getResult() {
|
||||
return new BoundedTreeSet<ListableContainerProperties>(containerMetadata, currentUrl, prefix, marker,
|
||||
maxResults, nextMarker);
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ public class ContainerNameEnumerationResultsHandler extends
|
|||
prefix = (prefix.equals("")) ? null : prefix;
|
||||
} else if (qName.equals("Delimiter")) {
|
||||
delimiter = currentText.toString().trim();
|
||||
delimiter = (prefix.equals("")) ? null : delimiter;
|
||||
delimiter = (delimiter.equals("")) ? null : delimiter;
|
||||
} else if (qName.equals("NextMarker")) {
|
||||
nextMarker = currentText.toString().trim();
|
||||
nextMarker = (nextMarker.equals("")) ? null : nextMarker;
|
||||
|
|
|
@ -43,7 +43,7 @@ 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.BoundedList;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
|
@ -78,7 +78,8 @@ public class AzureBlobClientLiveTest {
|
|||
@Test
|
||||
public void testListContainers() throws Exception {
|
||||
|
||||
SortedSet<ListableContainerProperties> response = connection.listContainers();
|
||||
SortedSet<ListableContainerProperties> response = connection.listContainers().get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assert null != response;
|
||||
long initialContainerCount = response.size();
|
||||
assertTrue(initialContainerCount >= 0);
|
||||
|
@ -107,7 +108,8 @@ public class AzureBlobClientLiveTest {
|
|||
throw e;
|
||||
}
|
||||
}
|
||||
SortedSet<ListableContainerProperties> response = connection.listContainers();
|
||||
SortedSet<ListableContainerProperties> response = connection.listContainers().get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assert null != response;
|
||||
long containerCount = response.size();
|
||||
assertTrue(containerCount >= 1);
|
||||
|
@ -175,8 +177,9 @@ public class AzureBlobClientLiveTest {
|
|||
@Test
|
||||
public void testListContainersWithOptions() throws Exception {
|
||||
|
||||
BoundedList<ListableContainerProperties> response = connection
|
||||
.listContainers(ListOptions.Builder.prefix(privateContainer).maxResults(1));
|
||||
BoundedSortedSet<ListableContainerProperties> response = connection.listContainers(
|
||||
ListOptions.Builder.prefix(privateContainer).maxResults(1))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assert null != response;
|
||||
long initialContainerCount = response.size();
|
||||
assertTrue(initialContainerCount >= 0);
|
||||
|
@ -195,18 +198,22 @@ public class AzureBlobClientLiveTest {
|
|||
public void testListOwnedContainers() throws Exception {
|
||||
|
||||
// Test default listing
|
||||
SortedSet<ListableContainerProperties> response = connection.listContainers();
|
||||
SortedSet<ListableContainerProperties> response = connection.listContainers().get(10,
|
||||
TimeUnit.SECONDS);
|
||||
// assertEquals(response.size(), initialContainerCount + 2);// if the containers already
|
||||
// exist, this will fail
|
||||
|
||||
// Test listing with options
|
||||
response = connection.listContainers(ListOptions.Builder.prefix(
|
||||
privateContainer.substring(0, privateContainer.length() - 1)).maxResults(1));
|
||||
response = connection
|
||||
.listContainers(
|
||||
ListOptions.Builder.prefix(
|
||||
privateContainer.substring(0, privateContainer.length() - 1))
|
||||
.maxResults(1)).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(response.size(), 1);
|
||||
assertEquals(response.first().getName(), privateContainer);
|
||||
|
||||
response = connection.listContainers(ListOptions.Builder.prefix(publicContainer)
|
||||
.maxResults(1));
|
||||
response = connection.listContainers(
|
||||
ListOptions.Builder.prefix(publicContainer).maxResults(1)).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(response.size(), 1);
|
||||
assertEquals(response.first().getName(), publicContainer);
|
||||
|
||||
|
@ -273,7 +280,7 @@ public class AzureBlobClientLiveTest {
|
|||
// Multimap<String, String> userMetadata = HashMultimap.create();
|
||||
// userMetadata.put("New-Metadata-1", "value-1");
|
||||
// userMetadata.put("New-Metadata-2", "value-2");
|
||||
// assertTrue(connection.setObjectMetadata(privateContainer, object.getProperties().getName(),
|
||||
// assertTrue(connection.setBlobProperties(privateContainer, object.getProperties().getName(),
|
||||
// userMetadata));
|
||||
|
||||
// Test GET of missing object
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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;
|
||||
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.azure.storage.blob.blobstore.config.AzureBlobStoreContextModule;
|
||||
import org.jclouds.azure.storage.blob.config.AzureBlobRestClientModule;
|
||||
import org.jclouds.azure.storage.blob.config.AzureBlobStubClientModule;
|
||||
import org.jclouds.azure.storage.blob.domain.AzureBlob;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.AzureBlobImpl;
|
||||
import org.jclouds.azure.storage.blob.internal.StubAzureBlobClient;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.internal.BlobImpl;
|
||||
import org.jclouds.blobstore.internal.BlobStoreContextImpl;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Tests behavior of modules configured in AzureBlobContextBuilder
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "azureblob.AzureBlobContextBuilderTest")
|
||||
public class AzureBlobStoreContextBuilderTest {
|
||||
|
||||
public void testNewBuilder() {
|
||||
AzureBlobStoreContextBuilder builder = newBuilder();
|
||||
assertEquals(builder.getProperties().getProperty(PROPERTY_USER_METADATA_PREFIX),
|
||||
"x-ms-meta-");
|
||||
assertEquals(builder.getProperties().getProperty(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT),
|
||||
"id");
|
||||
assertEquals(builder.getProperties().getProperty(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY),
|
||||
"secret");
|
||||
}
|
||||
|
||||
private AzureBlobStoreContextBuilder newBuilder() {
|
||||
return new AzureBlobStoreContextBuilder(new AzureBlobStorePropertiesBuilder("id",
|
||||
"secret").build()).withModules(new AzureBlobStubClientModule());
|
||||
}
|
||||
|
||||
public void testBuildContext() {
|
||||
BlobStoreContext<AzureBlobClient> context = newBuilder().buildContext();
|
||||
assertEquals(context.getClass(), BlobStoreContextImpl.class);
|
||||
assertEquals(context.getApi().getClass(), StubAzureBlobClient.class);
|
||||
assertEquals(context.getBlobStore().getClass(), AzureBlobStore.class);
|
||||
assertEquals(context.getApi().newBlob().getClass(), AzureBlobImpl.class);
|
||||
assertEquals(context.getBlobStore().newBlob().getClass(), BlobImpl.class);
|
||||
assertEquals(context.getAccount(), "id");
|
||||
assertEquals(context.getEndPoint(), URI.create("https://localhost/azurestub"));
|
||||
}
|
||||
|
||||
public void testBuildInjector() {
|
||||
Injector i = newBuilder().buildInjector();
|
||||
assert i.getInstance(Key.get(new TypeLiteral<BlobStoreContext<AzureBlobClient>>() {
|
||||
})) != null;
|
||||
assert i.getInstance(AzureBlob.class) != null;
|
||||
assert i.getInstance(Blob.class) != null;
|
||||
}
|
||||
|
||||
protected void testAddContextModule() {
|
||||
List<Module> modules = new ArrayList<Module>();
|
||||
AzureBlobStoreContextBuilder builder = newBuilder();
|
||||
builder.addContextModule(modules);
|
||||
assertEquals(modules.size(), 1);
|
||||
assertEquals(modules.get(0).getClass(), AzureBlobStoreContextModule.class);
|
||||
}
|
||||
|
||||
protected void addClientModule() {
|
||||
List<Module> modules = new ArrayList<Module>();
|
||||
AzureBlobStoreContextBuilder builder = newBuilder();
|
||||
builder.addClientModule(modules);
|
||||
assertEquals(modules.size(), 1);
|
||||
assertEquals(modules.get(0).getClass(), AzureBlobRestClientModule.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.azure.storage.blob.blobstore.strategy.FindMD5InBlobProperties;
|
||||
import org.jclouds.azure.storage.blob.config.AzureBlobStubClientModule;
|
||||
import org.jclouds.azure.storage.blob.reference.AzureBlobConstants;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.internal.BlobStoreContextImpl;
|
||||
import org.jclouds.blobstore.strategy.ContainsValueInListStrategy;
|
||||
import org.jclouds.concurrent.WithinThreadExecutorService;
|
||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
import org.jclouds.util.Jsr330;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "azureblob.AzureBlobStoreModuleTest")
|
||||
public class AzureBlobStoreModuleTest {
|
||||
|
||||
Injector createInjector() {
|
||||
return Guice.createInjector(new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||
new JDKLoggingModule(), new AzureBlobStubClientModule(),
|
||||
new AzureBlobStoreContextModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT))
|
||||
.to("user");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to(
|
||||
"key");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT)).to(
|
||||
"http://localhost");
|
||||
super.configure();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testContextImpl() {
|
||||
|
||||
Injector injector = createInjector();
|
||||
BlobStoreContext<AzureBlobClient> handler = injector.getInstance(Key
|
||||
.get(new TypeLiteral<BlobStoreContext<AzureBlobClient>>() {
|
||||
}));
|
||||
assertEquals(handler.getClass(), BlobStoreContextImpl.class);
|
||||
ContainsValueInListStrategy valueList = injector
|
||||
.getInstance(ContainsValueInListStrategy.class);
|
||||
|
||||
assertEquals(valueList.getClass(), FindMD5InBlobProperties.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.integration;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author James Murty
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "integration", "live" }, testName = "azureblob.AzureBlobContainerIntegrationTest")
|
||||
public class AzureBlobContainerIntegrationTest extends BaseContainerIntegrationTest<AzureBlobClient> {
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.integration;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.blobstore.integration.internal.BaseContainerLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "live" }, testName = "azureblob.AzureBlobContainerLiveTest")
|
||||
public class AzureBlobContainerLiveTest extends BaseContainerLiveTest<AzureBlobClient> {
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.integration;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.blobstore.integration.internal.BaseInputStreamMapIntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "integration", "live" }, testName = "azureblob.AzureBlobInputStreamMapIntegrationTest")
|
||||
public class AzureBlobInputStreamMapIntegrationTest extends
|
||||
BaseInputStreamMapIntegrationTest<AzureBlobClient> {
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.integration;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "integration", "live" }, testName = "azureblob.AzureBlobIntegrationTest")
|
||||
public class AzureBlobIntegrationTest extends BaseBlobIntegrationTest<AzureBlobClient> {
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.integration;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "live" }, testName = "azureblob.AzureBlobLiveTest")
|
||||
public class AzureBlobLiveTest extends BaseBlobLiveTest<AzureBlobClient> {
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.integration;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobMapIntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "integration", "live" }, testName = "azureblob.AzureBlobMapIntegrationTest")
|
||||
public class AzureBlobMapIntegrationTest extends BaseBlobMapIntegrationTest<AzureBlobClient> {
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.integration;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.blobstore.integration.internal.BaseServiceIntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "integration", "live" }, testName = "azureblob.AzureBlobServiceIntegrationTest")
|
||||
public class AzureBlobServiceIntegrationTest extends BaseServiceIntegrationTest<AzureBlobClient> {
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.integration;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.azure.storage.blob.blobstore.AzureBlobStoreContextBuilder;
|
||||
import org.jclouds.azure.storage.blob.blobstore.AzureBlobStoreContextFactory;
|
||||
import org.jclouds.azure.storage.blob.blobstore.AzureBlobStorePropertiesBuilder;
|
||||
import org.jclouds.azure.storage.blob.config.AzureBlobStubClientModule;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.integration.internal.BaseTestInitializer;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class AzureBlobTestInitializer extends BaseTestInitializer<AzureBlobClient> {
|
||||
|
||||
@Override
|
||||
protected BlobStoreContext<AzureBlobClient> createLiveContext(Module configurationModule,
|
||||
String url, String app, String account, String key) {
|
||||
return new AzureBlobStoreContextBuilder(new AzureBlobStorePropertiesBuilder(
|
||||
account, key).relaxSSLHostname().build()).withModules(configurationModule,
|
||||
new Log4JLoggingModule()).buildContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlobStoreContext<AzureBlobClient> createStubContext() {
|
||||
return AzureBlobStoreContextFactory.createContext("user", "pass",
|
||||
new AzureBlobStubClientModule());
|
||||
}
|
||||
|
||||
}
|
|
@ -21,13 +21,13 @@
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.azure.storage.blob;
|
||||
package org.jclouds.azure.storage.blob.config;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.azure.storage.blob.config.AzureBlobContextModule;
|
||||
import org.jclouds.azure.storage.blob.config.AzureBlobStubClientModule;
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.azure.storage.blob.reference.AzureBlobConstants;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.internal.RestContextImpl;
|
||||
import org.jclouds.util.Jsr330;
|
||||
|
@ -45,27 +45,28 @@ import com.google.inject.TypeLiteral;
|
|||
public class AzureBlobContextModuleTest {
|
||||
|
||||
Injector createInjector() {
|
||||
return Guice.createInjector(new AzureBlobStubClientModule(), new AzureBlobContextModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureBlobConstants.PROPERTY_AZURESTORAGE_ACCOUNT)).to("user");
|
||||
bindConstant()
|
||||
.annotatedWith(Jsr330.named(AzureBlobConstants.PROPERTY_AZURESTORAGE_KEY)).to(
|
||||
"key");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT)).to(
|
||||
"http://localhost");
|
||||
super.configure();
|
||||
}
|
||||
});
|
||||
return Guice.createInjector(new AzureBlobStubClientModule(), new JDKLoggingModule(),
|
||||
new AzureBlobContextModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureBlobConstants.PROPERTY_AZURESTORAGE_ACCOUNT)).to(
|
||||
"user");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureBlobConstants.PROPERTY_AZURESTORAGE_KEY)).to("key");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT)).to(
|
||||
"http://localhost");
|
||||
super.configure();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testContextImpl() {
|
||||
|
||||
RestContext<AzureBlobClient> handler = createInjector().getInstance(
|
||||
Key.get(new TypeLiteral<RestContext<AzureBlobClient>>() {
|
||||
Injector injector = createInjector();
|
||||
RestContext<AzureBlobClient> handler = injector.getInstance(Key
|
||||
.get(new TypeLiteral<RestContext<AzureBlobClient>>() {
|
||||
}));
|
||||
assertEquals(handler.getClass(), RestContextImpl.class);
|
||||
|
|
@ -1,20 +1,44 @@
|
|||
package org.jclouds.azure.storage.blob.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||
import org.jclouds.azure.storage.blob.blobstore.functions.AzureBlobToBlob;
|
||||
import org.jclouds.azure.storage.blob.blobstore.functions.BlobMetadataToBlobProperties;
|
||||
import org.jclouds.azure.storage.blob.blobstore.functions.BlobToAzureBlob;
|
||||
import org.jclouds.azure.storage.blob.blobstore.functions.ListBlobsOptionsToListOptions;
|
||||
import org.jclouds.azure.storage.blob.blobstore.functions.ResourceToListBlobsResponse;
|
||||
import org.jclouds.azure.storage.blob.domain.AzureBlob;
|
||||
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.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.BoundedList;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedTreeSet;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.blobstore.attr.ConsistencyModel;
|
||||
import org.jclouds.blobstore.attr.ConsistencyModels;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions;
|
||||
import org.jclouds.blobstore.integration.internal.StubBlobStore;
|
||||
import org.jclouds.blobstore.integration.internal.StubBlobStore.FutureBase;
|
||||
import org.jclouds.concurrent.FutureFunctionWrapper;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.logging.Logger.LoggerFactory;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* Implementation of {@link AzureBlobClient} which keeps all data in a local Map object.
|
||||
|
@ -23,9 +47,45 @@ import org.jclouds.http.options.GetOptions;
|
|||
*/
|
||||
@ConsistencyModel(ConsistencyModels.STRICT)
|
||||
public class StubAzureBlobClient implements AzureBlobClient {
|
||||
private final HttpGetOptionsListToGetOptions httpGetOptionsConverter;
|
||||
private final StubBlobStore blobStore;
|
||||
private final LoggerFactory logFactory;
|
||||
private final AzureBlob.Factory objectProvider;
|
||||
private final AzureBlobToBlob object2Blob;
|
||||
private final BlobToAzureBlob blob2Object;
|
||||
private final BlobMetadataToBlobProperties blob2ObjectInfo;
|
||||
private final ListBlobsOptionsToListOptions container2ContainerListOptions;
|
||||
private final ResourceToListBlobsResponse resource2ObjectList;
|
||||
private final ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs;
|
||||
|
||||
@Inject
|
||||
private StubAzureBlobClient(StubBlobStore blobStore, LoggerFactory logFactory,
|
||||
ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs,
|
||||
AzureBlob.Factory objectProvider,
|
||||
HttpGetOptionsListToGetOptions httpGetOptionsConverter, AzureBlobToBlob object2Blob,
|
||||
BlobToAzureBlob blob2Object, BlobMetadataToBlobProperties blob2ObjectInfo,
|
||||
ListBlobsOptionsToListOptions container2ContainerListOptions,
|
||||
ResourceToListBlobsResponse resource2ContainerList) {
|
||||
this.logFactory = logFactory;
|
||||
this.containerToBlobs = containerToBlobs;
|
||||
this.blobStore = blobStore;
|
||||
this.objectProvider = objectProvider;
|
||||
this.httpGetOptionsConverter = httpGetOptionsConverter;
|
||||
this.object2Blob = checkNotNull(object2Blob, "object2Blob");
|
||||
this.blob2Object = checkNotNull(blob2Object, "blob2Object");
|
||||
this.blob2ObjectInfo = checkNotNull(blob2ObjectInfo, "blob2ObjectInfo");
|
||||
this.container2ContainerListOptions = checkNotNull(container2ContainerListOptions,
|
||||
"container2ContainerListOptions");
|
||||
this.resource2ObjectList = checkNotNull(resource2ContainerList, "resource2ContainerList");
|
||||
}
|
||||
|
||||
protected <F, T> Future<T> wrapFuture(Future<? extends F> future, Function<F, T> function) {
|
||||
return new FutureFunctionWrapper<F, T>(future, function, logFactory.getLogger(function
|
||||
.getClass().getName()));
|
||||
}
|
||||
|
||||
public Future<Boolean> createContainer(String container, CreateContainerOptions... options) {
|
||||
throw new UnsupportedOperationException();
|
||||
return blobStore.createContainer(container);
|
||||
}
|
||||
|
||||
public Future<Boolean> createRootContainer(CreateContainerOptions... options) {
|
||||
|
@ -33,11 +93,16 @@ public class StubAzureBlobClient implements AzureBlobClient {
|
|||
}
|
||||
|
||||
public Future<Void> deleteBlob(String container, String key) {
|
||||
throw new UnsupportedOperationException();
|
||||
return blobStore.removeBlob(container, key);
|
||||
}
|
||||
|
||||
public Future<Void> deleteContainer(String container) {
|
||||
throw new UnsupportedOperationException();
|
||||
public Future<Void> deleteContainer(final String container) {
|
||||
return new FutureBase<Void>() {
|
||||
public Void get() throws InterruptedException, ExecutionException {
|
||||
StubAzureBlobClient.this.containerToBlobs.remove(container);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Future<Boolean> deleteRootContainer() {
|
||||
|
@ -45,35 +110,53 @@ public class StubAzureBlobClient implements AzureBlobClient {
|
|||
}
|
||||
|
||||
public Future<AzureBlob> getBlob(String container, String key, GetOptions... options) {
|
||||
throw new UnsupportedOperationException();
|
||||
org.jclouds.blobstore.options.GetOptions getOptions = httpGetOptionsConverter.apply(options);
|
||||
return wrapFuture(blobStore.getBlob(container, key, getOptions), blob2Object);
|
||||
}
|
||||
|
||||
public BlobProperties getBlobProperties(String container, String key) {
|
||||
throw new UnsupportedOperationException();
|
||||
return blob2ObjectInfo.apply(blobStore.blobMetadata(container, key));
|
||||
}
|
||||
|
||||
public ListableContainerProperties getContainerProperties(String container) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Future<ListBlobsResponse> listBlobs(String container, ListBlobsOptions... options) {
|
||||
throw new UnsupportedOperationException();
|
||||
public Future<ListBlobsResponse> listBlobs(String container, ListBlobsOptions... optionsList) {
|
||||
org.jclouds.blobstore.options.ListOptions options = container2ContainerListOptions
|
||||
.apply(optionsList);
|
||||
return wrapFuture(blobStore.list(container, options), resource2ObjectList);
|
||||
}
|
||||
|
||||
public Future<ListBlobsResponse> listBlobs(ListBlobsOptions... options) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public BoundedList<ListableContainerProperties> listContainers(ListOptions... listOptions) {
|
||||
throw new UnsupportedOperationException();
|
||||
public Future<? extends BoundedSortedSet<ListableContainerProperties>> listContainers(
|
||||
ListOptions... listOptions) {
|
||||
return new FutureBase<BoundedSortedSet<ListableContainerProperties>>() {
|
||||
|
||||
public BoundedSortedSet<ListableContainerProperties> get() throws InterruptedException,
|
||||
ExecutionException {
|
||||
return new BoundedTreeSet<ListableContainerProperties>(Iterables.transform(blobStore
|
||||
.getContainerToBlobs().keySet(),
|
||||
new Function<String, ListableContainerProperties>() {
|
||||
public ListableContainerProperties apply(String name) {
|
||||
return new ListableContainerPropertiesImpl(URI.create("http://stub/"
|
||||
+ name), new DateTime(), "");
|
||||
}
|
||||
|
||||
}), null, null, null, null, null);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public AzureBlob newBlob() {
|
||||
throw new UnsupportedOperationException();
|
||||
return objectProvider.create(null);
|
||||
}
|
||||
|
||||
public Future<String> putBlob(String container, AzureBlob object) {
|
||||
throw new UnsupportedOperationException();
|
||||
return blobStore.putBlob(container, object2Blob.apply(object));
|
||||
}
|
||||
|
||||
public void setBlobMetadata(String container, String key, Map<String, String> metadata) {
|
||||
|
@ -84,4 +167,8 @@ public class StubAzureBlobClient implements AzureBlobClient {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean containerExists(String container) {
|
||||
return blobStore.getContainerToBlobs().containsKey(container);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ 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.BoundedList;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedTreeSet;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.jclouds.util.DateService;
|
||||
|
@ -70,11 +70,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"));
|
||||
BoundedList<ListableContainerProperties> list = new BoundedTreeSet<ListableContainerProperties>(
|
||||
BoundedSortedSet<ListableContainerProperties> list = new BoundedTreeSet<ListableContainerProperties>(
|
||||
contents, URI.create("http://myaccount.blob.core.windows.net/"), null, null, 3,
|
||||
"video");
|
||||
|
||||
BoundedList<ListableContainerProperties> result = (BoundedList<ListableContainerProperties>) factory
|
||||
BoundedSortedSet<ListableContainerProperties> result = (BoundedSortedSet<ListableContainerProperties>) factory
|
||||
.create(injector.getInstance(AccountNameEnumerationResultsHandler.class)).parse(is);
|
||||
|
||||
assertEquals(result, list);
|
||||
|
@ -92,10 +92,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("/test_list_containers_options.xml");
|
||||
BoundedList<ListableContainerProperties> list = new BoundedTreeSet<ListableContainerProperties>(
|
||||
BoundedSortedSet<ListableContainerProperties> list = new BoundedTreeSet<ListableContainerProperties>(
|
||||
contents, URI.create("http://myaccount.blob.core.windows.net"), "prefix", "marker",
|
||||
1, "video");
|
||||
BoundedList<ListableContainerProperties> result = (BoundedList<ListableContainerProperties>) factory
|
||||
BoundedSortedSet<ListableContainerProperties> result = (BoundedSortedSet<ListableContainerProperties>) factory
|
||||
.create(injector.getInstance(AccountNameEnumerationResultsHandler.class)).parse(is);
|
||||
assertEquals(result, list);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ import java.util.SortedSet;
|
|||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public interface BoundedList<T> extends SortedSet<T> {
|
||||
public interface BoundedSortedSet<T> extends SortedSet<T> {
|
||||
URI getUrl();
|
||||
|
||||
String getPrefix();
|
|
@ -24,17 +24,18 @@
|
|||
package org.jclouds.azure.storage.domain.internal;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.jclouds.azure.storage.domain.BoundedList;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public class BoundedTreeSet<T> extends TreeSet<T> implements BoundedList<T> {
|
||||
public class BoundedTreeSet<T> extends TreeSet<T> implements BoundedSortedSet<T> {
|
||||
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -7133632087734650835L;
|
||||
|
@ -44,9 +45,9 @@ public class BoundedTreeSet<T> extends TreeSet<T> implements BoundedList<T> {
|
|||
protected final Integer maxResults;
|
||||
protected final String nextMarker;
|
||||
|
||||
public BoundedTreeSet(SortedSet<T> contents, URI url, String prefix, String marker,
|
||||
public BoundedTreeSet(Iterable<T> contents, URI url, String prefix, String marker,
|
||||
Integer maxResults, String nextMarker) {
|
||||
this.addAll(contents);
|
||||
Iterables.addAll(this, contents);
|
||||
this.url = url;
|
||||
this.prefix = prefix;
|
||||
this.nextMarker = nextMarker;
|
||||
|
|
|
@ -45,6 +45,10 @@ public class ListOptions extends BaseHttpRequestOptions {
|
|||
return this;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return getFirstQueryOrNull("prefix");
|
||||
}
|
||||
|
||||
/**
|
||||
* A string value that identifies the portion of the list to be returned with the next list
|
||||
* operation. The operation returns a marker value within the response body if the list returned
|
||||
|
@ -58,6 +62,10 @@ public class ListOptions extends BaseHttpRequestOptions {
|
|||
return this;
|
||||
}
|
||||
|
||||
public String getMarker() {
|
||||
return getFirstQueryOrNull("marker");
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the maximum number of containers to return. If maxresults is not specified, the
|
||||
* server will return up to 5,000 items. If the parameter is set to a value greater than 5,000,
|
||||
|
@ -70,6 +78,11 @@ public class ListOptions extends BaseHttpRequestOptions {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Integer getMaxResults() {
|
||||
String maxresults = getFirstQueryOrNull("maxresults");
|
||||
return (maxresults != null) ? new Integer(maxresults) : null;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,7 +33,7 @@ import javax.ws.rs.Path;
|
|||
import javax.ws.rs.PathParam;
|
||||
|
||||
import org.jclouds.azure.storage.AzureQueue;
|
||||
import org.jclouds.azure.storage.domain.BoundedList;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
|
||||
import org.jclouds.azure.storage.options.CreateOptions;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
|
@ -85,7 +85,7 @@ public interface AzureQueueClient {
|
|||
@XMLResponseParser(AccountNameEnumerationResultsHandler.class)
|
||||
@Path("/")
|
||||
@QueryParams(keys = "comp", values = "list")
|
||||
BoundedList<QueueMetadata> listQueues(ListOptions... listOptions);
|
||||
BoundedSortedSet<QueueMetadata> listQueues(ListOptions... listOptions);
|
||||
|
||||
/**
|
||||
* The Create Queue operation creates a new queue under the specified account.
|
||||
|
|
|
@ -29,7 +29,7 @@ import java.util.TreeSet;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.azure.storage.domain.BoundedList;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedTreeSet;
|
||||
import org.jclouds.azure.storage.queue.domain.QueueMetadata;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
|
@ -43,7 +43,7 @@ import org.jclouds.http.functions.ParseSax;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class AccountNameEnumerationResultsHandler extends
|
||||
ParseSax.HandlerWithResult<BoundedList<QueueMetadata>> {
|
||||
ParseSax.HandlerWithResult<BoundedSortedSet<QueueMetadata>> {
|
||||
|
||||
private SortedSet<QueueMetadata> metadata = new TreeSet<QueueMetadata>();
|
||||
private URI currentUrl;
|
||||
|
@ -59,7 +59,7 @@ public class AccountNameEnumerationResultsHandler extends
|
|||
public AccountNameEnumerationResultsHandler() {
|
||||
}
|
||||
|
||||
public BoundedList<QueueMetadata> getResult() {
|
||||
public BoundedSortedSet<QueueMetadata> getResult() {
|
||||
return new BoundedTreeSet<QueueMetadata>(metadata, currentUrl, prefix, marker, maxResults,
|
||||
nextMarker);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import static org.testng.Assert.assertTrue;
|
|||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import org.jclouds.azure.storage.domain.BoundedList;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.options.CreateOptions;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.azure.storage.queue.domain.QueueMetadata;
|
||||
|
@ -67,7 +67,7 @@ public class AzureQueueClientLiveTest {
|
|||
@Test
|
||||
public void testListQueues() throws Exception {
|
||||
|
||||
BoundedList<QueueMetadata> response = connection.listQueues();
|
||||
BoundedSortedSet<QueueMetadata> response = connection.listQueues();
|
||||
assert null != response;
|
||||
long initialQueueCount = response.size();
|
||||
assertTrue(initialQueueCount >= 0);
|
||||
|
@ -93,7 +93,7 @@ public class AzureQueueClientLiveTest {
|
|||
throw e;
|
||||
}
|
||||
}
|
||||
BoundedList<QueueMetadata> response = connection.listQueues();
|
||||
BoundedSortedSet<QueueMetadata> response = connection.listQueues();
|
||||
assert null != response;
|
||||
long queueCount = response.size();
|
||||
assertTrue(queueCount >= 1);
|
||||
|
@ -103,7 +103,7 @@ public class AzureQueueClientLiveTest {
|
|||
@Test
|
||||
public void testListQueuesWithOptions() throws Exception {
|
||||
|
||||
BoundedList<QueueMetadata> response = connection.listQueues(ListOptions.Builder.prefix(
|
||||
BoundedSortedSet<QueueMetadata> response = connection.listQueues(ListOptions.Builder.prefix(
|
||||
privateQueue).maxResults(1));
|
||||
assert null != response;
|
||||
long initialQueueCount = response.size();
|
||||
|
|
|
@ -28,7 +28,7 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.azure.storage.domain.BoundedList;
|
||||
import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||
import org.jclouds.azure.storage.domain.internal.BoundedTreeSet;
|
||||
import org.jclouds.azure.storage.queue.domain.QueueMetadata;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
|
@ -46,24 +46,24 @@ public class AccountNameEnumerationResultsHandlerTest extends BaseHandlerTest {
|
|||
|
||||
public void testApplyInputStream() {
|
||||
InputStream is = getClass().getResourceAsStream("/test_list_queues.xml");
|
||||
BoundedList<QueueMetadata> list = new BoundedTreeSet<QueueMetadata>(ImmutableSortedSet.of(
|
||||
BoundedSortedSet<QueueMetadata> list = new BoundedTreeSet<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");
|
||||
BoundedList<QueueMetadata> result = (BoundedList<QueueMetadata>) factory.create(
|
||||
BoundedSortedSet<QueueMetadata> result = (BoundedSortedSet<QueueMetadata>) factory.create(
|
||||
injector.getInstance(AccountNameEnumerationResultsHandler.class)).parse(is);
|
||||
assertEquals(result, list);
|
||||
}
|
||||
|
||||
public void testApplyInputStreamWithOptions() {
|
||||
InputStream is = getClass().getResourceAsStream("/test_list_queues_options.xml");
|
||||
BoundedList<QueueMetadata> list = new BoundedTreeSet<QueueMetadata>(ImmutableSortedSet.of(
|
||||
BoundedSortedSet<QueueMetadata> list = new BoundedTreeSet<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);
|
||||
|
||||
BoundedList<QueueMetadata> result = (BoundedList<QueueMetadata>) factory.create(
|
||||
BoundedSortedSet<QueueMetadata> result = (BoundedSortedSet<QueueMetadata>) factory.create(
|
||||
injector.getInstance(AccountNameEnumerationResultsHandler.class)).parse(is);
|
||||
|
||||
assertEquals(result, list);
|
||||
|
|
Loading…
Reference in New Issue