mirror of https://github.com/apache/jclouds.git
tuned timestamp logic
git-svn-id: http://jclouds.googlecode.com/svn/trunk@1982 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
b4a4bedcc3
commit
e939114702
|
@ -26,6 +26,7 @@ package org.jclouds.aws.s3;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_ACCESSKEYID;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY;
|
||||
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SESSIONINTERVAL;
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
|
||||
import java.net.URI;
|
||||
|
@ -76,6 +77,8 @@ public class S3ContextBuilder extends
|
|||
}, props);
|
||||
properties.setProperty(S3Constants.PROPERTY_S3_ENDPOINT, "https://s3.amazonaws.com");
|
||||
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-amz-meta-");
|
||||
if (!properties.containsKey(PROPERTY_S3_SESSIONINTERVAL))
|
||||
this.withTimeStampExpiration(60);
|
||||
}
|
||||
|
||||
public S3ContextBuilder(String id, String secret) {
|
||||
|
@ -162,4 +165,8 @@ public class S3ContextBuilder extends
|
|||
modules.add(new RestS3ConnectionModule());
|
||||
}
|
||||
|
||||
public S3ContextBuilder withTimeStampExpiration(long seconds) {
|
||||
getProperties().setProperty(PROPERTY_S3_SESSIONINTERVAL, seconds + "");
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
package org.jclouds.aws.s3.config;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
@ -48,7 +50,11 @@ import org.jclouds.http.annotation.ClientError;
|
|||
import org.jclouds.http.annotation.Redirection;
|
||||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.rest.RestClientFactory;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.jclouds.util.TimeStamp;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.MapMaker;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Scopes;
|
||||
|
@ -62,6 +68,28 @@ import com.google.inject.Scopes;
|
|||
@RequiresHttp
|
||||
public class RestS3ConnectionModule extends AbstractModule {
|
||||
|
||||
@Provides
|
||||
@TimeStamp
|
||||
protected String provideTimeStamp(@TimeStamp ConcurrentMap<String, String> cache) {
|
||||
return cache.get("doesn't matter");
|
||||
}
|
||||
|
||||
/**
|
||||
* borrowing concurrency code to ensure that caching takes place properly
|
||||
*/
|
||||
@Provides
|
||||
@TimeStamp
|
||||
ConcurrentMap<String, String> provideTimeStampCache(
|
||||
@Named(S3Constants.PROPERTY_S3_SESSIONINTERVAL) long seconds,
|
||||
final DateService dateService) {
|
||||
return new MapMaker().expiration(seconds, TimeUnit.SECONDS).makeComputingMap(
|
||||
new Function<String, String>() {
|
||||
public String apply(String key) {
|
||||
return dateService.rfc822DateFormat();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(RequestAuthorizeSignature.class).in(Scopes.SINGLETON);
|
||||
|
@ -78,7 +106,8 @@ public class RestS3ConnectionModule extends AbstractModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected BlobStore<BucketMetadata, ObjectMetadata, S3Object> provideS3BlobStore(RestClientFactory factory) {
|
||||
protected BlobStore<BucketMetadata, ObjectMetadata, S3Object> provideS3BlobStore(
|
||||
RestClientFactory factory) {
|
||||
return factory.create(S3BlobStore.class);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,11 +29,10 @@ import java.util.Collection;
|
|||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
|
@ -42,12 +41,12 @@ import org.jclouds.http.HttpException;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.jclouds.util.TimeStamp;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* Signs the S3 request. This will update timestamps at most once per second.
|
||||
* Signs the S3 request.
|
||||
*
|
||||
* @see <a href= "http://docs.amazonwebservices.com/AmazonS3/latest/RESTAuthentication.html" />
|
||||
* @author Adrian Cole
|
||||
|
@ -60,46 +59,15 @@ public class RequestAuthorizeSignature implements HttpRequestFilter {
|
|||
|
||||
private final String accessKey;
|
||||
private final String secretKey;
|
||||
private final DateService dateService;
|
||||
|
||||
public final long BILLION = 1000000000;
|
||||
private final AtomicReference<String> timeStamp;
|
||||
private final AtomicLong trigger = new AtomicLong(System.nanoTime() + 1 * BILLION);
|
||||
|
||||
/**
|
||||
* Start the time update service. Amazon clocks need to be within 900 seconds of the request
|
||||
* time. This method updates the clock every second. This is not performed per-request, as
|
||||
* creation of the date object is a slow, synchronized command.
|
||||
*/
|
||||
synchronized void updateIfTimeOut() {
|
||||
|
||||
if (trigger.get() - System.nanoTime() <= 0) {
|
||||
timeStamp.set(createNewStamp());
|
||||
trigger.set(System.nanoTime() + 1 * BILLION);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// this is a hotspot when submitted concurrently, so be lazy.
|
||||
// amazon is ok with up to 15 minutes off their time, so let's
|
||||
// be as lazy as possible.
|
||||
String createNewStamp() {
|
||||
return dateService.rfc822DateFormat();
|
||||
}
|
||||
|
||||
public String timestampAsHeaderString() {
|
||||
updateIfTimeOut();
|
||||
return timeStamp.get();
|
||||
}
|
||||
private final Provider<String> timeStampProvider;
|
||||
|
||||
@Inject
|
||||
public RequestAuthorizeSignature(@Named(S3Constants.PROPERTY_AWS_ACCESSKEYID) String accessKey,
|
||||
@Named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY) String secretKey,
|
||||
DateService dateService) {
|
||||
@TimeStamp Provider<String> timeStampProvider) {
|
||||
this.accessKey = accessKey;
|
||||
this.secretKey = secretKey;
|
||||
this.dateService = dateService;
|
||||
timeStamp = new AtomicReference<String>(createNewStamp());
|
||||
this.timeStampProvider = timeStampProvider;
|
||||
}
|
||||
|
||||
public void filter(HttpRequest request) throws HttpException {
|
||||
|
@ -142,7 +110,7 @@ public class RequestAuthorizeSignature implements HttpRequestFilter {
|
|||
|
||||
private void replaceDateHeader(HttpRequest request) {
|
||||
request.getHeaders().replaceValues(HttpHeaders.DATE,
|
||||
Collections.singletonList(timestampAsHeaderString()));
|
||||
Collections.singletonList(timeStampProvider.get()));
|
||||
}
|
||||
|
||||
private void appendAmzHeaders(HttpRequest request, StringBuilder toSign) {
|
||||
|
|
|
@ -42,7 +42,10 @@ public interface S3Constants extends AWSConstants, S3Headers, BlobStoreConstants
|
|||
public static final String MARKER = "marker";
|
||||
public static final String MAX_KEYS = "max-keys";
|
||||
public static final String DELIMITER = "delimiter";
|
||||
public static final String PROPERTY_S3_ENDPOINT = "https://s3.amazonaws.com";
|
||||
|
||||
public static final String PROPERTY_S3_ENDPOINT = "jclouds.s3.endpoint";
|
||||
/**
|
||||
* how long do we wait before obtaining a new timestamp for requests.
|
||||
*/
|
||||
public static final String PROPERTY_S3_SESSIONINTERVAL = "jclouds.s3.sessioninterval";
|
||||
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
package org.jclouds.aws.s3.config;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.jclouds.aws.s3.handlers.AWSClientErrorRetryHandler;
|
||||
import org.jclouds.aws.s3.handlers.AWSRedirectionRetryHandler;
|
||||
|
@ -32,6 +35,7 @@ import org.jclouds.aws.s3.reference.S3Constants;
|
|||
import org.jclouds.http.functions.config.ParserModule;
|
||||
import org.jclouds.http.handlers.DelegatingErrorHandler;
|
||||
import org.jclouds.http.handlers.DelegatingRetryHandler;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.jclouds.util.Jsr330;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -46,17 +50,33 @@ import com.google.inject.Injector;
|
|||
public class RestS3ConnectionModuleTest {
|
||||
|
||||
Injector createInjector() {
|
||||
return Guice.createInjector(new RestS3ConnectionModule(), new ParserModule(), new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to(
|
||||
"user");
|
||||
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY))
|
||||
.to("key");
|
||||
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_S3_ENDPOINT)).to(
|
||||
"http://localhost");
|
||||
}
|
||||
});
|
||||
return Guice.createInjector(new RestS3ConnectionModule(), new ParserModule(),
|
||||
new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to("user");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY)).to("key");
|
||||
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_S3_ENDPOINT))
|
||||
.to("http://localhost");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(S3Constants.PROPERTY_S3_SESSIONINTERVAL)).to("2");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdatesOnlyOncePerSecond() throws NoSuchMethodException, InterruptedException {
|
||||
RestS3ConnectionModule module = new RestS3ConnectionModule();
|
||||
|
||||
ConcurrentMap<String, String> map = module.provideTimeStampCache(1, new DateService());
|
||||
String timeStamp = map.get("foo");
|
||||
for (int i = 0; i < 10; i++)
|
||||
map.get("foo");
|
||||
assertEquals(timeStamp, map.get("foo"));
|
||||
Thread.sleep(1001);
|
||||
assertFalse(timeStamp.equals(map.get("foo")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -30,9 +30,10 @@ import java.net.URI;
|
|||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.aws.s3.config.RestS3ConnectionModule;
|
||||
import org.jclouds.aws.s3.reference.S3Constants;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.jclouds.http.functions.config.ParserModule;
|
||||
import org.jclouds.util.Jsr330;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.DataProvider;
|
||||
|
@ -132,36 +133,26 @@ public class RequestAuthorizeSignatureTest {
|
|||
assertEquals(builder.toString(), "/adriancole.s3int5");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdatesOnlyOncePerSecond() throws NoSuchMethodException, InterruptedException {
|
||||
// filter.createNewStamp();
|
||||
String timeStamp = filter.timestampAsHeaderString();
|
||||
// replay(filter);
|
||||
for (int i = 0; i < 10; i++)
|
||||
filter.updateIfTimeOut();
|
||||
assert timeStamp.equals(filter.timestampAsHeaderString());
|
||||
Thread.sleep(1000);
|
||||
assert !timeStamp.equals(filter.timestampAsHeaderString());
|
||||
// verify(filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* before class, as we need to ensure that the filter is threadsafe.
|
||||
*
|
||||
*/
|
||||
@BeforeClass
|
||||
protected void createFilter() {
|
||||
injector = Guice.createInjector(new AbstractModule() {
|
||||
injector = Guice.createInjector(new RestS3ConnectionModule(), new ParserModule(),
|
||||
new AbstractModule() {
|
||||
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to(
|
||||
"foo");
|
||||
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY))
|
||||
.to("bar");
|
||||
bind(DateService.class);
|
||||
|
||||
}
|
||||
});
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to("foo");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY)).to("bar");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(S3Constants.PROPERTY_S3_SESSIONINTERVAL)).to("2");
|
||||
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_S3_ENDPOINT))
|
||||
.to("https://s3.amazonaws.com");
|
||||
}
|
||||
});
|
||||
filter = injector.getInstance(RequestAuthorizeSignature.class);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
|
||||
import org.jclouds.aws.domain.AWSError;
|
||||
import org.jclouds.aws.s3.config.RestS3ConnectionModule;
|
||||
import org.jclouds.aws.s3.reference.S3Constants;
|
||||
import org.jclouds.aws.s3.reference.S3Headers;
|
||||
import org.jclouds.http.HttpCommand;
|
||||
|
@ -59,17 +60,22 @@ public class S3UtilsTest {
|
|||
|
||||
@BeforeTest
|
||||
protected void setUpInjector() {
|
||||
Injector injector = Guice.createInjector(new ParserModule(), new AbstractModule() {
|
||||
Injector injector = Guice.createInjector(new RestS3ConnectionModule(), new ParserModule(),
|
||||
new AbstractModule() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to(
|
||||
"user");
|
||||
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY))
|
||||
.to("key");
|
||||
}
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to("user");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY)).to("key");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(S3Constants.PROPERTY_S3_SESSIONINTERVAL)).to("2");
|
||||
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_S3_ENDPOINT))
|
||||
.to("https://s3.amazonaws.com");
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
utils = injector.getInstance(S3Utils.class);
|
||||
response = new HttpResponse();
|
||||
response.setStatusCode(400);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
package org.jclouds.azure.storage.blob;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.azure.storage.reference.AzureStorageConstants.PROPERTY_AZURESTORAGE_SESSIONINTERVAL;
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
|
||||
import java.net.URI;
|
||||
|
@ -76,14 +77,10 @@ public class AzureBlobContextBuilder extends
|
|||
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-ms-meta-");
|
||||
properties.setProperty(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT,
|
||||
"https://{account}.blob.core.windows.net");
|
||||
if (!properties.containsKey(PROPERTY_AZURESTORAGE_SESSIONINTERVAL))
|
||||
this.withTimeStampExpiration(60);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// protected void addBlobStoreModule(List<Module> modules) {
|
||||
// modules.add(BlobStoreMapsModule.Builder.newBuilder(containerMetadataType, blobMetadataType,
|
||||
// blobType).withClearContainerStrategy(RecreateClearContainerStrategy.class).build());
|
||||
// }
|
||||
|
||||
public AzureBlobContextBuilder(String id, String secret) {
|
||||
this(new Properties());
|
||||
properties.setProperty(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT, checkNotNull(id,
|
||||
|
@ -173,4 +170,8 @@ public class AzureBlobContextBuilder extends
|
|||
modules.add(new RestAzureBlobStoreModule());
|
||||
}
|
||||
|
||||
public AzureBlobContextBuilder withTimeStampExpiration(long seconds) {
|
||||
getProperties().setProperty(PROPERTY_AZURESTORAGE_SESSIONINTERVAL, seconds + "");
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.jclouds.azure.storage.blob.functions.ParseContainerMetadataFromHeader
|
|||
import org.jclouds.azure.storage.blob.functions.ReturnTrueIfContainerAlreadyExists;
|
||||
import org.jclouds.azure.storage.blob.options.CreateContainerOptions;
|
||||
import org.jclouds.azure.storage.blob.options.ListBlobsOptions;
|
||||
import org.jclouds.azure.storage.config.RestAzureStorageConnectionModule;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
|
||||
|
@ -81,7 +82,8 @@ public class AzureBlobConnectionTest {
|
|||
Method method = AzureBlobConnection.class.getMethod("listContainers", Array.newInstance(
|
||||
ListOptions.class, 0).getClass());
|
||||
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method, new Object[] {});
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method,
|
||||
new Object[] {});
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "comp=list");
|
||||
|
@ -89,8 +91,7 @@ public class AzureBlobConnectionTest {
|
|||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
ParseSax.class);
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(), ParseSax.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||
}
|
||||
|
@ -99,8 +100,8 @@ public class AzureBlobConnectionTest {
|
|||
Method method = AzureBlobConnection.class.getMethod("listContainers", Array.newInstance(
|
||||
ListOptions.class, 0).getClass());
|
||||
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method, new Object[] { maxResults(1).marker(
|
||||
"marker").prefix("prefix") });
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method,
|
||||
new Object[] { maxResults(1).marker("marker").prefix("prefix") });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/");
|
||||
assert httpMethod.getEndpoint().getQuery().contains("comp=list");
|
||||
|
@ -111,8 +112,7 @@ public class AzureBlobConnectionTest {
|
|||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
ParseSax.class);
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(), ParseSax.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||
}
|
||||
|
@ -121,7 +121,8 @@ public class AzureBlobConnectionTest {
|
|||
Method method = AzureBlobConnection.class.getMethod("createContainer", String.class, Array
|
||||
.newInstance(CreateContainerOptions.class, 0).getClass());
|
||||
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method, new Object[] { "container" });
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method,
|
||||
new Object[] { "container" });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container");
|
||||
|
@ -140,7 +141,8 @@ public class AzureBlobConnectionTest {
|
|||
public void testDeleteContainer() throws SecurityException, NoSuchMethodException {
|
||||
Method method = AzureBlobConnection.class.getMethod("deleteContainer", String.class);
|
||||
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method, new Object[] { "container" });
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method,
|
||||
new Object[] { "container" });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container");
|
||||
|
@ -159,8 +161,9 @@ public class AzureBlobConnectionTest {
|
|||
Method method = AzureBlobConnection.class.getMethod("createContainer", String.class, Array
|
||||
.newInstance(CreateContainerOptions.class, 0).getClass());
|
||||
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method, new Object[] { "container",
|
||||
withPublicAcl().withMetadata(ImmutableMultimap.of("foo", "bar")) });
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method,
|
||||
new Object[] { "container",
|
||||
withPublicAcl().withMetadata(ImmutableMultimap.of("foo", "bar")) });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container");
|
||||
|
@ -183,7 +186,8 @@ public class AzureBlobConnectionTest {
|
|||
Method method = AzureBlobConnection.class.getMethod("createRootContainer", Array.newInstance(
|
||||
CreateContainerOptions.class, 0).getClass());
|
||||
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method, new Object[] {});
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method,
|
||||
new Object[] {});
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/$root");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container");
|
||||
|
@ -202,7 +206,8 @@ public class AzureBlobConnectionTest {
|
|||
public void testDeleteRootContainer() throws SecurityException, NoSuchMethodException {
|
||||
Method method = AzureBlobConnection.class.getMethod("deleteRootContainer");
|
||||
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method, new Object[] {});
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method,
|
||||
new Object[] {});
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/$root");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container");
|
||||
|
@ -221,8 +226,8 @@ public class AzureBlobConnectionTest {
|
|||
Method method = AzureBlobConnection.class.getMethod("createRootContainer", Array.newInstance(
|
||||
CreateContainerOptions.class, 0).getClass());
|
||||
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method, new Object[] { withPublicAcl()
|
||||
.withMetadata(ImmutableMultimap.of("foo", "bar")) });
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method,
|
||||
new Object[] { withPublicAcl().withMetadata(ImmutableMultimap.of("foo", "bar")) });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/$root");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container");
|
||||
|
@ -245,7 +250,8 @@ public class AzureBlobConnectionTest {
|
|||
Method method = AzureBlobConnection.class.getMethod("listBlobs", String.class, Array
|
||||
.newInstance(ListBlobsOptions.class, 0).getClass());
|
||||
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method, new Object[] { "container" });
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method,
|
||||
new Object[] { "container" });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container&comp=list");
|
||||
|
@ -253,8 +259,7 @@ public class AzureBlobConnectionTest {
|
|||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
ParseSax.class);
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(), ParseSax.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||
}
|
||||
|
@ -263,7 +268,8 @@ public class AzureBlobConnectionTest {
|
|||
Method method = AzureBlobConnection.class.getMethod("listBlobs", Array.newInstance(
|
||||
ListBlobsOptions.class, 0).getClass());
|
||||
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method, new Object[] {});
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method,
|
||||
new Object[] {});
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/$root");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container&comp=list");
|
||||
|
@ -271,8 +277,7 @@ public class AzureBlobConnectionTest {
|
|||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
ParseSax.class);
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(), ParseSax.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||
}
|
||||
|
@ -280,7 +285,8 @@ public class AzureBlobConnectionTest {
|
|||
public void testContainerProperties() throws SecurityException, NoSuchMethodException {
|
||||
Method method = AzureBlobConnection.class.getMethod("getContainerProperties", String.class);
|
||||
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method, new Object[] { "container" });
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method,
|
||||
new Object[] { "container" });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container");
|
||||
|
@ -297,8 +303,8 @@ public class AzureBlobConnectionTest {
|
|||
Method method = AzureBlobConnection.class.getMethod("setContainerMetadata", String.class,
|
||||
Multimap.class);
|
||||
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method, new Object[] { "container",
|
||||
ImmutableMultimap.of("key", "value") });
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method,
|
||||
new Object[] { "container", ImmutableMultimap.of("key", "value") });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container&comp=metadata");
|
||||
|
@ -318,8 +324,8 @@ public class AzureBlobConnectionTest {
|
|||
public void testSetBlobMetadata() throws SecurityException, NoSuchMethodException {
|
||||
Method method = AzureBlobConnection.class.getMethod("setBlobMetadata", String.class,
|
||||
String.class, Multimap.class);
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method, new Object[] { "container", "blob",
|
||||
ImmutableMultimap.of("key", "value") });
|
||||
GeneratedHttpRequest<AzureBlobConnection> httpMethod = processor.createRequest(method,
|
||||
new Object[] { "container", "blob", ImmutableMultimap.of("key", "value") });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/container/blob");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "comp=metadata");
|
||||
|
@ -357,9 +363,12 @@ public class AzureBlobConnectionTest {
|
|||
return Logger.NULL;
|
||||
}
|
||||
});
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_SESSIONINTERVAL)).to(
|
||||
1l);
|
||||
}
|
||||
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||
new JavaUrlHttpCommandExecutorServiceModule());
|
||||
}, new RestAzureStorageConnectionModule(), new RestModule(), new ExecutorServiceModule(
|
||||
new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule());
|
||||
processor = injector.getInstance(Key
|
||||
.get(new TypeLiteral<RestAnnotationProcessor<AzureBlobConnection>>() {
|
||||
}));
|
||||
|
|
|
@ -37,6 +37,7 @@ import javax.ws.rs.core.HttpHeaders;
|
|||
import org.jclouds.azure.storage.AzureBlob;
|
||||
import org.jclouds.azure.storage.blob.domain.Blob;
|
||||
import org.jclouds.azure.storage.blob.functions.ReturnTrueIfContainerAlreadyExists;
|
||||
import org.jclouds.azure.storage.config.RestAzureStorageConnectionModule;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
|
||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||
|
@ -75,7 +76,8 @@ public class AzureBlobStoreTest {
|
|||
public void testListContainers() throws SecurityException, NoSuchMethodException {
|
||||
Method method = AzureBlobStore.class.getMethod("listContainers");
|
||||
|
||||
GeneratedHttpRequest<AzureBlobStore> httpMethod = processor.createRequest(method, new Object[] {});
|
||||
GeneratedHttpRequest<AzureBlobStore> httpMethod = processor.createRequest(method,
|
||||
new Object[] {});
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "comp=list");
|
||||
|
@ -83,8 +85,7 @@ public class AzureBlobStoreTest {
|
|||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
ParseSax.class);
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(), ParseSax.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||
}
|
||||
|
@ -92,7 +93,8 @@ public class AzureBlobStoreTest {
|
|||
public void testCreateContainer() throws SecurityException, NoSuchMethodException {
|
||||
Method method = AzureBlobStore.class.getMethod("createContainer", String.class);
|
||||
|
||||
GeneratedHttpRequest<AzureBlobStore> httpMethod = processor.createRequest(method, new Object[] { "container" });
|
||||
GeneratedHttpRequest<AzureBlobStore> httpMethod = processor.createRequest(method,
|
||||
new Object[] { "container" });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container");
|
||||
|
@ -111,7 +113,8 @@ public class AzureBlobStoreTest {
|
|||
public void testDeleteContainer() throws SecurityException, NoSuchMethodException {
|
||||
Method method = AzureBlobStore.class.getMethod("deleteContainer", String.class);
|
||||
|
||||
GeneratedHttpRequest<AzureBlobStore> httpMethod = processor.createRequest(method, new Object[] { "container" });
|
||||
GeneratedHttpRequest<AzureBlobStore> httpMethod = processor.createRequest(method,
|
||||
new Object[] { "container" });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container");
|
||||
|
@ -129,7 +132,8 @@ public class AzureBlobStoreTest {
|
|||
public void testListBlobs() throws SecurityException, NoSuchMethodException {
|
||||
Method method = AzureBlobStore.class.getMethod("listBlobs", String.class);
|
||||
|
||||
GeneratedHttpRequest<AzureBlobStore> httpMethod = processor.createRequest(method, new Object[] { "container" });
|
||||
GeneratedHttpRequest<AzureBlobStore> httpMethod = processor.createRequest(method,
|
||||
new Object[] { "container" });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container&comp=list");
|
||||
|
@ -137,8 +141,7 @@ public class AzureBlobStoreTest {
|
|||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||
.singletonList("2009-07-17"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
|
||||
ParseSax.class);
|
||||
assertEquals(processor.createResponseParser(method, httpMethod).getClass(), ParseSax.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||
}
|
||||
|
@ -148,8 +151,8 @@ public class AzureBlobStoreTest {
|
|||
|
||||
Blob blob = new Blob("test");
|
||||
blob.setData("test");
|
||||
GeneratedHttpRequest<AzureBlobStore> httpMethod = processor
|
||||
.createRequest(method, new Object[] { "mycontainer", blob });
|
||||
GeneratedHttpRequest<AzureBlobStore> httpMethod = processor.createRequest(method,
|
||||
new Object[] { "mycontainer", blob });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/mycontainer/test");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), null);
|
||||
|
@ -188,6 +191,9 @@ public class AzureBlobStoreTest {
|
|||
return Logger.NULL;
|
||||
}
|
||||
});
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_SESSIONINTERVAL)).to(
|
||||
1l);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
@ -202,8 +208,8 @@ public class AzureBlobStoreTest {
|
|||
};
|
||||
}
|
||||
|
||||
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||
new JavaUrlHttpCommandExecutorServiceModule());
|
||||
}, new RestAzureStorageConnectionModule(), new RestModule(), new ExecutorServiceModule(
|
||||
new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule());
|
||||
processor = injector.getInstance(Key
|
||||
.get(new TypeLiteral<RestAnnotationProcessor<AzureBlobStore>>() {
|
||||
}));
|
||||
|
|
|
@ -28,6 +28,7 @@ import static org.testng.Assert.assertEquals;
|
|||
import org.jclouds.azure.storage.blob.handlers.AzureBlobClientErrorRetryHandler;
|
||||
import org.jclouds.azure.storage.blob.reference.AzureBlobConstants;
|
||||
import org.jclouds.azure.storage.handlers.ParseAzureStorageErrorFromXmlContent;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.functions.config.ParserModule;
|
||||
import org.jclouds.http.handlers.DelegatingErrorHandler;
|
||||
|
@ -60,6 +61,9 @@ public class RestAzureBlobConnectionModuleTest {
|
|||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT)).to(
|
||||
"http://localhost");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_SESSIONINTERVAL)).to(
|
||||
1l);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -23,6 +23,13 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.config;
|
||||
|
||||
import static org.jclouds.azure.storage.reference.AzureStorageConstants.PROPERTY_AZURESTORAGE_SESSIONINTERVAL;
|
||||
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.azure.storage.handlers.ParseAzureStorageErrorFromXmlContent;
|
||||
import org.jclouds.cloud.ConfiguresCloudConnection;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
|
@ -30,8 +37,13 @@ import org.jclouds.http.RequiresHttp;
|
|||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.annotation.Redirection;
|
||||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.jclouds.util.TimeStamp;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.MapMaker;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
* Configures the AzureStorage connection, including logging and http transport.
|
||||
|
@ -42,6 +54,28 @@ import com.google.inject.AbstractModule;
|
|||
@RequiresHttp
|
||||
public class RestAzureStorageConnectionModule extends AbstractModule {
|
||||
|
||||
@Provides
|
||||
@TimeStamp
|
||||
protected String provideTimeStamp(@TimeStamp ConcurrentMap<String, String> cache) {
|
||||
return cache.get("doesn't matter");
|
||||
}
|
||||
|
||||
/**
|
||||
* borrowing concurrency code to ensure that caching takes place properly
|
||||
*/
|
||||
@Provides
|
||||
@TimeStamp
|
||||
ConcurrentMap<String, String> provideTimeStampCache(
|
||||
@Named(PROPERTY_AZURESTORAGE_SESSIONINTERVAL) long seconds,
|
||||
final DateService dateService) {
|
||||
return new MapMaker().expiration(seconds, TimeUnit.SECONDS).makeComputingMap(
|
||||
new Function<String, String>() {
|
||||
public String apply(String key) {
|
||||
return dateService.rfc822DateFormat();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindErrorHandlers();
|
||||
|
|
|
@ -27,11 +27,10 @@ import java.util.Collection;
|
|||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
|
@ -40,12 +39,12 @@ import org.jclouds.http.HttpException;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.jclouds.util.TimeStamp;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* Signs the Azure Storage request. This will update timestamps at most once per second.
|
||||
* Signs the Azure Storage request.
|
||||
*
|
||||
* @see <a href= "http://msdn.microsoft.com/en-us/library/dd179428.aspx" />
|
||||
* @author Adrian Cole
|
||||
|
@ -57,48 +56,17 @@ public class SharedKeyAuthentication implements HttpRequestFilter {
|
|||
HttpHeaders.CONTENT_TYPE, HttpHeaders.DATE };
|
||||
|
||||
private final String account;
|
||||
private byte[] key;
|
||||
private final DateService dateService;
|
||||
|
||||
public final long BILLION = 1000000000;
|
||||
private final AtomicReference<String> timeStamp;
|
||||
private final AtomicLong trigger = new AtomicLong(System.nanoTime() + 1 * BILLION);
|
||||
|
||||
/**
|
||||
* Start the time update service. Azure clocks need to be within 900 seconds of the request time.
|
||||
* This method updates the clock every second. This is not performed per-request, as creation of
|
||||
* the date object is a slow, synchronized command.
|
||||
*/
|
||||
synchronized void updateIfTimeOut() {
|
||||
|
||||
if (trigger.get() - System.nanoTime() <= 0) {
|
||||
timeStamp.set(createNewStamp());
|
||||
trigger.set(System.nanoTime() + 1 * BILLION);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// this is a hotspot when submitted concurrently, so be lazy.
|
||||
// amazon is ok with up to 15 minutes off their time, so let's
|
||||
// be as lazy as possible.
|
||||
String createNewStamp() {
|
||||
return dateService.rfc822DateFormat();
|
||||
}
|
||||
|
||||
public String timestampAsHeaderString() {
|
||||
updateIfTimeOut();
|
||||
return timeStamp.get();
|
||||
}
|
||||
private final byte[] key;
|
||||
private final Provider<String> timeStampProvider;
|
||||
|
||||
@Inject
|
||||
public SharedKeyAuthentication(
|
||||
@Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT) String account,
|
||||
@Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY) String encodedKey,
|
||||
DateService dateService) {
|
||||
@TimeStamp Provider<String> timeStampProvider) {
|
||||
this.account = account;
|
||||
this.key = HttpUtils.fromBase64String(encodedKey);
|
||||
this.dateService = dateService;
|
||||
timeStamp = new AtomicReference<String>(createNewStamp());
|
||||
this.timeStampProvider = timeStampProvider;
|
||||
}
|
||||
|
||||
public void filter(HttpRequest request) throws HttpException {
|
||||
|
@ -140,7 +108,7 @@ public class SharedKeyAuthentication implements HttpRequestFilter {
|
|||
|
||||
private void replaceDateHeader(HttpRequest request) {
|
||||
request.getHeaders().replaceValues(HttpHeaders.DATE,
|
||||
Collections.singletonList(timestampAsHeaderString()));
|
||||
Collections.singletonList(timeStampProvider.get()));
|
||||
}
|
||||
|
||||
private void appendCanonicalizedHeaders(HttpRequest request, StringBuilder toSign) {
|
||||
|
@ -153,45 +121,6 @@ public class SharedKeyAuthentication implements HttpRequestFilter {
|
|||
toSign.deleteCharAt(toSign.lastIndexOf(","));
|
||||
toSign.append("\n");
|
||||
}
|
||||
// }
|
||||
// // Retrieve all headers for the resource that begin with x-ms-, including the x-ms-date
|
||||
// // header.
|
||||
// Set<String> matchingHeaders = Sets.filter(request.getHeaders().keySet(),
|
||||
// new Predicate<String>() {
|
||||
// public boolean apply(String input) {
|
||||
// return input.startsWith("x-ms-");
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// // Convert each HTTP header name to lowercase.
|
||||
// // Sort the container of headers lexicographically by header name, in ascending order.
|
||||
// SortedSet<String> lowercaseHeaders =
|
||||
// Sets.newTreeSet(Iterables.transform(matchingHeaders,
|
||||
// new Function<String, String>() {
|
||||
// public String apply(String from) {
|
||||
// return from.toLowerCase();
|
||||
// }
|
||||
// }));
|
||||
//
|
||||
// for (String header : lowercaseHeaders) {
|
||||
// // Combine headers with the same name into one header. The resulting header should be a
|
||||
// // name-value pair of the format "header-name:comma-separated-value-list", without any
|
||||
// // white
|
||||
// // space between values.
|
||||
// toSign.append(header).append(":");
|
||||
// // Trim any white space around the colon in the header.
|
||||
// // TODO: not sure why there would be...
|
||||
// for (String value : request.getHeaders().get(header))
|
||||
// // Replace any breaking white space with a single space.
|
||||
// toSign.append(value.replaceAll("\r?\n", " ")).append(",");
|
||||
// toSign.deleteCharAt(toSign.lastIndexOf(","));
|
||||
// // Finally, append a new line character to each canonicalized header in the resulting
|
||||
// list.
|
||||
// // Construct the CanonicalizedHeaders string by concatenating all headers in this list
|
||||
// into
|
||||
// // a
|
||||
// // single string.
|
||||
// toSign.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,4 +31,8 @@ package org.jclouds.azure.storage.reference;
|
|||
public interface AzureStorageConstants {
|
||||
public static final String PROPERTY_AZURESTORAGE_ACCOUNT = "jclouds.azure.storage.account";
|
||||
public static final String PROPERTY_AZURESTORAGE_KEY = "jclouds.azure.storage.key";
|
||||
/**
|
||||
* how long do we wait before obtaining a new timestamp for requests.
|
||||
*/
|
||||
public static final String PROPERTY_AZURESTORAGE_SESSIONINTERVAL = "jclouds.azure.storage.sessioninterval";
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import javax.ws.rs.GET;
|
|||
import javax.ws.rs.Path;
|
||||
|
||||
import org.jclouds.azure.storage.AzureBlob;
|
||||
import org.jclouds.azure.storage.config.RestAzureStorageConnectionModule;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
import org.jclouds.concurrent.WithinThreadExecutorService;
|
||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
|
@ -85,19 +86,29 @@ public class SharedKeyAuthenticationLiveTest {
|
|||
"jclouds.test.user");
|
||||
final String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||
uri = "http://" + account + ".blob.core.windows.net";
|
||||
injector = Guice.createInjector(new AbstractModule() {
|
||||
injector = Guice.createInjector(
|
||||
new AbstractModule() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(URI.class).annotatedWith(AzureBlob.class).toInstance(URI.create(uri));
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT)).to(account);
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to(key);
|
||||
}
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(URI.class).annotatedWith(AzureBlob.class).toInstance(URI.create(uri));
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT))
|
||||
.to(account);
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY))
|
||||
.to(key);
|
||||
bindConstant()
|
||||
.annotatedWith(
|
||||
Jsr330
|
||||
.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_SESSIONINTERVAL))
|
||||
.to(1l);
|
||||
}
|
||||
|
||||
}, new RestModule(), new Log4JLoggingModule(), new ExecutorServiceModule(
|
||||
new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule());
|
||||
}, new RestAzureStorageConnectionModule(), new RestModule(),
|
||||
new Log4JLoggingModule(),
|
||||
new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||
new JavaUrlHttpCommandExecutorServiceModule());
|
||||
RestClientFactory factory = injector.getInstance(RestClientFactory.class);
|
||||
client = factory.create(IntegrationTestClient.class);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.filters;
|
||||
|
||||
import static org.jclouds.azure.storage.reference.AzureStorageConstants.PROPERTY_AZURESTORAGE_SESSIONINTERVAL;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
|
@ -30,10 +31,11 @@ import java.net.URI;
|
|||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.azure.storage.config.RestAzureStorageConnectionModule;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.jclouds.http.functions.config.ParserModule;
|
||||
import org.jclouds.util.Jsr330;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.DataProvider;
|
||||
|
@ -127,36 +129,27 @@ public class SharedKeyAuthenticationTest {
|
|||
assertEquals(builder.toString(), "/mycontainer?comp=list");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdatesOnlyOncePerSecond() throws NoSuchMethodException, InterruptedException {
|
||||
// filter.createNewStamp();
|
||||
String timeStamp = filter.timestampAsHeaderString();
|
||||
// replay(filter);
|
||||
for (int i = 0; i < 10; i++)
|
||||
filter.updateIfTimeOut();
|
||||
assert timeStamp.equals(filter.timestampAsHeaderString());
|
||||
Thread.sleep(1000);
|
||||
assert !timeStamp.equals(filter.timestampAsHeaderString());
|
||||
// verify(filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* before class, as we need to ensure that the filter is threadsafe.
|
||||
*
|
||||
*/
|
||||
@BeforeClass
|
||||
protected void createFilter() {
|
||||
injector = Guice.createInjector(new AbstractModule() {
|
||||
injector = Guice.createInjector(new ParserModule(), new RestAzureStorageConnectionModule(),
|
||||
new AbstractModule() {
|
||||
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT)).to(ACCOUNT);
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to(KEY);
|
||||
bind(DateService.class);
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT))
|
||||
.to(ACCOUNT);
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY))
|
||||
.to(KEY);
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(PROPERTY_AZURESTORAGE_SESSIONINTERVAL)).to("1");
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
filter = injector.getInstance(SharedKeyAuthentication.class);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
package org.jclouds.azure.storage.queue;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.azure.storage.reference.AzureStorageConstants.PROPERTY_AZURESTORAGE_SESSIONINTERVAL;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
@ -68,6 +69,8 @@ public class AzureQueueContextBuilder extends CloudContextBuilder<AzureQueueConn
|
|||
String endpoint = properties.getProperty(AzureQueueConstants.PROPERTY_AZUREQUEUE_ENDPOINT);
|
||||
properties.setProperty(AzureQueueConstants.PROPERTY_AZUREQUEUE_ENDPOINT, endpoint.replaceAll(
|
||||
"\\{account\\}", id));
|
||||
if (!properties.containsKey(PROPERTY_AZURESTORAGE_SESSIONINTERVAL))
|
||||
this.withTimeStampExpiration(60);
|
||||
}
|
||||
|
||||
public AzureQueueContextBuilder(Properties properties) {
|
||||
|
@ -161,4 +164,9 @@ public class AzureQueueContextBuilder extends CloudContextBuilder<AzureQueueConn
|
|||
return (AzureQueueContextBuilder) super
|
||||
.withPoolRequestInvokerThreads(poolRequestInvokerThreads);
|
||||
}
|
||||
|
||||
public AzureQueueContextBuilder withTimeStampExpiration(long seconds) {
|
||||
getProperties().setProperty(PROPERTY_AZURESTORAGE_SESSIONINTERVAL, seconds + "");
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import java.util.Collections;
|
|||
import javax.ws.rs.HttpMethod;
|
||||
|
||||
import org.jclouds.azure.storage.AzureQueue;
|
||||
import org.jclouds.azure.storage.config.RestAzureStorageConnectionModule;
|
||||
import org.jclouds.azure.storage.options.CreateOptions;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
|
@ -184,9 +185,12 @@ public class AzureQueueConnectionTest {
|
|||
return Logger.NULL;
|
||||
}
|
||||
});
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_SESSIONINTERVAL)).to(
|
||||
1l);
|
||||
}
|
||||
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||
new JavaUrlHttpCommandExecutorServiceModule());
|
||||
}, new RestAzureStorageConnectionModule(), new RestModule(), new ExecutorServiceModule(
|
||||
new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule());
|
||||
processor = injector.getInstance(Key
|
||||
.get(new TypeLiteral<RestAnnotationProcessor<AzureQueueConnection>>() {
|
||||
}));
|
||||
|
|
|
@ -38,7 +38,6 @@ import javax.ws.rs.core.MediaType;
|
|||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.blobstore.util;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.http.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.rest.internal;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.util;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
/**
|
||||
* Related to a TimeStamp
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
||||
@Qualifier
|
||||
public @interface TimeStamp {
|
||||
|
||||
}
|
|
@ -1,3 +1,26 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.mezeo.pcs2.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.mezeo.pcs2.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.mezeo.pcs2.options;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
|
|
@ -40,13 +40,14 @@ import org.testng.annotations.Test;
|
|||
@Test(groups = { "integration", "live" }, testName = "cloudfiles.PCSBlobMapIntegrationTest")
|
||||
public class PCSBlobMapIntegrationTest extends
|
||||
BaseBlobMapIntegrationTest<PCSConnection, ContainerMetadata, FileMetadata, PCSFile> {
|
||||
|
||||
@Test(enabled = false)
|
||||
@Override
|
||||
public void testEntrySet() throws IOException, InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
// fails on 400 errors
|
||||
}
|
||||
|
||||
@Test(enabled = false)
|
||||
@Override
|
||||
public void testContains() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
// not supported
|
||||
|
|
|
@ -41,30 +41,35 @@ import org.testng.annotations.Test;
|
|||
public class PCSInputStreamMapIntegrationTest extends
|
||||
BaseInputStreamMapIntegrationTest<PCSConnection, ContainerMetadata, FileMetadata, PCSFile> {
|
||||
|
||||
@Test(enabled = false)
|
||||
@Override
|
||||
public void testEntrySet() throws IOException, InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
// fails on 400 errors
|
||||
}
|
||||
|
||||
|
||||
@Test(enabled = false)
|
||||
@Override
|
||||
public void testContainsBytesValue() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
// not supported
|
||||
}
|
||||
|
||||
@Test(enabled = false)
|
||||
@Override
|
||||
public void testContainsFileValue() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
// not supported
|
||||
}
|
||||
|
||||
@Test(enabled = false)
|
||||
@Override
|
||||
public void testContainsInputStreamValue() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
// not supported
|
||||
}
|
||||
|
||||
@Test(enabled = false)
|
||||
@Override
|
||||
public void testContainsStringValue() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.mezeo.pcs2.options;
|
||||
|
||||
import static org.jclouds.mezeo.pcs2.options.PutBlockOptions.Builder.range;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.nirvanix.sdn;
|
||||
|
||||
import org.jclouds.cloud.CloudContext;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.nirvanix.sdn.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.nirvanix.sdn.config;
|
||||
|
||||
import java.net.URI;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.nirvanix.sdn.domain;
|
||||
|
||||
import java.net.URI;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.nirvanix.sdn.filters;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.nirvanix.sdn.filters;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.nirvanix.sdn;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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.nirvanix.sdn.binders;
|
||||
|
||||
import static org.easymock.classextension.EasyMock.createMock;
|
||||
|
|
Loading…
Reference in New Issue