mirror of https://github.com/apache/jclouds.git
removed mapmaker expiration as it is incompatible with google appengine. replaced with ExpirableSupplier
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2032 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
af2fa174d1
commit
3d030cfac0
|
@ -27,7 +27,6 @@ import static org.jclouds.atmosonline.saas.reference.AtmosStorageConstants.PROPE
|
||||||
import static org.jclouds.atmosonline.saas.reference.AtmosStorageConstants.PROPERTY_EMCSAAS_SESSIONINTERVAL;
|
import static org.jclouds.atmosonline.saas.reference.AtmosStorageConstants.PROPERTY_EMCSAAS_SESSIONINTERVAL;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
@ -37,6 +36,7 @@ import org.jclouds.atmosonline.saas.AtmosStorage;
|
||||||
import org.jclouds.atmosonline.saas.AtmosStorageClient;
|
import org.jclouds.atmosonline.saas.AtmosStorageClient;
|
||||||
import org.jclouds.atmosonline.saas.handlers.AtmosStorageClientErrorRetryHandler;
|
import org.jclouds.atmosonline.saas.handlers.AtmosStorageClientErrorRetryHandler;
|
||||||
import org.jclouds.atmosonline.saas.handlers.ParseAtmosStorageErrorFromXmlContent;
|
import org.jclouds.atmosonline.saas.handlers.ParseAtmosStorageErrorFromXmlContent;
|
||||||
|
import org.jclouds.concurrent.ExpirableSupplier;
|
||||||
import org.jclouds.http.HttpErrorHandler;
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
import org.jclouds.http.HttpRetryHandler;
|
import org.jclouds.http.HttpRetryHandler;
|
||||||
import org.jclouds.http.RequiresHttp;
|
import org.jclouds.http.RequiresHttp;
|
||||||
|
@ -48,8 +48,7 @@ import org.jclouds.rest.RestClientFactory;
|
||||||
import org.jclouds.util.DateService;
|
import org.jclouds.util.DateService;
|
||||||
import org.jclouds.util.TimeStamp;
|
import org.jclouds.util.TimeStamp;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.MapMaker;
|
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
|
@ -82,8 +81,8 @@ public class AtmosStorageRestClientModule extends AbstractModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@TimeStamp
|
@TimeStamp
|
||||||
protected String provideTimeStamp(@TimeStamp ConcurrentMap<String, String> cache) {
|
protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
|
||||||
return cache.get("doesn't matter");
|
return cache.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,14 +90,13 @@ public class AtmosStorageRestClientModule extends AbstractModule {
|
||||||
*/
|
*/
|
||||||
@Provides
|
@Provides
|
||||||
@TimeStamp
|
@TimeStamp
|
||||||
ConcurrentMap<String, String> provideTimeStampCache(
|
Supplier<String> provideTimeStampCache(@Named(PROPERTY_EMCSAAS_SESSIONINTERVAL) long seconds,
|
||||||
@Named(PROPERTY_EMCSAAS_SESSIONINTERVAL) long seconds, final DateService dateService) {
|
final DateService dateService) {
|
||||||
return new MapMaker().expiration(seconds, TimeUnit.SECONDS).makeComputingMap(
|
return new ExpirableSupplier<String>(new Supplier<String>() {
|
||||||
new Function<String, String>() {
|
public String get() {
|
||||||
public String apply(String key) {
|
|
||||||
return dateService.rfc822DateFormat();
|
return dateService.rfc822DateFormat();
|
||||||
}
|
}
|
||||||
});
|
}, seconds, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void bindErrorHandlers() {
|
protected void bindErrorHandlers() {
|
||||||
|
|
|
@ -26,8 +26,6 @@ package org.jclouds.atmosonline.saas.config;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertFalse;
|
import static org.testng.Assert.assertFalse;
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
|
|
||||||
import org.bouncycastle.util.encoders.Base64;
|
import org.bouncycastle.util.encoders.Base64;
|
||||||
import org.jclouds.atmosonline.saas.handlers.AtmosStorageClientErrorRetryHandler;
|
import org.jclouds.atmosonline.saas.handlers.AtmosStorageClientErrorRetryHandler;
|
||||||
import org.jclouds.atmosonline.saas.handlers.ParseAtmosStorageErrorFromXmlContent;
|
import org.jclouds.atmosonline.saas.handlers.ParseAtmosStorageErrorFromXmlContent;
|
||||||
|
@ -42,6 +40,7 @@ import org.jclouds.util.DateService;
|
||||||
import org.jclouds.util.Jsr330;
|
import org.jclouds.util.Jsr330;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
@ -74,13 +73,13 @@ public class AtmosStorageRestClientModuleTest {
|
||||||
void testUpdatesOnlyOncePerSecond() throws NoSuchMethodException, InterruptedException {
|
void testUpdatesOnlyOncePerSecond() throws NoSuchMethodException, InterruptedException {
|
||||||
AtmosStorageRestClientModule module = new AtmosStorageRestClientModule();
|
AtmosStorageRestClientModule module = new AtmosStorageRestClientModule();
|
||||||
|
|
||||||
ConcurrentMap<String, String> map = module.provideTimeStampCache(1, new DateService());
|
Supplier<String> map = module.provideTimeStampCache(1, new DateService());
|
||||||
String timeStamp = map.get("foo");
|
String timeStamp = map.get();
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
map.get("foo");
|
map.get();
|
||||||
assertEquals(timeStamp, map.get("foo"));
|
assertEquals(timeStamp, map.get());
|
||||||
Thread.sleep(1001);
|
Thread.sleep(1001);
|
||||||
assertFalse(timeStamp.equals(map.get("foo")));
|
assertFalse(timeStamp.equals(map.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -26,8 +26,11 @@ package org.jclouds.aws.s3;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
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_ACCESSKEYID;
|
||||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY;
|
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_ENDPOINT;
|
||||||
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_METADATA_PREFIX;
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_METADATA_PREFIX;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_RETRY;
|
||||||
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SESSIONINTERVAL;
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SESSIONINTERVAL;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_TIMEOUT;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
@ -44,7 +47,7 @@ public class S3PropertiesBuilder extends HttpPropertiesBuilder {
|
||||||
@Override
|
@Override
|
||||||
protected Properties defaultProperties() {
|
protected Properties defaultProperties() {
|
||||||
Properties properties = super.defaultProperties();
|
Properties properties = super.defaultProperties();
|
||||||
properties.setProperty(S3Constants.PROPERTY_S3_ENDPOINT, "https://s3.amazonaws.com");
|
properties.setProperty(PROPERTY_S3_ENDPOINT, "https://s3.amazonaws.com");
|
||||||
properties.setProperty(PROPERTY_S3_METADATA_PREFIX, "x-amz-meta-");
|
properties.setProperty(PROPERTY_S3_METADATA_PREFIX, "x-amz-meta-");
|
||||||
properties.setProperty(PROPERTY_S3_SESSIONINTERVAL, "60");
|
properties.setProperty(PROPERTY_S3_SESSIONINTERVAL, "60");
|
||||||
return properties;
|
return properties;
|
||||||
|
@ -77,4 +80,24 @@ public class S3PropertiesBuilder extends HttpPropertiesBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* longest time a single synchronous operation can take before throwing an exception.
|
||||||
|
*/
|
||||||
|
public S3PropertiesBuilder withRequestTimeout(long milliseconds) {
|
||||||
|
properties.setProperty(PROPERTY_S3_TIMEOUT, Long.toString(milliseconds));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* longest time a single synchronous operation can take before throwing an exception.
|
||||||
|
*/
|
||||||
|
public S3PropertiesBuilder withMaxRetries(int retries) {
|
||||||
|
properties.setProperty(PROPERTY_S3_RETRY, Integer.toString(retries));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected S3PropertiesBuilder withMetaPrefix(String prefix) {
|
||||||
|
properties.setProperty(PROPERTY_S3_METADATA_PREFIX, prefix);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,11 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.blobstore;
|
package org.jclouds.aws.s3.blobstore;
|
||||||
|
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.*;
|
||||||
|
import static org.jclouds.blobstore.reference.BlobStoreConstants.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Client;
|
import org.jclouds.aws.s3.S3Client;
|
||||||
|
@ -34,6 +37,7 @@ import org.jclouds.blobstore.BlobStoreContextBuilder;
|
||||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
@ -55,7 +59,17 @@ public class S3BlobStoreContextBuilder extends BlobStoreContextBuilder<S3Client>
|
||||||
|
|
||||||
public S3BlobStoreContextBuilder(Properties props) {
|
public S3BlobStoreContextBuilder(Properties props) {
|
||||||
super(new TypeLiteral<S3Client>() {
|
super(new TypeLiteral<S3Client>() {
|
||||||
}, props);
|
}, convert(props));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Properties convert(Properties props) {
|
||||||
|
for (Entry<String, String> entry : ImmutableMap.of(PROPERTY_S3_METADATA_PREFIX,
|
||||||
|
PROPERTY_USER_METADATA_PREFIX, PROPERTY_S3_RETRY, PROPERTY_BLOBSTORE_RETRY,
|
||||||
|
PROPERTY_S3_TIMEOUT, PROPERTY_USER_METADATA_PREFIX).entrySet()) {
|
||||||
|
if (props.containsKey(entry.getKey()))
|
||||||
|
props.setProperty(entry.getValue(), props.getProperty(entry.getKey()));
|
||||||
|
}
|
||||||
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.net.URI;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Client;
|
import org.jclouds.aws.s3.S3Client;
|
||||||
|
import org.jclouds.aws.s3.S3PropertiesBuilder;
|
||||||
import org.jclouds.blobstore.BlobStoreContext;
|
import org.jclouds.blobstore.BlobStoreContext;
|
||||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
|
@ -47,19 +48,19 @@ import com.google.inject.Module;
|
||||||
*/
|
*/
|
||||||
public class S3BlobStoreContextFactory {
|
public class S3BlobStoreContextFactory {
|
||||||
public static BlobStoreContext<S3Client> createContext(Properties properties, Module... modules) {
|
public static BlobStoreContext<S3Client> createContext(Properties properties, Module... modules) {
|
||||||
return new S3BlobStoreContextBuilder(new S3BlobStorePropertiesBuilder(properties).build())
|
return new S3BlobStoreContextBuilder(new S3PropertiesBuilder(properties).build())
|
||||||
.withModules(modules).buildContext();
|
.withModules(modules).buildContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlobStoreContext<S3Client> createContext(String awsAccessKeyId,
|
public static BlobStoreContext<S3Client> createContext(String awsAccessKeyId,
|
||||||
String awsSecretAccessKey, Module... modules) {
|
String awsSecretAccessKey, Module... modules) {
|
||||||
return new S3BlobStoreContextBuilder(new S3BlobStorePropertiesBuilder(awsAccessKeyId,
|
return new S3BlobStoreContextBuilder(new S3PropertiesBuilder(awsAccessKeyId,
|
||||||
awsSecretAccessKey).build()).withModules(modules).buildContext();
|
awsSecretAccessKey).build()).withModules(modules).buildContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlobStoreContext<S3Client> createContext(URI endpoint, String awsAccessKeyId,
|
public static BlobStoreContext<S3Client> createContext(URI endpoint, String awsAccessKeyId,
|
||||||
String awsSecretAccessKey, Module... modules) {
|
String awsSecretAccessKey, Module... modules) {
|
||||||
return new S3BlobStoreContextBuilder(new S3BlobStorePropertiesBuilder(awsAccessKeyId,
|
return new S3BlobStoreContextBuilder(new S3PropertiesBuilder(awsAccessKeyId,
|
||||||
awsSecretAccessKey).withEndpoint(endpoint).build()).withModules(modules)
|
awsSecretAccessKey).withEndpoint(endpoint).build()).withModules(modules)
|
||||||
.buildContext();
|
.buildContext();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* 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.aws.s3.blobstore;
|
|
||||||
|
|
||||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
|
||||||
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3PropertiesBuilder;
|
|
||||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds properties used in S3 Blob Stores
|
|
||||||
*
|
|
||||||
* @author Adrian Cole, Andrew Newdigate
|
|
||||||
*/
|
|
||||||
public class S3BlobStorePropertiesBuilder extends S3PropertiesBuilder {
|
|
||||||
|
|
||||||
public S3BlobStorePropertiesBuilder(String id, String secret) {
|
|
||||||
super(id, secret);
|
|
||||||
}
|
|
||||||
|
|
||||||
public S3BlobStorePropertiesBuilder(Properties properties) {
|
|
||||||
super(properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* longest time a single synchronous operation can take before throwing an exception.
|
|
||||||
*/
|
|
||||||
public S3BlobStorePropertiesBuilder withRequestTimeout(long milliseconds) {
|
|
||||||
properties.setProperty(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT, Long
|
|
||||||
.toString(milliseconds));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Properties defaultProperties() {
|
|
||||||
Properties props = super.defaultProperties();
|
|
||||||
props.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-amz-meta-");
|
|
||||||
return props;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,7 +24,6 @@
|
||||||
package org.jclouds.aws.s3.config;
|
package org.jclouds.aws.s3.config;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
@ -37,6 +36,7 @@ import org.jclouds.aws.s3.handlers.AWSClientErrorRetryHandler;
|
||||||
import org.jclouds.aws.s3.handlers.AWSRedirectionRetryHandler;
|
import org.jclouds.aws.s3.handlers.AWSRedirectionRetryHandler;
|
||||||
import org.jclouds.aws.s3.handlers.ParseAWSErrorFromXmlContent;
|
import org.jclouds.aws.s3.handlers.ParseAWSErrorFromXmlContent;
|
||||||
import org.jclouds.aws.s3.reference.S3Constants;
|
import org.jclouds.aws.s3.reference.S3Constants;
|
||||||
|
import org.jclouds.concurrent.ExpirableSupplier;
|
||||||
import org.jclouds.http.HttpErrorHandler;
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
import org.jclouds.http.HttpRetryHandler;
|
import org.jclouds.http.HttpRetryHandler;
|
||||||
import org.jclouds.http.RequiresHttp;
|
import org.jclouds.http.RequiresHttp;
|
||||||
|
@ -48,8 +48,7 @@ import org.jclouds.rest.RestClientFactory;
|
||||||
import org.jclouds.util.DateService;
|
import org.jclouds.util.DateService;
|
||||||
import org.jclouds.util.TimeStamp;
|
import org.jclouds.util.TimeStamp;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.MapMaker;
|
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import com.google.inject.Scopes;
|
import com.google.inject.Scopes;
|
||||||
|
@ -65,8 +64,8 @@ public class S3RestClientModule extends AbstractModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@TimeStamp
|
@TimeStamp
|
||||||
protected String provideTimeStamp(@TimeStamp ConcurrentMap<String, String> cache) {
|
protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
|
||||||
return cache.get("doesn't matter");
|
return cache.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,15 +73,14 @@ public class S3RestClientModule extends AbstractModule {
|
||||||
*/
|
*/
|
||||||
@Provides
|
@Provides
|
||||||
@TimeStamp
|
@TimeStamp
|
||||||
ConcurrentMap<String, String> provideTimeStampCache(
|
Supplier<String> provideTimeStampCache(
|
||||||
@Named(S3Constants.PROPERTY_S3_SESSIONINTERVAL) long seconds,
|
@Named(S3Constants.PROPERTY_S3_SESSIONINTERVAL) long seconds,
|
||||||
final DateService dateService) {
|
final DateService dateService) {
|
||||||
return new MapMaker().expiration(seconds, TimeUnit.SECONDS).makeComputingMap(
|
return new ExpirableSupplier<String>(new Supplier<String>() {
|
||||||
new Function<String, String>() {
|
public String get() {
|
||||||
public String apply(String key) {
|
|
||||||
return dateService.rfc822DateFormat();
|
return dateService.rfc822DateFormat();
|
||||||
}
|
}
|
||||||
});
|
}, seconds, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.functions;
|
package org.jclouds.aws.s3.functions;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -31,6 +33,7 @@ import com.google.common.base.Function;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@Singleton
|
||||||
public class ObjectKey implements Function<Object, String> {
|
public class ObjectKey implements Function<Object, String> {
|
||||||
|
|
||||||
public String apply(Object from) {
|
public String apply(Object from) {
|
||||||
|
|
|
@ -46,6 +46,19 @@ public interface S3Constants extends AWSConstants, S3Headers {
|
||||||
* how long do we wait before obtaining a new timestamp for requests.
|
* how long do we wait before obtaining a new timestamp for requests.
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_S3_SESSIONINTERVAL = "jclouds.s3.sessioninterval";
|
public static final String PROPERTY_S3_SESSIONINTERVAL = "jclouds.s3.sessioninterval";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* longest time a single synchronous operation can take before throwing an exception.
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_S3_TIMEOUT = "jclouds.s3.timeout";
|
||||||
|
/**
|
||||||
|
* time to pause before retrying a transient failure
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_S3_RETRY = "jclouds.s3.retry";
|
||||||
|
/**
|
||||||
|
* Any header starting with this prefix is considered user metadata. It will be stored with the
|
||||||
|
* object and returned when you retrieve the object/
|
||||||
|
*/
|
||||||
public static final String PROPERTY_S3_METADATA_PREFIX = "jclouds.s3.metaprefix";
|
public static final String PROPERTY_S3_METADATA_PREFIX = "jclouds.s3.metaprefix";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Client;
|
import org.jclouds.aws.s3.S3Client;
|
||||||
|
import org.jclouds.aws.s3.S3PropertiesBuilder;
|
||||||
import org.jclouds.aws.s3.blobstore.config.S3BlobStoreContextModule;
|
import org.jclouds.aws.s3.blobstore.config.S3BlobStoreContextModule;
|
||||||
import org.jclouds.aws.s3.config.S3RestClientModule;
|
import org.jclouds.aws.s3.config.S3RestClientModule;
|
||||||
import org.jclouds.aws.s3.config.S3StubClientModule;
|
import org.jclouds.aws.s3.config.S3StubClientModule;
|
||||||
|
@ -59,8 +60,8 @@ import com.google.inject.TypeLiteral;
|
||||||
public class S3BlobStoreContextBuilderTest {
|
public class S3BlobStoreContextBuilderTest {
|
||||||
|
|
||||||
public void testNewBuilder() {
|
public void testNewBuilder() {
|
||||||
S3BlobStoreContextBuilder builder = new S3BlobStoreContextBuilder(
|
S3BlobStoreContextBuilder builder = new S3BlobStoreContextBuilder(new S3PropertiesBuilder(
|
||||||
new S3BlobStorePropertiesBuilder("id", "secret").build());
|
"id", "secret").build());
|
||||||
assertEquals(builder.getProperties().getProperty(PROPERTY_USER_METADATA_PREFIX),
|
assertEquals(builder.getProperties().getProperty(PROPERTY_USER_METADATA_PREFIX),
|
||||||
"x-amz-meta-");
|
"x-amz-meta-");
|
||||||
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_ACCESSKEYID), "id");
|
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_ACCESSKEYID), "id");
|
||||||
|
@ -68,9 +69,8 @@ public class S3BlobStoreContextBuilderTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBuildContext() {
|
public void testBuildContext() {
|
||||||
BlobStoreContext<S3Client> context = new S3BlobStoreContextBuilder(
|
BlobStoreContext<S3Client> context = new S3BlobStoreContextBuilder(new S3PropertiesBuilder(
|
||||||
new S3BlobStorePropertiesBuilder("id", "secret").build()).withModules(
|
"id", "secret").build()).withModules(new S3StubClientModule()).buildContext();
|
||||||
new S3StubClientModule()).buildContext();
|
|
||||||
assertEquals(context.getClass(), BlobStoreContextImpl.class);
|
assertEquals(context.getClass(), BlobStoreContextImpl.class);
|
||||||
assertEquals(context.getApi().getClass(), StubS3Client.class);
|
assertEquals(context.getApi().getClass(), StubS3Client.class);
|
||||||
assertEquals(context.getBlobStore().getClass(), S3BlobStore.class);
|
assertEquals(context.getBlobStore().getClass(), S3BlobStore.class);
|
||||||
|
@ -81,8 +81,8 @@ public class S3BlobStoreContextBuilderTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBuildInjector() {
|
public void testBuildInjector() {
|
||||||
Injector i = new S3BlobStoreContextBuilder(new S3BlobStorePropertiesBuilder("id", "secret")
|
Injector i = new S3BlobStoreContextBuilder(new S3PropertiesBuilder("id", "secret").build())
|
||||||
.build()).withModules(new S3StubClientModule()).buildInjector();
|
.withModules(new S3StubClientModule()).buildInjector();
|
||||||
assert i.getInstance(Key.get(new TypeLiteral<BlobStoreContext<S3Client>>() {
|
assert i.getInstance(Key.get(new TypeLiteral<BlobStoreContext<S3Client>>() {
|
||||||
})) != null;
|
})) != null;
|
||||||
assert i.getInstance(S3Object.class) != null;
|
assert i.getInstance(S3Object.class) != null;
|
||||||
|
@ -91,8 +91,8 @@ public class S3BlobStoreContextBuilderTest {
|
||||||
|
|
||||||
protected void testAddContextModule() {
|
protected void testAddContextModule() {
|
||||||
List<Module> modules = new ArrayList<Module>();
|
List<Module> modules = new ArrayList<Module>();
|
||||||
S3BlobStoreContextBuilder builder = new S3BlobStoreContextBuilder(
|
S3BlobStoreContextBuilder builder = new S3BlobStoreContextBuilder(new S3PropertiesBuilder(
|
||||||
new S3BlobStorePropertiesBuilder("id", "secret").build());
|
"id", "secret").build());
|
||||||
builder.addContextModule(modules);
|
builder.addContextModule(modules);
|
||||||
assertEquals(modules.size(), 1);
|
assertEquals(modules.size(), 1);
|
||||||
assertEquals(modules.get(0).getClass(), S3BlobStoreContextModule.class);
|
assertEquals(modules.get(0).getClass(), S3BlobStoreContextModule.class);
|
||||||
|
@ -100,8 +100,8 @@ public class S3BlobStoreContextBuilderTest {
|
||||||
|
|
||||||
protected void addClientModule() {
|
protected void addClientModule() {
|
||||||
List<Module> modules = new ArrayList<Module>();
|
List<Module> modules = new ArrayList<Module>();
|
||||||
S3BlobStoreContextBuilder builder = new S3BlobStoreContextBuilder(
|
S3BlobStoreContextBuilder builder = new S3BlobStoreContextBuilder(new S3PropertiesBuilder(
|
||||||
new S3BlobStorePropertiesBuilder("id", "secret").build());
|
"id", "secret").build());
|
||||||
builder.addClientModule(modules);
|
builder.addClientModule(modules);
|
||||||
assertEquals(modules.size(), 1);
|
assertEquals(modules.size(), 1);
|
||||||
assertEquals(modules.get(0).getClass(), S3RestClientModule.class);
|
assertEquals(modules.get(0).getClass(), S3RestClientModule.class);
|
||||||
|
|
|
@ -24,9 +24,9 @@
|
||||||
package org.jclouds.aws.s3.blobstore.integration;
|
package org.jclouds.aws.s3.blobstore.integration;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Client;
|
import org.jclouds.aws.s3.S3Client;
|
||||||
|
import org.jclouds.aws.s3.S3PropertiesBuilder;
|
||||||
import org.jclouds.aws.s3.blobstore.S3BlobStoreContextBuilder;
|
import org.jclouds.aws.s3.blobstore.S3BlobStoreContextBuilder;
|
||||||
import org.jclouds.aws.s3.blobstore.S3BlobStoreContextFactory;
|
import org.jclouds.aws.s3.blobstore.S3BlobStoreContextFactory;
|
||||||
import org.jclouds.aws.s3.blobstore.S3BlobStorePropertiesBuilder;
|
|
||||||
import org.jclouds.aws.s3.config.S3StubClientModule;
|
import org.jclouds.aws.s3.config.S3StubClientModule;
|
||||||
import org.jclouds.blobstore.BlobStoreContext;
|
import org.jclouds.blobstore.BlobStoreContext;
|
||||||
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
|
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
|
||||||
|
@ -45,9 +45,8 @@ public class S3TestInitializer extends BaseTestInitializer<S3Client> {
|
||||||
protected BlobStoreContext<S3Client> createLiveContext(Module configurationModule, String url,
|
protected BlobStoreContext<S3Client> createLiveContext(Module configurationModule, String url,
|
||||||
String app, String account, String key) {
|
String app, String account, String key) {
|
||||||
BaseBlobStoreIntegrationTest.SANITY_CHECK_RETURNED_BUCKET_NAME = true;
|
BaseBlobStoreIntegrationTest.SANITY_CHECK_RETURNED_BUCKET_NAME = true;
|
||||||
return new S3BlobStoreContextBuilder(new S3BlobStorePropertiesBuilder(account, key)
|
return new S3BlobStoreContextBuilder(new S3PropertiesBuilder(account, key).relaxSSLHostname()
|
||||||
.relaxSSLHostname().build()).withModules(configurationModule,
|
.build()).withModules(configurationModule, new Log4JLoggingModule()).buildContext();
|
||||||
new Log4JLoggingModule()).buildContext();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -26,8 +26,6 @@ package org.jclouds.aws.s3.config;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertFalse;
|
import static org.testng.Assert.assertFalse;
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
|
|
||||||
import org.jclouds.aws.s3.handlers.AWSClientErrorRetryHandler;
|
import org.jclouds.aws.s3.handlers.AWSClientErrorRetryHandler;
|
||||||
import org.jclouds.aws.s3.handlers.AWSRedirectionRetryHandler;
|
import org.jclouds.aws.s3.handlers.AWSRedirectionRetryHandler;
|
||||||
import org.jclouds.aws.s3.handlers.ParseAWSErrorFromXmlContent;
|
import org.jclouds.aws.s3.handlers.ParseAWSErrorFromXmlContent;
|
||||||
|
@ -41,6 +39,7 @@ import org.jclouds.util.DateService;
|
||||||
import org.jclouds.util.Jsr330;
|
import org.jclouds.util.Jsr330;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
@ -72,13 +71,13 @@ public class S3RestClientModuleTest {
|
||||||
void testUpdatesOnlyOncePerSecond() throws NoSuchMethodException, InterruptedException {
|
void testUpdatesOnlyOncePerSecond() throws NoSuchMethodException, InterruptedException {
|
||||||
S3RestClientModule module = new S3RestClientModule();
|
S3RestClientModule module = new S3RestClientModule();
|
||||||
|
|
||||||
ConcurrentMap<String, String> map = module.provideTimeStampCache(1, new DateService());
|
Supplier<String> map = module.provideTimeStampCache(1, new DateService());
|
||||||
String timeStamp = map.get("foo");
|
String timeStamp = map.get();
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
map.get("foo");
|
map.get();
|
||||||
assertEquals(timeStamp, map.get("foo"));
|
assertEquals(timeStamp, map.get());
|
||||||
Thread.sleep(1001);
|
Thread.sleep(1001);
|
||||||
assertFalse(timeStamp.equals(map.get("foo")));
|
assertFalse(timeStamp.equals(map.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -24,14 +24,19 @@
|
||||||
package org.jclouds.azure.storage.blob;
|
package org.jclouds.azure.storage.blob;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static org.jclouds.azure.storage.blob.reference.AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT;
|
||||||
|
import static org.jclouds.azure.storage.blob.reference.AzureBlobConstants.PROPERTY_AZUREBLOB_METADATA_PREFIX;
|
||||||
|
import static org.jclouds.azure.storage.blob.reference.AzureBlobConstants.PROPERTY_AZUREBLOB_RETRY;
|
||||||
|
import static org.jclouds.azure.storage.blob.reference.AzureBlobConstants.PROPERTY_AZUREBLOB_SESSIONINTERVAL;
|
||||||
|
import static org.jclouds.azure.storage.blob.reference.AzureBlobConstants.PROPERTY_AZUREBLOB_TIMEOUT;
|
||||||
|
import static org.jclouds.azure.storage.reference.AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT;
|
||||||
|
import static org.jclouds.azure.storage.reference.AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY;
|
||||||
import static org.jclouds.azure.storage.reference.AzureStorageConstants.PROPERTY_AZURESTORAGE_SESSIONINTERVAL;
|
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;
|
import java.net.URI;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.azure.storage.blob.reference.AzureBlobConstants;
|
|
||||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
|
||||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
|
||||||
import org.jclouds.http.HttpPropertiesBuilder;
|
import org.jclouds.http.HttpPropertiesBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,10 +48,10 @@ public class AzureBlobPropertiesBuilder extends HttpPropertiesBuilder {
|
||||||
@Override
|
@Override
|
||||||
protected Properties defaultProperties() {
|
protected Properties defaultProperties() {
|
||||||
Properties properties = super.defaultProperties();
|
Properties properties = super.defaultProperties();
|
||||||
properties.setProperty(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT,
|
properties
|
||||||
"https://{account}.blob.core.windows.net");
|
.setProperty(PROPERTY_AZUREBLOB_ENDPOINT, "https://{account}.blob.core.windows.net");
|
||||||
properties.setProperty(AzureBlobConstants.PROPERTY_AZUREBLOB_METADATA_PREFIX, "x-ms-meta-");
|
properties.setProperty(PROPERTY_AZUREBLOB_METADATA_PREFIX, "x-ms-meta-");
|
||||||
properties.setProperty(BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX, "x-ms-meta-");
|
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-ms-meta-");
|
||||||
properties.setProperty(PROPERTY_AZURESTORAGE_SESSIONINTERVAL, 60 + "");
|
properties.setProperty(PROPERTY_AZURESTORAGE_SESSIONINTERVAL, 60 + "");
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
@ -61,29 +66,48 @@ public class AzureBlobPropertiesBuilder extends HttpPropertiesBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public AzureBlobPropertiesBuilder withCredentials(String id, String secret) {
|
public AzureBlobPropertiesBuilder withCredentials(String id, String secret) {
|
||||||
properties.setProperty(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT, checkNotNull(id,
|
properties
|
||||||
"azureStorageAccount"));
|
.setProperty(PROPERTY_AZURESTORAGE_ACCOUNT, checkNotNull(id, "azureStorageAccount"));
|
||||||
properties.setProperty(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY, checkNotNull(secret,
|
properties.setProperty(PROPERTY_AZURESTORAGE_KEY, checkNotNull(secret, "azureStorageKey"));
|
||||||
"azureStorageKey"));
|
String endpoint = properties.getProperty(PROPERTY_AZUREBLOB_ENDPOINT);
|
||||||
String endpoint = properties.getProperty(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT);
|
properties.setProperty(PROPERTY_AZUREBLOB_ENDPOINT, endpoint.replaceAll("\\{account\\}", id));
|
||||||
properties.setProperty(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT, endpoint.replaceAll(
|
|
||||||
"\\{account\\}", id));
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AzureBlobPropertiesBuilder withEndpoint(URI endpoint) {
|
public AzureBlobPropertiesBuilder withEndpoint(URI endpoint) {
|
||||||
String account = checkNotNull(properties
|
String account = checkNotNull(properties.getProperty(PROPERTY_AZURESTORAGE_ACCOUNT),
|
||||||
.getProperty(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT),
|
|
||||||
"azureStorageAccount");
|
"azureStorageAccount");
|
||||||
properties.setProperty(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT, checkNotNull(endpoint,
|
properties.setProperty(PROPERTY_AZUREBLOB_ENDPOINT, checkNotNull(endpoint, "endpoint")
|
||||||
"endpoint").toString());
|
.toString());
|
||||||
properties.setProperty(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT, endpoint.toString()
|
properties.setProperty(PROPERTY_AZUREBLOB_ENDPOINT, endpoint.toString().replaceAll(
|
||||||
.replaceAll("\\{account\\}", account));
|
"\\{account\\}", account));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AzureBlobPropertiesBuilder withTimeStampExpiration(long seconds) {
|
public AzureBlobPropertiesBuilder withTimeStampExpiration(long seconds) {
|
||||||
properties.setProperty(PROPERTY_AZURESTORAGE_SESSIONINTERVAL, seconds + "");
|
properties.setProperty(PROPERTY_AZUREBLOB_SESSIONINTERVAL, seconds + "");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* longest time a single synchronous operation can take before throwing an exception.
|
||||||
|
*/
|
||||||
|
public AzureBlobPropertiesBuilder withRequestTimeout(long milliseconds) {
|
||||||
|
properties.setProperty(PROPERTY_AZUREBLOB_TIMEOUT, Long.toString(milliseconds));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* longest time a single synchronous operation can take before throwing an exception.
|
||||||
|
*/
|
||||||
|
public AzureBlobPropertiesBuilder withMaxRetries(int retries) {
|
||||||
|
properties.setProperty(PROPERTY_AZUREBLOB_RETRY, Integer.toString(retries));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AzureBlobPropertiesBuilder withMetaPrefix(String prefix) {
|
||||||
|
properties.setProperty(PROPERTY_AZUREBLOB_METADATA_PREFIX, prefix);
|
||||||
|
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, prefix);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,26 +23,27 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azure.storage.blob.binders;
|
package org.jclouds.azure.storage.blob.binders;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.*;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
import org.jclouds.azure.storage.blob.blobstore.functions.AzureBlobToBlob;
|
import org.jclouds.azure.storage.blob.blobstore.functions.AzureBlobToBlob;
|
||||||
import org.jclouds.azure.storage.blob.domain.AzureBlob;
|
import org.jclouds.azure.storage.blob.domain.AzureBlob;
|
||||||
|
import org.jclouds.azure.storage.blob.reference.AzureBlobConstants;
|
||||||
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
|
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.rest.Binder;
|
|
||||||
|
|
||||||
public class BindAzureBlobToEntity implements Binder {
|
public class BindAzureBlobToEntity extends BindBlobToEntityAndUserMetadataToHeadersWithPrefix {
|
||||||
|
|
||||||
private final BindBlobToEntityAndUserMetadataToHeadersWithPrefix blobBinder;
|
|
||||||
private final AzureBlobToBlob azureBlob2Blob;
|
private final AzureBlobToBlob azureBlob2Blob;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public BindAzureBlobToEntity(AzureBlobToBlob azureBlob2Blob,
|
public BindAzureBlobToEntity(AzureBlobToBlob azureBlob2Blob,
|
||||||
BindBlobToEntityAndUserMetadataToHeadersWithPrefix blobBinder) {
|
@Named(AzureBlobConstants.PROPERTY_AZUREBLOB_METADATA_PREFIX) String prefix) {
|
||||||
this.blobBinder = blobBinder;
|
super(prefix);
|
||||||
this.azureBlob2Blob = azureBlob2Blob;
|
this.azureBlob2Blob = azureBlob2Blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ public class BindAzureBlobToEntity implements Binder {
|
||||||
checkArgument(
|
checkArgument(
|
||||||
checkNotNull(object.getContentLength(), "object.getContentLength()") <= 64 * 1024 * 1024,
|
checkNotNull(object.getContentLength(), "object.getContentLength()") <= 64 * 1024 * 1024,
|
||||||
"maximum size for put Blob is 64MB");
|
"maximum size for put Blob is 64MB");
|
||||||
blobBinder.bindToRequest(request, azureBlob2Blob.apply(object));
|
super.bindToRequest(request, azureBlob2Blob.apply(object));
|
||||||
|
|
||||||
if (object.getProperties().getContentLanguage() != null) {
|
if (object.getProperties().getContentLanguage() != null) {
|
||||||
request.getHeaders().put(HttpHeaders.CONTENT_LANGUAGE,
|
request.getHeaders().put(HttpHeaders.CONTENT_LANGUAGE,
|
||||||
|
|
|
@ -23,8 +23,15 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azure.storage.blob.blobstore;
|
package org.jclouds.azure.storage.blob.blobstore;
|
||||||
|
|
||||||
|
import static org.jclouds.azure.storage.blob.reference.AzureBlobConstants.PROPERTY_AZUREBLOB_METADATA_PREFIX;
|
||||||
|
import static org.jclouds.azure.storage.blob.reference.AzureBlobConstants.PROPERTY_AZUREBLOB_RETRY;
|
||||||
|
import static org.jclouds.azure.storage.blob.reference.AzureBlobConstants.PROPERTY_AZUREBLOB_TIMEOUT;
|
||||||
|
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_BLOBSTORE_RETRY;
|
||||||
|
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||||
|
@ -34,6 +41,7 @@ import org.jclouds.blobstore.BlobStoreContextBuilder;
|
||||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
@ -55,7 +63,17 @@ public class AzureBlobStoreContextBuilder extends BlobStoreContextBuilder<AzureB
|
||||||
|
|
||||||
public AzureBlobStoreContextBuilder(Properties props) {
|
public AzureBlobStoreContextBuilder(Properties props) {
|
||||||
super(new TypeLiteral<AzureBlobClient>() {
|
super(new TypeLiteral<AzureBlobClient>() {
|
||||||
}, props);
|
}, convert(props));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Properties convert(Properties props) {
|
||||||
|
for (Entry<String, String> entry : ImmutableMap.of(PROPERTY_AZUREBLOB_METADATA_PREFIX,
|
||||||
|
PROPERTY_USER_METADATA_PREFIX, PROPERTY_AZUREBLOB_RETRY, PROPERTY_BLOBSTORE_RETRY,
|
||||||
|
PROPERTY_AZUREBLOB_TIMEOUT, PROPERTY_USER_METADATA_PREFIX).entrySet()) {
|
||||||
|
if (props.containsKey(entry.getKey()))
|
||||||
|
props.setProperty(entry.getValue(), props.getProperty(entry.getKey()));
|
||||||
|
}
|
||||||
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.net.URI;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||||
|
import org.jclouds.azure.storage.blob.AzureBlobPropertiesBuilder;
|
||||||
import org.jclouds.blobstore.BlobStoreContext;
|
import org.jclouds.blobstore.BlobStoreContext;
|
||||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
|
@ -34,8 +35,7 @@ import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link AzureBlobStoreContext} instances based on the most commonly requested
|
* Creates {@link AzureBlobStoreContext} instances based on the most commonly requested arguments.
|
||||||
* arguments.
|
|
||||||
* <p/>
|
* <p/>
|
||||||
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
|
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -49,20 +49,19 @@ import com.google.inject.Module;
|
||||||
public class AzureBlobStoreContextFactory {
|
public class AzureBlobStoreContextFactory {
|
||||||
public static BlobStoreContext<AzureBlobClient> createContext(Properties properties,
|
public static BlobStoreContext<AzureBlobClient> createContext(Properties properties,
|
||||||
Module... modules) {
|
Module... modules) {
|
||||||
return new AzureBlobStoreContextBuilder(new AzureBlobStorePropertiesBuilder(
|
return new AzureBlobStoreContextBuilder(new AzureBlobPropertiesBuilder(properties).build())
|
||||||
properties).build()).withModules(modules).buildContext();
|
.withModules(modules).buildContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlobStoreContext<AzureBlobClient> createContext(String user,
|
public static BlobStoreContext<AzureBlobClient> createContext(String user, String encodedKey,
|
||||||
|
Module... modules) {
|
||||||
|
return new AzureBlobStoreContextBuilder(new AzureBlobPropertiesBuilder(user, encodedKey)
|
||||||
|
.build()).withModules(modules).buildContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BlobStoreContext<AzureBlobClient> createContext(URI endpoint, String user,
|
||||||
String encodedKey, Module... modules) {
|
String encodedKey, Module... modules) {
|
||||||
return new AzureBlobStoreContextBuilder(new AzureBlobStorePropertiesBuilder(
|
return new AzureBlobStoreContextBuilder(new AzureBlobPropertiesBuilder(user, encodedKey)
|
||||||
user, encodedKey).build()).withModules(modules).buildContext();
|
.withEndpoint(endpoint).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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -32,6 +32,24 @@ import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||||
*/
|
*/
|
||||||
public interface AzureBlobConstants extends AzureStorageConstants {
|
public interface AzureBlobConstants extends AzureStorageConstants {
|
||||||
public static final String PROPERTY_AZUREBLOB_ENDPOINT = "jclouds.azureblob.endpoint";
|
public static final String PROPERTY_AZUREBLOB_ENDPOINT = "jclouds.azureblob.endpoint";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* how long do we wait before obtaining a new timestamp for requests.
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_AZUREBLOB_SESSIONINTERVAL = "jclouds.azureblob.sessioninterval";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* longest time a single synchronous operation can take before throwing an exception.
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_AZUREBLOB_TIMEOUT = "jclouds.azureblob.timeout";
|
||||||
|
/**
|
||||||
|
* time to pause before retrying a transient failure
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_AZUREBLOB_RETRY = "jclouds.azureblob.retry";
|
||||||
|
/**
|
||||||
|
* Any header starting with this prefix is considered user metadata. It will be stored with the
|
||||||
|
* object and returned when you retrieve the object/
|
||||||
|
*/
|
||||||
public static final String PROPERTY_AZUREBLOB_METADATA_PREFIX = "jclouds.azureblob.metaprefix";
|
public static final String PROPERTY_AZUREBLOB_METADATA_PREFIX = "jclouds.azureblob.metaprefix";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azure.storage.blob;
|
package org.jclouds.azure.storage.blob;
|
||||||
|
|
||||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -35,6 +34,7 @@ import org.jclouds.azure.storage.blob.config.AzureBlobRestClientModule;
|
||||||
import org.jclouds.azure.storage.blob.config.AzureBlobStubClientModule;
|
import org.jclouds.azure.storage.blob.config.AzureBlobStubClientModule;
|
||||||
import org.jclouds.azure.storage.blob.domain.AzureBlob;
|
import org.jclouds.azure.storage.blob.domain.AzureBlob;
|
||||||
import org.jclouds.azure.storage.blob.internal.StubAzureBlobClient;
|
import org.jclouds.azure.storage.blob.internal.StubAzureBlobClient;
|
||||||
|
import org.jclouds.azure.storage.blob.reference.AzureBlobConstants;
|
||||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
|
@ -57,7 +57,8 @@ public class AzureBlobContextBuilderTest {
|
||||||
public void testNewBuilder() {
|
public void testNewBuilder() {
|
||||||
AzureBlobContextBuilder builder = new AzureBlobContextBuilder(new AzureBlobPropertiesBuilder(
|
AzureBlobContextBuilder builder = new AzureBlobContextBuilder(new AzureBlobPropertiesBuilder(
|
||||||
"id", "secret").build()).withModules(new AzureBlobStubClientModule());
|
"id", "secret").build()).withModules(new AzureBlobStubClientModule());
|
||||||
assertEquals(builder.getProperties().getProperty(PROPERTY_USER_METADATA_PREFIX), "x-ms-meta-");
|
assertEquals(builder.getProperties().getProperty(
|
||||||
|
AzureBlobConstants.PROPERTY_AZUREBLOB_METADATA_PREFIX), "x-ms-meta-");
|
||||||
assertEquals(builder.getProperties().getProperty(
|
assertEquals(builder.getProperties().getProperty(
|
||||||
AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT), "id");
|
AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT), "id");
|
||||||
assertEquals(builder.getProperties().getProperty(
|
assertEquals(builder.getProperties().getProperty(
|
||||||
|
@ -65,8 +66,9 @@ public class AzureBlobContextBuilderTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBuildContext() {
|
public void testBuildContext() {
|
||||||
RestContext<AzureBlobClient> context = new AzureBlobContextBuilder(new AzureBlobPropertiesBuilder("id",
|
RestContext<AzureBlobClient> context = new AzureBlobContextBuilder(
|
||||||
"secret").build()).withModules(new AzureBlobStubClientModule()).buildContext();
|
new AzureBlobPropertiesBuilder("id", "secret").build()).withModules(
|
||||||
|
new AzureBlobStubClientModule()).buildContext();
|
||||||
assertEquals(context.getClass(), RestContextImpl.class);
|
assertEquals(context.getClass(), RestContextImpl.class);
|
||||||
assertEquals(context.getApi().getClass(), StubAzureBlobClient.class);
|
assertEquals(context.getApi().getClass(), StubAzureBlobClient.class);
|
||||||
assertEquals(context.getAccount(), "id");
|
assertEquals(context.getAccount(), "id");
|
||||||
|
@ -79,7 +81,8 @@ public class AzureBlobContextBuilderTest {
|
||||||
assert i.getInstance(Key.get(new TypeLiteral<RestContext<AzureBlobClient>>() {
|
assert i.getInstance(Key.get(new TypeLiteral<RestContext<AzureBlobClient>>() {
|
||||||
})) != null;
|
})) != null;
|
||||||
assert i.getInstance(AzureBlob.class) != null;
|
assert i.getInstance(AzureBlob.class) != null;
|
||||||
assert i.getInstance(Blob.class) != null; }
|
assert i.getInstance(Blob.class) != null;
|
||||||
|
}
|
||||||
|
|
||||||
protected void testAddContextModule() {
|
protected void testAddContextModule() {
|
||||||
List<Module> modules = new ArrayList<Module>();
|
List<Module> modules = new ArrayList<Module>();
|
||||||
|
|
|
@ -31,6 +31,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||||
|
import org.jclouds.azure.storage.blob.AzureBlobPropertiesBuilder;
|
||||||
import org.jclouds.azure.storage.blob.blobstore.config.AzureBlobStoreContextModule;
|
import org.jclouds.azure.storage.blob.blobstore.config.AzureBlobStoreContextModule;
|
||||||
import org.jclouds.azure.storage.blob.config.AzureBlobRestClientModule;
|
import org.jclouds.azure.storage.blob.config.AzureBlobRestClientModule;
|
||||||
import org.jclouds.azure.storage.blob.config.AzureBlobStubClientModule;
|
import org.jclouds.azure.storage.blob.config.AzureBlobStubClientModule;
|
||||||
|
@ -68,7 +69,7 @@ public class AzureBlobStoreContextBuilderTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private AzureBlobStoreContextBuilder newBuilder() {
|
private AzureBlobStoreContextBuilder newBuilder() {
|
||||||
return new AzureBlobStoreContextBuilder(new AzureBlobStorePropertiesBuilder("id",
|
return new AzureBlobStoreContextBuilder(new AzureBlobPropertiesBuilder("id",
|
||||||
"secret").build()).withModules(new AzureBlobStubClientModule());
|
"secret").build()).withModules(new AzureBlobStubClientModule());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,9 @@
|
||||||
package org.jclouds.azure.storage.blob.blobstore.integration;
|
package org.jclouds.azure.storage.blob.blobstore.integration;
|
||||||
|
|
||||||
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
import org.jclouds.azure.storage.blob.AzureBlobClient;
|
||||||
|
import org.jclouds.azure.storage.blob.AzureBlobPropertiesBuilder;
|
||||||
import org.jclouds.azure.storage.blob.blobstore.AzureBlobStoreContextBuilder;
|
import org.jclouds.azure.storage.blob.blobstore.AzureBlobStoreContextBuilder;
|
||||||
import org.jclouds.azure.storage.blob.blobstore.AzureBlobStoreContextFactory;
|
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.azure.storage.blob.config.AzureBlobStubClientModule;
|
||||||
import org.jclouds.blobstore.BlobStoreContext;
|
import org.jclouds.blobstore.BlobStoreContext;
|
||||||
import org.jclouds.blobstore.integration.internal.BaseTestInitializer;
|
import org.jclouds.blobstore.integration.internal.BaseTestInitializer;
|
||||||
|
@ -43,7 +43,7 @@ public class AzureBlobTestInitializer extends BaseTestInitializer<AzureBlobClien
|
||||||
@Override
|
@Override
|
||||||
protected BlobStoreContext<AzureBlobClient> createLiveContext(Module configurationModule,
|
protected BlobStoreContext<AzureBlobClient> createLiveContext(Module configurationModule,
|
||||||
String url, String app, String account, String key) {
|
String url, String app, String account, String key) {
|
||||||
return new AzureBlobStoreContextBuilder(new AzureBlobStorePropertiesBuilder(
|
return new AzureBlobStoreContextBuilder(new AzureBlobPropertiesBuilder(
|
||||||
account, key).relaxSSLHostname().build()).withModules(configurationModule,
|
account, key).relaxSSLHostname().build()).withModules(configurationModule,
|
||||||
new Log4JLoggingModule()).buildContext();
|
new Log4JLoggingModule()).buildContext();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,12 @@ package org.jclouds.azure.storage.config;
|
||||||
|
|
||||||
import static org.jclouds.azure.storage.reference.AzureStorageConstants.PROPERTY_AZURESTORAGE_SESSIONINTERVAL;
|
import static org.jclouds.azure.storage.reference.AzureStorageConstants.PROPERTY_AZURESTORAGE_SESSIONINTERVAL;
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import org.jclouds.azure.storage.handlers.ParseAzureStorageErrorFromXmlContent;
|
import org.jclouds.azure.storage.handlers.ParseAzureStorageErrorFromXmlContent;
|
||||||
|
import org.jclouds.concurrent.ExpirableSupplier;
|
||||||
import org.jclouds.http.HttpErrorHandler;
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
import org.jclouds.http.RequiresHttp;
|
import org.jclouds.http.RequiresHttp;
|
||||||
import org.jclouds.http.annotation.ClientError;
|
import org.jclouds.http.annotation.ClientError;
|
||||||
|
@ -40,8 +40,7 @@ import org.jclouds.rest.ConfiguresRestClient;
|
||||||
import org.jclouds.util.DateService;
|
import org.jclouds.util.DateService;
|
||||||
import org.jclouds.util.TimeStamp;
|
import org.jclouds.util.TimeStamp;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.MapMaker;
|
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
|
@ -56,8 +55,8 @@ public class AzureStorageRestClientModule extends AbstractModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@TimeStamp
|
@TimeStamp
|
||||||
protected String provideTimeStamp(@TimeStamp ConcurrentMap<String, String> cache) {
|
protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
|
||||||
return cache.get("doesn't matter");
|
return cache.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,15 +64,14 @@ public class AzureStorageRestClientModule extends AbstractModule {
|
||||||
*/
|
*/
|
||||||
@Provides
|
@Provides
|
||||||
@TimeStamp
|
@TimeStamp
|
||||||
ConcurrentMap<String, String> provideTimeStampCache(
|
Supplier<String> provideTimeStampCache(
|
||||||
@Named(PROPERTY_AZURESTORAGE_SESSIONINTERVAL) long seconds,
|
@Named(PROPERTY_AZURESTORAGE_SESSIONINTERVAL) long seconds,
|
||||||
final DateService dateService) {
|
final DateService dateService) {
|
||||||
return new MapMaker().expiration(seconds, TimeUnit.SECONDS).makeComputingMap(
|
return new ExpirableSupplier<String>(new Supplier<String>() {
|
||||||
new Function<String, String>() {
|
public String get() {
|
||||||
public String apply(String key) {
|
|
||||||
return dateService.rfc822DateFormat();
|
return dateService.rfc822DateFormat();
|
||||||
}
|
}
|
||||||
});
|
}, seconds, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -29,8 +29,6 @@ import static org.jclouds.azure.storage.reference.AzureStorageConstants.PROPERTY
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertFalse;
|
import static org.testng.Assert.assertFalse;
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
|
|
||||||
import org.jclouds.azure.storage.handlers.ParseAzureStorageErrorFromXmlContent;
|
import org.jclouds.azure.storage.handlers.ParseAzureStorageErrorFromXmlContent;
|
||||||
import org.jclouds.concurrent.WithinThreadExecutorService;
|
import org.jclouds.concurrent.WithinThreadExecutorService;
|
||||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||||
|
@ -43,6 +41,7 @@ import org.jclouds.util.DateService;
|
||||||
import org.jclouds.util.Jsr330;
|
import org.jclouds.util.Jsr330;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
@ -70,13 +69,13 @@ public class AzureStorageRestClientModuleTest {
|
||||||
void testUpdatesOnlyOncePerSecond() throws NoSuchMethodException, InterruptedException {
|
void testUpdatesOnlyOncePerSecond() throws NoSuchMethodException, InterruptedException {
|
||||||
AzureStorageRestClientModule module = new AzureStorageRestClientModule();
|
AzureStorageRestClientModule module = new AzureStorageRestClientModule();
|
||||||
|
|
||||||
ConcurrentMap<String, String> map = module.provideTimeStampCache(1, new DateService());
|
Supplier<String> map = module.provideTimeStampCache(1, new DateService());
|
||||||
String timeStamp = map.get("foo");
|
String timeStamp = map.get();
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
map.get("foo");
|
map.get();
|
||||||
assertEquals(timeStamp, map.get("foo"));
|
assertEquals(timeStamp, map.get());
|
||||||
Thread.sleep(1001);
|
Thread.sleep(1001);
|
||||||
assertFalse(timeStamp.equals(map.get("foo")));
|
assertFalse(timeStamp.equals(map.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -29,6 +29,11 @@ package org.jclouds.blobstore.reference;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public interface BlobStoreConstants {
|
public interface BlobStoreConstants {
|
||||||
|
/**
|
||||||
|
* comma-separated, fully qualified class names of implementations of BlobStoreContextBuilder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_BLOBSTORE_CONTEXTBUILDERS = "jclouds.blobstore.contextbuilders";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* longest time a single synchronous operation can take before throwing an exception.
|
* longest time a single synchronous operation can take before throwing an exception.
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class ParseBlobFromHeadersAndHttpContentTest {
|
||||||
metadataParser, blobProvider);
|
metadataParser, blobProvider);
|
||||||
Multimap<String, String> allHeaders = ImmutableMultimap.of("key", "value");
|
Multimap<String, String> allHeaders = ImmutableMultimap.of("key", "value");
|
||||||
HttpResponse from = new HttpResponse();
|
HttpResponse from = new HttpResponse();
|
||||||
from.setHeaders(allHeaders);
|
from.getHeaders().putAll(allHeaders);
|
||||||
Blob object = blobProvider.create(null);
|
Blob object = blobProvider.create(null);
|
||||||
callable.addAllHeadersTo(from, object);
|
callable.addAllHeadersTo(from, object);
|
||||||
assertEquals(object.getAllHeaders().get("key"), Collections.singletonList("value"));
|
assertEquals(object.getAllHeaders().get("key"), Collections.singletonList("value"));
|
||||||
|
|
|
@ -142,7 +142,7 @@ public class ParseBlobMetadataFromHeadersTest {
|
||||||
public void testAddUserMetadataTo() {
|
public void testAddUserMetadataTo() {
|
||||||
Multimap<String, String> allHeaders = ImmutableMultimap.of("prefix" + "key", "value");
|
Multimap<String, String> allHeaders = ImmutableMultimap.of("prefix" + "key", "value");
|
||||||
HttpResponse from = new HttpResponse();
|
HttpResponse from = new HttpResponse();
|
||||||
from.setHeaders(allHeaders);
|
from.getHeaders().putAll(allHeaders);
|
||||||
MutableBlobMetadata metadata = blobMetadataProvider.get();
|
MutableBlobMetadata metadata = blobMetadataProvider.get();
|
||||||
parser.addUserMetadataTo(from, metadata);
|
parser.addUserMetadataTo(from, metadata);
|
||||||
assertEquals(metadata.getUserMetadata().get("key"), "value");
|
assertEquals(metadata.getUserMetadata().get("key"), "value");
|
||||||
|
|
|
@ -82,7 +82,7 @@ public class BaseBlobStoreIntegrationTest<S> {
|
||||||
protected static volatile AtomicInteger containerIndex = new AtomicInteger(0);
|
protected static volatile AtomicInteger containerIndex = new AtomicInteger(0);
|
||||||
|
|
||||||
protected volatile BlobStoreContext<S> context;
|
protected volatile BlobStoreContext<S> context;
|
||||||
protected static volatile int containerCount = 20;
|
protected static volatile int containerCount = 10;
|
||||||
public static final String CONTAINER_PREFIX = System.getProperty("user.name") + "-blobstore";
|
public static final String CONTAINER_PREFIX = System.getProperty("user.name") + "-blobstore";
|
||||||
/**
|
/**
|
||||||
* two test groups integration and live.
|
* two test groups integration and live.
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.concurrent;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Works in google app engine since it doesn't use threads.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class ExpirableSupplier<V> implements Supplier<V> {
|
||||||
|
private final Supplier<V> supplier;
|
||||||
|
private final AtomicReference<V> currentValue;
|
||||||
|
private final AtomicLong trigger;
|
||||||
|
private final long expirationNanos;
|
||||||
|
|
||||||
|
public ExpirableSupplier(Supplier<V> supplier, long duration, TimeUnit unit) {
|
||||||
|
this.supplier = supplier;
|
||||||
|
this.expirationNanos = unit.toNanos(duration);
|
||||||
|
this.currentValue = new AtomicReference<V>(null);
|
||||||
|
trigger = new AtomicLong(System.nanoTime() + expirationNanos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateIfExpired() {
|
||||||
|
V current = currentValue.get();
|
||||||
|
if (current == null || trigger.get() - System.nanoTime() <= 0) {
|
||||||
|
trigger.set(System.nanoTime() + expirationNanos);
|
||||||
|
// we always want the last one to win. think login session
|
||||||
|
currentValue.set(supplier.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public V get() {
|
||||||
|
updateIfExpired();
|
||||||
|
return currentValue.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -47,13 +47,14 @@ public class HttpMessage {
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHeaders(Multimap<String, String> headers) {
|
/**
|
||||||
this.headers = Multimaps.synchronizedMultimap(headers);
|
* try to get the value, then try as lowercase.
|
||||||
}
|
*/
|
||||||
|
|
||||||
public String getFirstHeaderOrNull(String string) {
|
public String getFirstHeaderOrNull(String string) {
|
||||||
Collection<String> values = headers.get(string);
|
Collection<String> values = headers.get(string);
|
||||||
return (values != null && values.size() >= 1) ? values.iterator().next() : null;
|
if (values.size() == 0)
|
||||||
|
values = headers.get(string.toLowerCase());
|
||||||
|
return (values.size() >= 1) ? values.iterator().next() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -71,7 +71,7 @@ public class HttpRequest extends HttpMessage implements Request<URI> {
|
||||||
*/
|
*/
|
||||||
public HttpRequest(String method, URI endPoint, Multimap<String, String> headers) {
|
public HttpRequest(String method, URI endPoint, Multimap<String, String> headers) {
|
||||||
this(method, endPoint);
|
this(method, endPoint);
|
||||||
setHeaders(checkNotNull(headers, "headers"));
|
getHeaders().putAll(checkNotNull(headers, "headers"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,7 +84,7 @@ public class HttpRequest extends HttpMessage implements Request<URI> {
|
||||||
protected HttpRequest(String method, URI endPoint, Multimap<String, String> headers,
|
protected HttpRequest(String method, URI endPoint, Multimap<String, String> headers,
|
||||||
@Nullable Object entity) {
|
@Nullable Object entity) {
|
||||||
this(method, endPoint);
|
this(method, endPoint);
|
||||||
setHeaders(checkNotNull(headers, "headers"));
|
getHeaders().putAll(checkNotNull(headers, "headers"));
|
||||||
setEntity(entity);
|
setEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest.binders;
|
package org.jclouds.rest.binders;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
|
@ -40,7 +42,7 @@ public class BindToStringEntity implements Binder {
|
||||||
String stringEntity = entity.toString();
|
String stringEntity = entity.toString();
|
||||||
if (request.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE) == null)
|
if (request.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE) == null)
|
||||||
request.getHeaders().put(HttpHeaders.CONTENT_TYPE, "application/unknown");
|
request.getHeaders().put(HttpHeaders.CONTENT_TYPE, "application/unknown");
|
||||||
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, stringEntity.getBytes().length + "");
|
request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,Collections.singletonList(stringEntity.getBytes().length + ""));
|
||||||
request.setEntity(stringEntity);
|
request.setEntity(stringEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -354,7 +354,6 @@ public class RestAnnotationProcessor<T> {
|
||||||
|
|
||||||
GeneratedHttpRequest<T> request = new GeneratedHttpRequest<T>(httpMethod, endPoint, this,
|
GeneratedHttpRequest<T> request = new GeneratedHttpRequest<T>(httpMethod, endPoint, this,
|
||||||
declaring, method, args);
|
declaring, method, args);
|
||||||
request.setHeaders(headers);
|
|
||||||
addHostHeaderIfAnnotatedWithVirtualHost(headers, request.getEndpoint().getHost(), method);
|
addHostHeaderIfAnnotatedWithVirtualHost(headers, request.getEndpoint().getHost(), method);
|
||||||
addFiltersIfAnnotated(method, request);
|
addFiltersIfAnnotated(method, request);
|
||||||
if (stringEntity != null) {
|
if (stringEntity != null) {
|
||||||
|
@ -362,6 +361,7 @@ public class RestAnnotationProcessor<T> {
|
||||||
if (headers.get(HttpHeaders.CONTENT_TYPE) != null)
|
if (headers.get(HttpHeaders.CONTENT_TYPE) != null)
|
||||||
headers.put(HttpHeaders.CONTENT_TYPE, "application/unknown");
|
headers.put(HttpHeaders.CONTENT_TYPE, "application/unknown");
|
||||||
}
|
}
|
||||||
|
request.getHeaders().putAll(headers);
|
||||||
decorateRequest(request);
|
decorateRequest(request);
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,7 @@ public abstract class BaseJettyTest {
|
||||||
} else {
|
} else {
|
||||||
handleAction(request, response);
|
handleAction(request, response);
|
||||||
}
|
}
|
||||||
} else if (request.getHeader("Range") != null) {
|
} else if (request.getHeader("range") != null) {
|
||||||
response.sendError(404, "no content");
|
response.sendError(404, "no content");
|
||||||
} else if (request.getHeader("test") != null) {
|
} else if (request.getHeader("test") != null) {
|
||||||
response.setContentType("text/plain");
|
response.setContentType("text/plain");
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.mezeo.pcs2.functions;
|
package org.jclouds.mezeo.pcs2.functions;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -31,6 +33,7 @@ import com.google.common.base.Function;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@Singleton
|
||||||
public class ReturnFalseIfContainerNotFound implements Function<Exception, Boolean> {
|
public class ReturnFalseIfContainerNotFound implements Function<Exception, Boolean> {
|
||||||
|
|
||||||
public Boolean apply(Exception from) {
|
public Boolean apply(Exception from) {
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.mezeo.pcs2.functions;
|
package org.jclouds.mezeo.pcs2.functions;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.http.HttpResponseException;
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -31,6 +33,7 @@ import com.google.common.base.Function;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@Singleton
|
||||||
public class ReturnTrueIfContainerAlreadyExists implements Function<Exception, Boolean> {
|
public class ReturnTrueIfContainerAlreadyExists implements Function<Exception, Boolean> {
|
||||||
|
|
||||||
public Boolean apply(Exception from) {
|
public Boolean apply(Exception from) {
|
||||||
|
|
|
@ -23,8 +23,9 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudfiles;
|
package org.jclouds.rackspace.cloudfiles;
|
||||||
|
|
||||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
|
||||||
import static org.jclouds.rackspace.cloudfiles.reference.CloudFilesConstants.PROPERTY_CLOUDFILES_METADATA_PREFIX;
|
import static org.jclouds.rackspace.cloudfiles.reference.CloudFilesConstants.PROPERTY_CLOUDFILES_METADATA_PREFIX;
|
||||||
|
import static org.jclouds.rackspace.cloudfiles.reference.CloudFilesConstants.PROPERTY_CLOUDFILES_RETRY;
|
||||||
|
import static org.jclouds.rackspace.cloudfiles.reference.CloudFilesConstants.PROPERTY_CLOUDFILES_TIMEOUT;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
@ -40,7 +41,6 @@ public class CloudFilesPropertiesBuilder extends RackspacePropertiesBuilder {
|
||||||
protected Properties defaultProperties() {
|
protected Properties defaultProperties() {
|
||||||
Properties properties = super.defaultProperties();
|
Properties properties = super.defaultProperties();
|
||||||
properties.setProperty(PROPERTY_CLOUDFILES_METADATA_PREFIX, "X-Object-Meta-");
|
properties.setProperty(PROPERTY_CLOUDFILES_METADATA_PREFIX, "X-Object-Meta-");
|
||||||
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "X-Object-Meta-");
|
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,4 +52,24 @@ public class CloudFilesPropertiesBuilder extends RackspacePropertiesBuilder {
|
||||||
super(id, secret);
|
super(id, secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* longest time a single synchronous operation can take before throwing an exception.
|
||||||
|
*/
|
||||||
|
public CloudFilesPropertiesBuilder withRequestTimeout(long milliseconds) {
|
||||||
|
properties.setProperty(PROPERTY_CLOUDFILES_TIMEOUT, Long.toString(milliseconds));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* longest time a single synchronous operation can take before throwing an exception.
|
||||||
|
*/
|
||||||
|
public CloudFilesPropertiesBuilder withMaxRetries(int retries) {
|
||||||
|
properties.setProperty(PROPERTY_CLOUDFILES_RETRY, Integer.toString(retries));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CloudFilesPropertiesBuilder withMetaPrefix(String prefix) {
|
||||||
|
properties.setProperty(PROPERTY_CLOUDFILES_METADATA_PREFIX, prefix);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ package org.jclouds.rackspace.cloudfiles.binders;
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
|
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
|
||||||
|
@ -33,16 +34,15 @@ import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpUtils;
|
import org.jclouds.http.HttpUtils;
|
||||||
import org.jclouds.rackspace.cloudfiles.blobstore.functions.ObjectToBlob;
|
import org.jclouds.rackspace.cloudfiles.blobstore.functions.ObjectToBlob;
|
||||||
import org.jclouds.rackspace.cloudfiles.domain.CFObject;
|
import org.jclouds.rackspace.cloudfiles.domain.CFObject;
|
||||||
import org.jclouds.rest.Binder;
|
import org.jclouds.rackspace.cloudfiles.reference.CloudFilesConstants;
|
||||||
|
|
||||||
public class BindCFObjectToEntity implements Binder {
|
public class BindCFObjectToEntity extends BindBlobToEntityAndUserMetadataToHeadersWithPrefix {
|
||||||
private final BindBlobToEntityAndUserMetadataToHeadersWithPrefix blobBinder;
|
|
||||||
private final ObjectToBlob object2Blob;
|
private final ObjectToBlob object2Blob;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public BindCFObjectToEntity(ObjectToBlob object2Blob,
|
public BindCFObjectToEntity(ObjectToBlob object2Blob,
|
||||||
BindBlobToEntityAndUserMetadataToHeadersWithPrefix blobBinder) {
|
@Named(CloudFilesConstants.PROPERTY_CLOUDFILES_METADATA_PREFIX) String prefix) {
|
||||||
this.blobBinder = blobBinder;
|
super(prefix);
|
||||||
this.object2Blob = object2Blob;
|
this.object2Blob = object2Blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ public class BindCFObjectToEntity implements Binder {
|
||||||
request.getHeaders().put("Transfer-Encoding", "chunked");
|
request.getHeaders().put("Transfer-Encoding", "chunked");
|
||||||
}
|
}
|
||||||
|
|
||||||
blobBinder.bindToRequest(request, object2Blob.apply(object));
|
super.bindToRequest(request, object2Blob.apply(object));
|
||||||
if (object.getInfo().getHash() != null) {
|
if (object.getInfo().getHash() != null) {
|
||||||
request.getHeaders().put(HttpHeaders.ETAG,
|
request.getHeaders().put(HttpHeaders.ETAG,
|
||||||
HttpUtils.toHexString(object.getInfo().getHash()));
|
HttpUtils.toHexString(object.getInfo().getHash()));
|
||||||
|
|
|
@ -23,8 +23,15 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudfiles.blobstore;
|
package org.jclouds.rackspace.cloudfiles.blobstore;
|
||||||
|
|
||||||
|
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_BLOBSTORE_RETRY;
|
||||||
|
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||||
|
import static org.jclouds.rackspace.cloudfiles.reference.CloudFilesConstants.PROPERTY_CLOUDFILES_METADATA_PREFIX;
|
||||||
|
import static org.jclouds.rackspace.cloudfiles.reference.CloudFilesConstants.PROPERTY_CLOUDFILES_RETRY;
|
||||||
|
import static org.jclouds.rackspace.cloudfiles.reference.CloudFilesConstants.PROPERTY_CLOUDFILES_TIMEOUT;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
import org.jclouds.blobstore.BlobStoreContextBuilder;
|
import org.jclouds.blobstore.BlobStoreContextBuilder;
|
||||||
|
@ -35,13 +42,14 @@ import org.jclouds.rackspace.cloudfiles.blobstore.config.CloudFilesBlobStoreCont
|
||||||
import org.jclouds.rackspace.cloudfiles.config.CloudFilesRestClientModule;
|
import org.jclouds.rackspace.cloudfiles.config.CloudFilesRestClientModule;
|
||||||
import org.jclouds.rackspace.config.RackspaceAuthenticationRestModule;
|
import org.jclouds.rackspace.config.RackspaceAuthenticationRestModule;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link CloudFilesBlobStoreContext} or {@link Injector} instances based on the most commonly
|
* Creates {@link CloudFilesBlobStoreContext} or {@link Injector} instances based on the most
|
||||||
* requested arguments.
|
* commonly requested arguments.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
|
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -56,7 +64,17 @@ public class CloudFilesBlobStoreContextBuilder extends BlobStoreContextBuilder<C
|
||||||
|
|
||||||
public CloudFilesBlobStoreContextBuilder(Properties props) {
|
public CloudFilesBlobStoreContextBuilder(Properties props) {
|
||||||
super(new TypeLiteral<CloudFilesClient>() {
|
super(new TypeLiteral<CloudFilesClient>() {
|
||||||
}, props);
|
}, convert(props));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Properties convert(Properties props) {
|
||||||
|
for (Entry<String, String> entry : ImmutableMap.of(PROPERTY_CLOUDFILES_METADATA_PREFIX,
|
||||||
|
PROPERTY_USER_METADATA_PREFIX, PROPERTY_CLOUDFILES_RETRY, PROPERTY_BLOBSTORE_RETRY,
|
||||||
|
PROPERTY_CLOUDFILES_TIMEOUT, PROPERTY_USER_METADATA_PREFIX).entrySet()) {
|
||||||
|
if (props.containsKey(entry.getKey()))
|
||||||
|
props.setProperty(entry.getValue(), props.getProperty(entry.getKey()));
|
||||||
|
}
|
||||||
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.jclouds.blobstore.BlobStoreContext;
|
||||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
import org.jclouds.rackspace.cloudfiles.CloudFilesClient;
|
import org.jclouds.rackspace.cloudfiles.CloudFilesClient;
|
||||||
|
import org.jclouds.rackspace.cloudfiles.CloudFilesPropertiesBuilder;
|
||||||
|
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
|
@ -49,20 +50,19 @@ import com.google.inject.Module;
|
||||||
public class CloudFilesBlobStoreContextFactory {
|
public class CloudFilesBlobStoreContextFactory {
|
||||||
public static BlobStoreContext<CloudFilesClient> createContext(Properties properties,
|
public static BlobStoreContext<CloudFilesClient> createContext(Properties properties,
|
||||||
Module... modules) {
|
Module... modules) {
|
||||||
return new CloudFilesBlobStoreContextBuilder(new CloudFilesBlobStorePropertiesBuilder(
|
return new CloudFilesBlobStoreContextBuilder(new CloudFilesPropertiesBuilder(properties)
|
||||||
properties).build()).withModules(modules).buildContext();
|
.build()).withModules(modules).buildContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlobStoreContext<CloudFilesClient> createContext(String user,
|
public static BlobStoreContext<CloudFilesClient> createContext(String user, String key,
|
||||||
|
Module... modules) {
|
||||||
|
return new CloudFilesBlobStoreContextBuilder(new CloudFilesPropertiesBuilder(user, key)
|
||||||
|
.build()).withModules(modules).buildContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BlobStoreContext<CloudFilesClient> createContext(URI endpoint, String user,
|
||||||
String key, Module... modules) {
|
String key, Module... modules) {
|
||||||
return new CloudFilesBlobStoreContextBuilder(new CloudFilesBlobStorePropertiesBuilder(
|
return new CloudFilesBlobStoreContextBuilder(new CloudFilesPropertiesBuilder(user, key)
|
||||||
user, key).build()).withModules(modules).buildContext();
|
.withEndpoint(endpoint).build()).withModules(modules).buildContext();
|
||||||
}
|
|
||||||
|
|
||||||
public static BlobStoreContext<CloudFilesClient> createContext(URI endpoint,
|
|
||||||
String user, String key, Module... modules) {
|
|
||||||
return new CloudFilesBlobStoreContextBuilder(new CloudFilesBlobStorePropertiesBuilder(
|
|
||||||
user, key).withEndpoint(endpoint).build()).withModules(
|
|
||||||
modules).buildContext();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* 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.rackspace.cloudfiles.blobstore;
|
|
||||||
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
|
||||||
import org.jclouds.rackspace.cloudfiles.CloudFilesPropertiesBuilder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds properties used in CloudFiles Blob Stores
|
|
||||||
*
|
|
||||||
* @author Adrian Cole, Andrew Newdigate
|
|
||||||
*/
|
|
||||||
public class CloudFilesBlobStorePropertiesBuilder extends CloudFilesPropertiesBuilder {
|
|
||||||
|
|
||||||
public CloudFilesBlobStorePropertiesBuilder(String id, String secret) {
|
|
||||||
super(id, secret);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloudFilesBlobStorePropertiesBuilder(Properties properties) {
|
|
||||||
super(properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* longest time a single synchronous operation can take before throwing an exception.
|
|
||||||
*/
|
|
||||||
public CloudFilesBlobStorePropertiesBuilder withRequestTimeout(long milliseconds) {
|
|
||||||
properties.setProperty(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT, Long
|
|
||||||
.toString(milliseconds));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -50,6 +50,17 @@ public interface CloudFilesConstants extends RackspaceConstants {
|
||||||
*/
|
*/
|
||||||
String PATH = "path";
|
String PATH = "path";
|
||||||
|
|
||||||
String PROPERTY_CLOUDFILES_METADATA_PREFIX = "jclouds.cloudfiles.metaprefix";
|
/**
|
||||||
|
* longest time a single synchronous operation can take before throwing an exception.
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_CLOUDFILES_TIMEOUT = "jclouds.cloudfiles.timeout";
|
||||||
|
/**
|
||||||
|
* time to pause before retrying a transient failure
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_CLOUDFILES_RETRY = "jclouds.cloudfiles.retry";
|
||||||
|
/**
|
||||||
|
* Any header starting with this prefix is considered user metadata. It will be stored with the
|
||||||
|
* object and returned when you retrieve the object/
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_CLOUDFILES_METADATA_PREFIX = "jclouds.cloudfiles.metaprefix";
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.jclouds.blobstore.domain.internal.BlobImpl;
|
||||||
import org.jclouds.blobstore.internal.BlobStoreContextImpl;
|
import org.jclouds.blobstore.internal.BlobStoreContextImpl;
|
||||||
import org.jclouds.rackspace.StubRackspaceAuthenticationModule;
|
import org.jclouds.rackspace.StubRackspaceAuthenticationModule;
|
||||||
import org.jclouds.rackspace.cloudfiles.CloudFilesClient;
|
import org.jclouds.rackspace.cloudfiles.CloudFilesClient;
|
||||||
|
import org.jclouds.rackspace.cloudfiles.CloudFilesPropertiesBuilder;
|
||||||
import org.jclouds.rackspace.cloudfiles.blobstore.config.CloudFilesBlobStoreContextModule;
|
import org.jclouds.rackspace.cloudfiles.blobstore.config.CloudFilesBlobStoreContextModule;
|
||||||
import org.jclouds.rackspace.cloudfiles.config.CloudFilesRestClientModule;
|
import org.jclouds.rackspace.cloudfiles.config.CloudFilesRestClientModule;
|
||||||
import org.jclouds.rackspace.cloudfiles.config.CloudFilesStubClientModule;
|
import org.jclouds.rackspace.cloudfiles.config.CloudFilesStubClientModule;
|
||||||
|
@ -69,7 +70,7 @@ public class CloudFilesBlobStoreContextBuilderTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private CloudFilesBlobStoreContextBuilder newBuilder() {
|
private CloudFilesBlobStoreContextBuilder newBuilder() {
|
||||||
return new CloudFilesBlobStoreContextBuilder(new CloudFilesBlobStorePropertiesBuilder("id",
|
return new CloudFilesBlobStoreContextBuilder(new CloudFilesPropertiesBuilder("id",
|
||||||
"secret").build()).withModules(new CloudFilesStubClientModule(),
|
"secret").build()).withModules(new CloudFilesStubClientModule(),
|
||||||
new StubRackspaceAuthenticationModule());
|
new StubRackspaceAuthenticationModule());
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,9 @@ import org.jclouds.blobstore.integration.internal.BaseTestInitializer;
|
||||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.jclouds.rackspace.StubRackspaceAuthenticationModule;
|
import org.jclouds.rackspace.StubRackspaceAuthenticationModule;
|
||||||
import org.jclouds.rackspace.cloudfiles.CloudFilesClient;
|
import org.jclouds.rackspace.cloudfiles.CloudFilesClient;
|
||||||
|
import org.jclouds.rackspace.cloudfiles.CloudFilesPropertiesBuilder;
|
||||||
import org.jclouds.rackspace.cloudfiles.blobstore.CloudFilesBlobStoreContextBuilder;
|
import org.jclouds.rackspace.cloudfiles.blobstore.CloudFilesBlobStoreContextBuilder;
|
||||||
import org.jclouds.rackspace.cloudfiles.blobstore.CloudFilesBlobStoreContextFactory;
|
import org.jclouds.rackspace.cloudfiles.blobstore.CloudFilesBlobStoreContextFactory;
|
||||||
import org.jclouds.rackspace.cloudfiles.blobstore.CloudFilesBlobStorePropertiesBuilder;
|
|
||||||
import org.jclouds.rackspace.cloudfiles.config.CloudFilesStubClientModule;
|
import org.jclouds.rackspace.cloudfiles.config.CloudFilesStubClientModule;
|
||||||
|
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
@ -44,8 +44,8 @@ public class CloudFilesTestInitializer extends BaseTestInitializer<CloudFilesCli
|
||||||
@Override
|
@Override
|
||||||
protected BlobStoreContext<CloudFilesClient> createLiveContext(Module configurationModule,
|
protected BlobStoreContext<CloudFilesClient> createLiveContext(Module configurationModule,
|
||||||
String url, String app, String account, String key) {
|
String url, String app, String account, String key) {
|
||||||
return new CloudFilesBlobStoreContextBuilder(new CloudFilesBlobStorePropertiesBuilder(
|
return new CloudFilesBlobStoreContextBuilder(new CloudFilesPropertiesBuilder(account, key)
|
||||||
account, key).relaxSSLHostname().build()).withModules(configurationModule,
|
.relaxSSLHostname().build()).withModules(configurationModule,
|
||||||
new Log4JLoggingModule()).buildContext();
|
new Log4JLoggingModule()).buildContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,32 +51,27 @@ public class ParseAuthenticationResponseFromHeaders implements
|
||||||
* parses the http response headers to create a new {@link AuthenticationResponse} object.
|
* parses the http response headers to create a new {@link AuthenticationResponse} object.
|
||||||
*/
|
*/
|
||||||
public AuthenticationResponse apply(final HttpResponse from) {
|
public AuthenticationResponse apply(final HttpResponse from) {
|
||||||
|
|
||||||
return new AuthenticationResponse() {
|
return new AuthenticationResponse() {
|
||||||
|
|
||||||
public String getAuthToken() {
|
public String getAuthToken() {
|
||||||
return checkNotNull(from.getFirstHeaderOrNull(AUTH_TOKEN),
|
return checkNotNull(from.getFirstHeaderOrNull(AUTH_TOKEN), AUTH_TOKEN);
|
||||||
AUTH_TOKEN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public URI getCDNManagementUrl() {
|
public URI getCDNManagementUrl() {
|
||||||
String cdnManagementUrl = checkNotNull(from
|
String cdnManagementUrl = checkNotNull(from.getFirstHeaderOrNull(CDN_MANAGEMENT_URL),
|
||||||
.getFirstHeaderOrNull(CDN_MANAGEMENT_URL),
|
|
||||||
CDN_MANAGEMENT_URL);
|
CDN_MANAGEMENT_URL);
|
||||||
return URI.create(cdnManagementUrl);
|
return URI.create(cdnManagementUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
public URI getServerManagementUrl() {
|
public URI getServerManagementUrl() {
|
||||||
String serverManagementUrl = checkNotNull(from
|
String serverManagementUrl = checkNotNull(from
|
||||||
.getFirstHeaderOrNull(SERVER_MANAGEMENT_URL),
|
.getFirstHeaderOrNull(SERVER_MANAGEMENT_URL), SERVER_MANAGEMENT_URL);
|
||||||
SERVER_MANAGEMENT_URL);
|
|
||||||
return URI.create(serverManagementUrl);
|
return URI.create(serverManagementUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
public URI getStorageUrl() {
|
public URI getStorageUrl() {
|
||||||
String storageUrl = checkNotNull(from
|
String storageUrl = checkNotNull(from.getFirstHeaderOrNull(STORAGE_URL), STORAGE_URL
|
||||||
.getFirstHeaderOrNull(STORAGE_URL),
|
+ " not found in headers:" + from.getStatusLine() + " - " + from.getHeaders());
|
||||||
STORAGE_URL);
|
|
||||||
return URI.create(storageUrl);
|
return URI.create(storageUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,29 +30,27 @@ import static org.jclouds.vcloudx.reference.VCloudXConstants.PROPERTY_VCLOUDX_US
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.concurrent.ExpirableSupplier;
|
||||||
import org.jclouds.http.RequiresHttp;
|
import org.jclouds.http.RequiresHttp;
|
||||||
import org.jclouds.http.filters.BasicAuthentication;
|
import org.jclouds.http.filters.BasicAuthentication;
|
||||||
import org.jclouds.rest.RestClientFactory;
|
import org.jclouds.rest.RestClientFactory;
|
||||||
import org.jclouds.vcloudx.VCloudXLogin;
|
|
||||||
import org.jclouds.vcloudx.VCloudToken;
|
import org.jclouds.vcloudx.VCloudToken;
|
||||||
|
import org.jclouds.vcloudx.VCloudXLogin;
|
||||||
import org.jclouds.vcloudx.VCloudXLogin.VCloudXSession;
|
import org.jclouds.vcloudx.VCloudXLogin.VCloudXSession;
|
||||||
import org.jclouds.vcloudx.endpoints.Org;
|
import org.jclouds.vcloudx.endpoints.Org;
|
||||||
import org.jclouds.vcloudx.endpoints.VCloudX;
|
import org.jclouds.vcloudx.endpoints.VCloudX;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.MapMaker;
|
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the VCloudX authentication service connection, including logging and http
|
* Configures the VCloudX authentication service connection, including logging and http transport.
|
||||||
* transport.
|
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@ -65,28 +63,28 @@ public class RestVCloudXAuthenticationModule extends AbstractModule {
|
||||||
|
|
||||||
@VCloudToken
|
@VCloudToken
|
||||||
@Provides
|
@Provides
|
||||||
String provideVCloudToken(ConcurrentMap<String, VCloudXSession> cache) {
|
String provideVCloudToken(Supplier<VCloudXSession> cache) {
|
||||||
return cache.get("doesn't matter").getVCloudToken();
|
return cache.get().getVCloudToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Org
|
@Org
|
||||||
protected URI provideOrg(ConcurrentMap<String, VCloudXSession> cache) {
|
protected URI provideOrg(Supplier<VCloudXSession> cache) {
|
||||||
return cache.get("doesn't matter").getOrg();
|
return cache.get().getOrg();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* borrowing concurrency code to ensure that caching takes place properly
|
* borrowing concurrency code to ensure that caching takes place properly
|
||||||
*/
|
*/
|
||||||
@Provides
|
@Provides
|
||||||
ConcurrentMap<String, VCloudXSession> provideVCloudTokenCache(
|
@Singleton
|
||||||
|
Supplier<VCloudXSession> provideVCloudTokenCache(
|
||||||
@Named(PROPERTY_VCLOUDX_SESSIONINTERVAL) long seconds, final VCloudXLogin login) {
|
@Named(PROPERTY_VCLOUDX_SESSIONINTERVAL) long seconds, final VCloudXLogin login) {
|
||||||
return new MapMaker().expiration(seconds, TimeUnit.SECONDS).makeComputingMap(
|
return new ExpirableSupplier<VCloudXSession>(new Supplier<VCloudXSession>() {
|
||||||
new Function<String, VCloudXSession>() {
|
public VCloudXSession get() {
|
||||||
public VCloudXSession apply(String key) {
|
|
||||||
return login.login();
|
return login.login();
|
||||||
}
|
}
|
||||||
});
|
}, seconds, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|
|
@ -30,7 +30,6 @@ import static org.jclouds.vcloudx.reference.VCloudXConstants.PROPERTY_VCLOUDX_US
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRetryHandler;
|
import org.jclouds.http.HttpRetryHandler;
|
||||||
|
@ -44,6 +43,7 @@ import org.jclouds.vcloudx.VCloudXLogin;
|
||||||
import org.jclouds.vcloudx.VCloudXLogin.VCloudXSession;
|
import org.jclouds.vcloudx.VCloudXLogin.VCloudXSession;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
@ -91,12 +91,12 @@ public class RestVCloudXAuthenticationModuleTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
ConcurrentMap<String, VCloudXSession> map = module.provideVCloudTokenCache(1, login);
|
Supplier<VCloudXSession> map = module.provideVCloudTokenCache(1, login);
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
map.get("foo");
|
map.get();
|
||||||
assert "1".equals(map.get("foo").getVCloudToken());
|
assert "1".equals(map.get().getVCloudToken());
|
||||||
Thread.sleep(1001);
|
Thread.sleep(1001);
|
||||||
assert "2".equals(map.get("foo").getVCloudToken());
|
assert "2".equals(map.get().getVCloudToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue