[infinispan-commits] Infinispan SVN: r1322 - in trunk: cachestore and 9 other directories.
infinispan-commits at lists.jboss.org
infinispan-commits at lists.jboss.org
Wed Dec 23 19:01:57 EST 2009
Author: manik.surtani at jboss.com
Date: 2009-12-23 19:01:56 -0500 (Wed, 23 Dec 2009)
New Revision: 1322
Added:
trunk/cachestore/cloud/
trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/
trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStore.java
trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStoreConfig.java
trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudConnectionException.java
trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/package-info.java
trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/
trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/CloudCacheStoreFunctionalIntegrationTest.java
trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/CloudCacheStoreIntegrationTest.java
trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/CloudCacheStoreIntegrationVamTest.java
Removed:
trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/s3/
trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/s3/
trunk/cachestore/cloud/src/test/resources/log4j.xml
trunk/cachestore/s3/
Modified:
trunk/cachestore/cloud/pom.xml
trunk/cachestore/cloud/src/main/resources/jclouds.properties
trunk/core/src/main/resources/xslt/jbc3x2infinispan4x.xslt
trunk/pom.xml
trunk/tools/src/test/java/org/infinispan/test/fwk/TestNameVerifier.java
Log:
[ISPN-298] (CloudCacheStore to be written)
Copied: trunk/cachestore/cloud (from rev 1303, trunk/cachestore/s3)
Modified: trunk/cachestore/cloud/pom.xml
===================================================================
--- trunk/cachestore/s3/pom.xml 2009-12-16 15:02:14 UTC (rev 1303)
+++ trunk/cachestore/cloud/pom.xml 2009-12-24 00:01:56 UTC (rev 1322)
@@ -9,41 +9,80 @@
<version>4.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <artifactId>infinispan-cachestore-s3</artifactId>
- <name>Infinispan Amazon S3 CacheStore</name>
- <description>Infinispan Amazon S3 CacheStore module</description>
+ <artifactId>infinispan-cachestore-cloud</artifactId>
+ <name>Infinispan CloudCacheStore</name>
+ <description>Infinispan CloudCacheStore module</description>
<properties>
<jclouds.aws.accesskeyid></jclouds.aws.accesskeyid>
<jclouds.aws.secretaccesskey></jclouds.aws.secretaccesskey>
- <version.jclouds>1.0-beta-2</version.jclouds>
- <version.commons.io>1.4</version.commons.io>
+ <version.jclouds>1.0-SNAPSHOT</version.jclouds>
</properties>
<dependencies>
<dependency>
<groupId>org.jclouds</groupId>
- <artifactId>jclouds-s3</artifactId>
+ <artifactId>jclouds-blobstore</artifactId>
<version>${version.jclouds}</version>
</dependency>
-
<dependency>
<groupId>org.jclouds</groupId>
+ <artifactId>jclouds-joda</artifactId>
+ <version>${version.jclouds}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jclouds</groupId>
+ <artifactId>jclouds-bouncycastle</artifactId>
+ <version>${version.jclouds}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jclouds</groupId>
<artifactId>jclouds-httpnio</artifactId>
<version>${version.jclouds}</version>
</dependency>
-
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-log4j</artifactId>
<version>${version.jclouds}</version>
</dependency>
+
+ <!-- =========================================================== -->
+ <!-- optional cloud provider plug-ins. You'd need at least one! -->
+ <dependency>
+ <groupId>org.jclouds</groupId>
+ <artifactId>jclouds-aws</artifactId>
+ <version>${version.jclouds}</version>
+ <scope>optional</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jclouds</groupId>
+ <artifactId>jclouds-azure</artifactId>
+ <version>${version.jclouds}</version>
+ <scope>optional</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jclouds</groupId>
+ <artifactId>jclouds-rackspace</artifactId>
+ <version>${version.jclouds}</version>
+ <scope>optional</scope>
+ </dependency>
+ <!-- =========================================================== -->
</dependencies>
<repositories>
<repository>
<id>jclouds</id>
<url>http://jclouds.googlecode.com/svn/repo</url>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
</repository>
+ <repository>
+ <id>jclouds-snapshots</id>
+ <url>http://jclouds.rimuhosting.com/maven2/snapshots</url>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
</repositories>
<build>
<plugins>
@@ -56,17 +95,20 @@
<parallel>false</parallel>
<systemProperties>
<property>
- <name>jclouds.aws.accesskeyid</name>
- <value>${jclouds.aws.accesskeyid}</value>
+ <name>infinispan.jclouds.username</name>
+ <value>${infinispan.jclouds.username}</value>
</property>
<property>
- <name>jclouds.aws.secretaccesskey</name>
- <value>${jclouds.aws.secretaccesskey}</value>
+ <name>infinispan.jclouds.password</name>
+ <value>${infinispan.jclouds.password}</value>
</property>
+ <property>
+ <name>infinispan.jclouds.service</name>
+ <value>${infinispan.jclouds.service}</value>
+ </property>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
-
</project>
Added: trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStore.java
===================================================================
--- trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStore.java (rev 0)
+++ trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStore.java 2009-12-24 00:01:56 UTC (rev 1322)
@@ -0,0 +1,285 @@
+package org.infinispan.loaders.cloud;
+
+import org.infinispan.Cache;
+import org.infinispan.config.ConfigurationException;
+import org.infinispan.container.entries.InternalCacheEntry;
+import org.infinispan.loaders.CacheLoaderConfig;
+import org.infinispan.loaders.CacheLoaderException;
+import org.infinispan.loaders.bucket.Bucket;
+import org.infinispan.loaders.bucket.BucketBasedCacheStore;
+import org.infinispan.loaders.modifications.Modification;
+import org.infinispan.marshall.Marshaller;
+import org.infinispan.util.Util;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+import org.jclouds.blobstore.BlobMap;
+import org.jclouds.blobstore.BlobStore;
+import org.jclouds.blobstore.BlobStoreContext;
+import org.jclouds.blobstore.BlobStoreContextFactory;
+import org.jclouds.blobstore.domain.Blob;
+import org.jclouds.http.HttpUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+/**
+ * A JClouds-based implementation of a {@link org.infinispan.loaders.bucket.BucketBasedCacheStore}. This file store
+ * stores stuff in the following format: <tt>http://{cloud-storage-provider}/{bucket}/{bucket_number}.bucket</tt>
+ * <p/>
+ *
+ * @author Adrian Cole
+ * @author Manik Surtani
+ * @since 4.0
+ */
+public class CloudCacheStore extends BucketBasedCacheStore {
+
+ private static final Log log = LogFactory.getLog(CloudCacheStore.class);
+ private final ThreadLocal<Set<Future<?>>> asyncCommandFutures = new ThreadLocal<Set<Future<?>>>();
+ private CloudCacheStoreConfig config;
+ private String containerName;
+ private BlobStoreContext<?, ?> ctx;
+ // TODO use BlobStore and AsyncBlobStore instead - so that on transactional calls we can use the async store and poll futures for completion.
+ private BlobMap blobMap;
+ private boolean pollFutures;
+
+
+ public Class<? extends CacheLoaderConfig> getConfigurationClass() {
+ return CloudCacheStoreConfig.class;
+ }
+
+ @Override
+ public void init(CacheLoaderConfig cfg, Cache cache, Marshaller m) throws CacheLoaderException {
+ this.config = (CloudCacheStoreConfig) cfg;
+ init(cfg, cache, m, null, null);
+ }
+
+ @Override
+ public void stop() throws CacheLoaderException {
+ super.stop();
+ }
+
+ // this overloaded version of init() is primarily for unit testing/extension.
+
+ protected void init(CacheLoaderConfig config, Cache cache, Marshaller m, BlobStoreContext ctx, BlobMap blobMap) throws CacheLoaderException {
+ super.init(config, cache, m);
+ this.config = (CloudCacheStoreConfig) config;
+ this.cache = cache;
+ this.marshaller = m;
+ this.ctx = ctx;
+ this.blobMap = blobMap;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void start() throws CacheLoaderException {
+ super.start();
+ if (config.getCloudService() == null)
+ throw new ConfigurationException("CloudService must be set!");
+ if (config.getIdentity() == null)
+ throw new ConfigurationException("Identity must be set");
+ if (config.getPassword() == null)
+ throw new ConfigurationException("Password must be set");
+ if (config.getBucketPrefix() == null)
+ throw new ConfigurationException("CloudBucket must be set");
+ containerName = getThisContainerName();
+ ctx = createBlobStoreContext(config);
+ BlobStore bs = ctx.getBlobStore();
+ if (!bs.containerExists(containerName)) bs.createContainer(containerName);
+ blobMap = ctx.createBlobMap(containerName);
+ pollFutures = !config.getAsyncStoreConfig().isEnabled();
+ }
+
+ private BlobStoreContext<?, ?> createBlobStoreContext(CloudCacheStoreConfig config) throws CacheLoaderException {
+ Properties properties = new Properties();
+ InputStream is = Util.loadResourceAsStream("jclouds.properties");
+ if (is != null) try {
+ properties.load(is);
+ } catch (IOException e) {
+ log.error("Unable to load contents from jclouds.properties", e);
+ }
+ BlobStoreContextFactory factory = new BlobStoreContextFactory(properties);
+
+ // Need a URI in blobstore://account:key@service/container/path
+ // TODO find a better way to create this context! Unnecessary construction of a URI only for it to be broken up again into components from within JClouds
+ return factory.createContext(HttpUtils.createUri("blobstore://" + config.getIdentity() +
+ ":" + config.getPassword() +
+ "@" + config.getCloudService() + "/"));
+ }
+
+ private String getThisContainerName() {
+ return config.getBucketPrefix() + "-" + cache.getName().toLowerCase();
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Set<InternalCacheEntry> loadAllLockSafe() throws CacheLoaderException {
+ Set<InternalCacheEntry> result = new HashSet<InternalCacheEntry>();
+ for (Blob blob : blobMap.values()) {
+ Bucket bucket = readFromBlob(blob);
+ if (bucket.removeExpiredEntries()) updateBucket(bucket);
+ result.addAll(bucket.getStoredEntries());
+ }
+ return result;
+ }
+
+ protected void fromStreamLockSafe(ObjectInput objectInput) throws CacheLoaderException {
+ String source;
+ try {
+ source = (String) objectInput.readObject();
+ } catch (Exception e) {
+ throw convertToCacheLoaderException("Error while reading from stream", e);
+ }
+ if (getThisContainerName().equals(source)) {
+ log.info("Attempt to load the same cloud bucket ignored");
+ } else {
+ // TODO implement stream handling. What's the JClouds API to "copy" one bucket to another?
+ }
+ }
+
+ @Override
+ protected boolean supportsMultiThreadedPurge() {
+ return true;
+ }
+
+ protected void toStreamLockSafe(ObjectOutput objectOutput) throws CacheLoaderException {
+ try {
+ objectOutput.writeObject(getThisContainerName());
+ } catch (IOException e) {
+ throw convertToCacheLoaderException("Error while writing to stream", e);
+ }
+ }
+
+ protected void clearLockSafe() throws CacheLoaderException {
+ Set<Future<?>> futures = asyncCommandFutures.get();
+ if (futures == null) {
+ // is a sync call
+ blobMap.clear();
+ } else {
+ // is an async call - invoke clear() on the container asynchronously and store the future in the 'futures' collection
+ // TODO make this async! AsyncBlobStore ?
+ blobMap.clear();
+ }
+ }
+
+ CacheLoaderException convertToCacheLoaderException(String message, Exception caught) {
+ return (caught instanceof CacheLoaderException) ? (CacheLoaderException) caught :
+ new CacheLoaderException(message, caught);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void purgeInternal() throws CacheLoaderException {
+ // TODO can expiry data be stored in a blob's metadata? More efficient purging that way.
+
+ if (!config.isLazyPurgingOnly()) {
+ acquireGlobalLock(false);
+ try {
+ final BlobMap blobMap = ctx.createBlobMap(containerName);
+ if (multiThreadedPurge) {
+ purgerService.execute(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ for (Blob blob : blobMap.values()) {
+ Bucket bucket = readFromBlob(blob);
+ if (bucket.removeExpiredEntries()) updateBucket(bucket);
+ }
+ } catch (CacheLoaderException e) {
+ log.warn("Problems purging bucket", e);
+ }
+ }
+ });
+ } else {
+ for (Blob blob : blobMap.values()) {
+ Bucket bucket = readFromBlob(blob);
+ if (bucket.removeExpiredEntries()) updateBucket(bucket);
+ }
+ }
+ } finally {
+ releaseGlobalLock(false);
+ }
+ }
+ }
+
+ protected Bucket loadBucket(String hash) throws CacheLoaderException {
+ return readFromBlob(blobMap.get(hash));
+ }
+
+
+ protected void insertBucket(Bucket bucket) throws CacheLoaderException {
+ Blob blob = blobMap.newBlob();
+ writeToBlob(blob, bucket);
+
+ Set<Future<?>> futures = asyncCommandFutures.get();
+ if (futures == null) {
+ // is a sync call
+ blobMap.put(getBucketName(bucket), blob);
+ } else {
+ // is an async call - invoke clear() on the container asynchronously and store the future in the 'futures' collection
+ // TODO make this async! AsyncBlobStore ?
+ blobMap.put(getBucketName(bucket), blob);
+ }
+ }
+
+ @Override
+ protected void applyModifications(List<? extends Modification> mods) throws CacheLoaderException {
+ Set<Future<?>> futures = new HashSet<Future<?>>(mods.size());
+ asyncCommandFutures.set(futures);
+ try {
+ super.applyModifications(mods);
+ if (pollFutures) {
+ CacheLoaderException exception = null;
+ try {
+ for (Future<?> f : asyncCommandFutures.get()) f.get();
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ } catch (ExecutionException e) {
+ if (e.getCause() instanceof CacheLoaderException)
+ exception = (CacheLoaderException) e.getCause();
+ else
+ exception = new CacheLoaderException(e.getCause());
+ }
+ throw exception;
+ }
+ } finally {
+ asyncCommandFutures.remove();
+ }
+ }
+
+ protected void updateBucket(Bucket bucket) throws CacheLoaderException {
+ insertBucket(bucket);
+ }
+
+ private void writeToBlob(Blob blob, Bucket bucket) throws CacheLoaderException {
+ try {
+ blob.setPayload(marshaller.objectToByteBuffer(bucket));
+ } catch (IOException e) {
+ throw new CacheLoaderException(e);
+ }
+ }
+
+ private Bucket readFromBlob(Blob blob) throws CacheLoaderException {
+ if (blob == null) return null;
+ try {
+ return (Bucket) marshaller.objectFromInputStream(blob.getContent());
+ } catch (Exception e) {
+ throw new CacheLoaderException(e);
+ }
+ }
+
+ private String getBucketName(Bucket bucket) {
+ String bucketName = bucket.getBucketName();
+ if (bucketName.startsWith("-")) {
+ return bucket.getBucketName().replace("-", "A");
+ } else {
+ return bucket.getBucketName();
+ }
+ }
+}
Property changes on: trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStore.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStoreConfig.java
===================================================================
--- trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStoreConfig.java (rev 0)
+++ trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStoreConfig.java 2009-12-24 00:01:56 UTC (rev 1322)
@@ -0,0 +1,125 @@
+package org.infinispan.loaders.cloud;
+
+import org.infinispan.loaders.LockSupportCacheStoreConfig;
+
+/**
+ * Configures {@link CloudCacheStore}. This allows you to tune a number of characteristics of
+ * the {@link CloudCacheStore}.
+ * <p/>
+ * <ul>
+ * <li><tt>cloudService</tt> - the cloud service provider to be used. For supported values, see <a href="http://TODO">this page on JClouds' website</a> with supported provider strings. This is required and there is no default.</li>
+ * <li><tt>identity</tt> - identifies you as the party responsible for cloud requests. This is required and there
+ * is no default. This is dependent on your cloud provider backend. For example, with Amazon Web Services, this is your AWS_ACCESS_KEY.</li>
+ * <li><tt>password</tt> - used to authenticate you as the owner of <tt>identity</tt>. This
+ * is required and there is no default. For example, with Amazon Web Services, this is your AWS_SECRET_KEY.</li>
+ * <li><tt>bucket</tt> - the name of the cloud bucket used to store cache data.
+ * This is required and there is no default.</li> <li><tt>requestTimeout</tt> - The maximum amount of milliseconds a
+ * single request can take before throwing an exception. Default is 10000</li><li><tt>lazyPurgingOnly</tt> - Causes
+ * {@link org.infinispan.loaders.CacheStore#purgeExpired()} to be a no-op, and only removes expired entries lazily, on a
+ * {@link org.infinispan.loaders.CacheLoader#load(Object)}. Defaults to <tt>true</tt>.</li></ul>
+ *
+ * @author Adrian Cole
+ * @author Manik Surtani
+ * @since 4.0
+ */
+public class CloudCacheStoreConfig extends LockSupportCacheStoreConfig {
+ private String identity;
+ private String password;
+ private String bucketPrefix;
+ private String proxyHost;
+ private int proxyPort;
+ private long requestTimeout = 10000;
+ private Boolean lazyPurgingOnly = true;
+ private String cloudService;
+
+
+ public Boolean isLazyPurgingOnly() {
+ return lazyPurgingOnly;
+ }
+
+ public void setLazyPurgingOnly(Boolean lazyPurgingOnly) {
+ this.lazyPurgingOnly = lazyPurgingOnly;
+ }
+
+ public long getRequestTimeout() {
+ return requestTimeout;
+ }
+
+ public void setRequestTimeout(long requestTimeout) {
+ this.requestTimeout = requestTimeout;
+ }
+
+
+ public int getMaxConnections() {
+ return maxConnections;
+ }
+
+ public void setMaxConnections(int maxConnections) {
+ this.maxConnections = maxConnections;
+ }
+
+ private int maxConnections = 3;
+ private boolean secure = true;
+
+ public boolean isSecure() {
+ return secure;
+ }
+
+ public void setSecure(boolean secure) {
+ this.secure = secure;
+ }
+
+
+ public CloudCacheStoreConfig() {
+ setCacheLoaderClassName(CloudCacheStore.class.getName());
+ }
+
+ public String getIdentity() {
+ return identity;
+ }
+
+
+ public void setIdentity(String identity) {
+ this.identity = identity;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getBucketPrefix() {
+ return bucketPrefix;
+ }
+
+ public void setBucketPrefix(String bucketPrefix) {
+ this.bucketPrefix = bucketPrefix;
+ }
+
+ public String getProxyHost() {
+ return proxyHost;
+ }
+
+ public void setProxyHost(String proxyHost) {
+ this.proxyHost = proxyHost;
+ }
+
+ public int getProxyPort() {
+ return proxyPort;
+ }
+
+ public void setProxyPort(int proxyPort) {
+ this.proxyPort = proxyPort;
+ }
+
+ public String getCloudService() {
+ return cloudService;
+ }
+
+ public void setCloudService(String cloudService) {
+ this.cloudService = cloudService;
+ }
+}
\ No newline at end of file
Property changes on: trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStoreConfig.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudConnectionException.java
===================================================================
--- trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudConnectionException.java (rev 0)
+++ trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudConnectionException.java 2009-12-24 00:01:56 UTC (rev 1322)
@@ -0,0 +1,28 @@
+package org.infinispan.loaders.cloud;
+
+import org.infinispan.loaders.CacheLoaderException;
+
+/**
+ * An exception thrown by the {@link org.infinispan.loaders.cloud.CloudCacheStore} if there are problems connecting
+ * to the cloud storage provider.
+ *
+ * @author Adrian Cole
+ * @author Manik Surtani
+ * @since 4.0
+ */
+public class CloudConnectionException extends CacheLoaderException {
+ public CloudConnectionException() {
+ }
+
+ public CloudConnectionException(String message) {
+ super(message);
+ }
+
+ public CloudConnectionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public CloudConnectionException(Throwable cause) {
+ super(cause);
+ }
+}
\ No newline at end of file
Property changes on: trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudConnectionException.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/package-info.java
===================================================================
--- trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/package-info.java (rev 0)
+++ trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/package-info.java 2009-12-24 00:01:56 UTC (rev 1322)
@@ -0,0 +1,6 @@
+/**
+ * This package contains a {@link org.infinispan.loaders.CacheStore} implementation based on
+ * <a href="http://code.google.com/p/jclouds/">JClouds</a>, to persist to cloud storage
+ * providers.
+ */
+package org.infinispan.loaders.cloud;
\ No newline at end of file
Property changes on: trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/package-info.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/cachestore/cloud/src/main/resources/jclouds.properties
===================================================================
--- trunk/cachestore/s3/src/main/resources/jclouds.properties 2009-12-16 15:02:14 UTC (rev 1303)
+++ trunk/cachestore/cloud/src/main/resources/jclouds.properties 2009-12-24 00:01:56 UTC (rev 1322)
@@ -1,8 +1,16 @@
-jclouds.http.address=s3.amazonaws.com
-jclouds.http.port=443
-jclouds.http.secure=true
-jclouds.http.pool.max_connection_reuse=75
-jclouds.http.pool.max_session_failures=2
-jclouds.http.pool.request_invoker_threads=1
-jclouds.http.pool.io_worker_threads=2
-jclouds.pool.max_connections=12
+azureblob.contextbuilder=org.jclouds.azure.storage.blob.blobstore.AzureBlobStoreContextBuilder
+azureblob.propertiesbuilder=org.jclouds.azure.storage.blob.AzureBlobPropertiesBuilder
+cloudfiles.contextbuilder=org.jclouds.rackspace.cloudfiles.blobstore.CloudFilesBlobStoreContextBuilder
+cloudfiles.propertiesbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesPropertiesBuilder
+s3.contextbuilder=org.jclouds.aws.s3.blobstore.S3BlobStoreContextBuilder
+s3.propertiesbuilder=org.jclouds.aws.s3.S3PropertiesBuilder
+
+#
+#jclouds.http.address=s3.amazonaws.com
+#jclouds.http.port=443
+#jclouds.http.secure=true
+#jclouds.http.pool.max_connection_reuse=75
+#jclouds.http.pool.max_session_failures=2
+#jclouds.http.pool.request_invoker_threads=1
+#jclouds.http.pool.io_worker_threads=2
+#jclouds.pool.max_connections=12
Added: trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/CloudCacheStoreFunctionalIntegrationTest.java
===================================================================
--- trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/CloudCacheStoreFunctionalIntegrationTest.java (rev 0)
+++ trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/CloudCacheStoreFunctionalIntegrationTest.java 2009-12-24 00:01:56 UTC (rev 1322)
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.loaders.cloud;
+
+import org.infinispan.loaders.BaseCacheStoreFunctionalTest;
+import org.infinispan.loaders.CacheStoreConfig;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Optional;
+import org.testng.annotations.Parameters;
+import org.testng.annotations.Test;
+
+ at Test(groups = "unit", sequential = true, testName = "loaders.cloud.CloudCacheStoreFunctionalIntegrationTest")
+public class CloudCacheStoreFunctionalIntegrationTest extends BaseCacheStoreFunctionalTest {
+
+ private String proxyHost;
+ private int proxyPort = -1;
+ private int maxConnections = 20;
+ private boolean isSecure = false;
+ private String csBucket;
+ private String accessKey;
+ private String secretKey;
+ private String cs;
+
+ private static final String sysUsername = System.getProperty("infinispan.jclouds.username");
+ private static final String sysPassword = System.getProperty("infinispan.jclouds.password");
+ private static final String sysService = System.getProperty("infinispan.jclouds.service");
+
+ @BeforeTest
+ @Parameters({"infinispan.jclouds.username", "infinispan.jclouds.password", "infinispan.jclouds.service"})
+ protected void setUpClient(@Optional String JcloudsUsername,
+ @Optional String JcloudsPassword,
+ @Optional String JcloudsService) throws Exception {
+
+ accessKey = (JcloudsUsername == null) ? sysUsername : JcloudsUsername;
+ secretKey = (JcloudsPassword == null) ? sysPassword : JcloudsPassword;
+ cs = (JcloudsService == null) ? sysService : JcloudsService;
+
+ if (accessKey == null || accessKey.trim().equals("") || secretKey == null || secretKey.trim().equals("")) {
+ accessKey = "dummy";
+ secretKey = "dummy";
+ }
+ csBucket = (System.getProperty("user.name") + "." + this.getClass().getSimpleName()).toLowerCase();
+ System.out.printf("accessKey: %1$s, bucket: %2$s%n", accessKey, csBucket);
+ }
+
+
+ @Override
+ protected CacheStoreConfig createCacheStoreConfig() throws Exception {
+ CloudCacheStoreConfig cfg = new CloudCacheStoreConfig();
+ cfg.setCloudService(cs);
+ cfg.setBucketPrefix(csBucket);
+ cfg.setIdentity(accessKey);
+ cfg.setPassword(secretKey);
+ cfg.setProxyHost(proxyHost);
+ cfg.setProxyPort(proxyPort);
+ cfg.setSecure(isSecure);
+ cfg.setMaxConnections(maxConnections);
+ cfg.setPurgeSynchronously(true); // for more accurate unit testing
+ return cfg;
+ }
+}
Property changes on: trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/CloudCacheStoreFunctionalIntegrationTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/CloudCacheStoreIntegrationTest.java
===================================================================
--- trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/CloudCacheStoreIntegrationTest.java (rev 0)
+++ trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/CloudCacheStoreIntegrationTest.java 2009-12-24 00:01:56 UTC (rev 1322)
@@ -0,0 +1,217 @@
+package org.infinispan.loaders.cloud;
+
+import org.infinispan.CacheDelegate;
+import org.infinispan.container.entries.InternalCacheEntry;
+import org.infinispan.container.entries.InternalEntryFactory;
+import org.infinispan.io.UnclosableObjectInputStream;
+import org.infinispan.io.UnclosableObjectOutputStream;
+import org.infinispan.loaders.BaseCacheStoreTest;
+import org.infinispan.loaders.CacheLoaderException;
+import org.infinispan.loaders.CacheStore;
+import org.infinispan.marshall.Marshaller;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Optional;
+import org.testng.annotations.Parameters;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Adrian Cole
+ * @since 4.0
+ */
+ at Test(groups = "unit", sequential = true, testName = "loaders.cloud.CloudCacheStoreIntegrationTest")
+public class CloudCacheStoreIntegrationTest extends BaseCacheStoreTest {
+
+ private String proxyHost;
+ private int proxyPort = -1;
+ private int maxConnections = 20;
+ private boolean isSecure = false;
+ private String csBucket;
+ private String cs2Bucket;
+ private String accessKey;
+ private String secretKey;
+ private String service;
+
+ private static final String sysUsername = System.getProperty("infinispan.jclouds.username");
+ private static final String sysPassword = System.getProperty("infinispan.jclouds.password");
+ private static final String sysService = System.getProperty("infinispan.jclouds.service");
+
+ @BeforeTest
+ @Parameters({"infinispan.jclouds.username", "infinispan.jclouds.password", "infinispan.jclouds.service"})
+ protected void setUpClient(@Optional String JcloudsUsername,
+ @Optional String JcloudsPassword,
+ @Optional String JcloudsService) throws Exception {
+
+ accessKey = (JcloudsUsername == null) ? sysUsername : JcloudsUsername;
+ secretKey = (JcloudsPassword == null) ? sysPassword : JcloudsPassword;
+ service = (JcloudsService == null) ? sysService : JcloudsService;
+
+ if (accessKey == null || accessKey.trim().equals("") || secretKey == null || secretKey.trim().equals("")) {
+ accessKey = "dummy";
+ secretKey = "dummy";
+ }
+ csBucket = (System.getProperty("user.name")
+ + "." + this.getClass().getSimpleName()).toLowerCase();
+ System.out.printf("accessKey: %1$s, bucket: %2$s%n", accessKey, csBucket);
+
+ cs2Bucket = csBucket + "2";
+ }
+
+ protected CacheStore createCacheStore() throws Exception {
+ return createAndStartCacheStore(csBucket);
+ }
+
+ protected CacheStore createAnotherCacheStore() throws Exception {
+ return createAndStartCacheStore(cs2Bucket);
+ }
+
+ private CacheStore createAndStartCacheStore(String bucket) throws Exception {
+ CloudCacheStore cs = new CloudCacheStore();
+ CloudCacheStoreConfig cfg = new CloudCacheStoreConfig();
+ cfg.setBucketPrefix(bucket);
+ cfg.setCloudService(service);
+ cfg.setIdentity(accessKey);
+ cfg.setPassword(secretKey);
+ cfg.setProxyHost(proxyHost);
+ cfg.setProxyPort(proxyPort);
+ cfg.setSecure(isSecure);
+ cfg.setMaxConnections(maxConnections);
+ cfg.setPurgeSynchronously(true); // for more accurate unit testing
+ cs.init(cfg, new CacheDelegate("aName"), getMarshaller());
+ cs.start();
+ return cs;
+ }
+
+ /* Changes below are needed to support testing of multiple cache stores */
+
+ protected CacheStore cs2;
+
+ @BeforeMethod
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ cs.clear();
+ Set entries = cs.loadAll();
+ assert entries.size() == 0;
+ cs2 = createAnotherCacheStore();
+ cs2.clear();
+ entries = cs2.loadAll();
+ assert entries.size() == 0;
+ }
+
+
+ @AfterMethod
+ @Override
+ public void tearDown() throws CacheLoaderException {
+ if (cs != null) {
+ cs.clear();
+ cs.stop();
+
+ }
+ cs = null;
+ if (cs2 != null) {
+ cs2.clear();
+
+ cs2.stop();
+ }
+ cs2 = null;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void testStreamingAPI() throws IOException, ClassNotFoundException, CacheLoaderException {
+ cs.store(InternalEntryFactory.create("k1", "v1", -1, -1));
+ cs.store(InternalEntryFactory.create("k2", "v2", -1, -1));
+ cs.store(InternalEntryFactory.create("k3", "v3", -1, -1));
+
+ Marshaller marshaller = getMarshaller();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ObjectOutput oo = marshaller.startObjectOutput(out, false);
+ try {
+ cs.toStream(new UnclosableObjectOutputStream(oo));
+ } finally {
+ marshaller.finishObjectOutput(oo);
+ out.close();
+ }
+
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ ObjectInput oi = marshaller.startObjectInput(in, false);
+ try {
+ cs2.fromStream(new UnclosableObjectInputStream(oi));
+ } finally {
+ marshaller.finishObjectInput(oi);
+ in.close();
+ }
+
+ Set<InternalCacheEntry> set = cs2.loadAll();
+ assertEquals(set.size(), 3);
+ Set expected = new HashSet();
+ expected.add("k1");
+ expected.add("k2");
+ expected.add("k3");
+ for (InternalCacheEntry se : set) assert expected.remove(se.getKey());
+ assert expected.isEmpty();
+ }
+
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void testStreamingAPIReusingStreams() throws IOException, ClassNotFoundException, CacheLoaderException {
+ cs.store(InternalEntryFactory.create("k1", "v1", -1, -1));
+ cs.store(InternalEntryFactory.create("k2", "v2", -1, -1));
+ cs.store(InternalEntryFactory.create("k3", "v3", -1, -1));
+
+ Marshaller marshaller = getMarshaller();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ byte[] dummyStartBytes = {1, 2, 3, 4, 5, 6, 7, 8};
+ byte[] dummyEndBytes = {8, 7, 6, 5, 4, 3, 2, 1};
+ ObjectOutput oo = marshaller.startObjectOutput(out, false);
+ try {
+ oo.write(dummyStartBytes);
+ cs.toStream(new UnclosableObjectOutputStream(oo));
+ oo.flush();
+ oo.write(dummyEndBytes);
+ } finally {
+ marshaller.finishObjectOutput(oo);
+ out.close();
+ }
+
+ // first pop the start bytes
+ byte[] dummy = new byte[8];
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ ObjectInput oi = marshaller.startObjectInput(in, false);
+ try {
+ int bytesRead = oi.read(dummy, 0, 8);
+ assert bytesRead == 8;
+ for (int i = 1; i < 9; i++) assert dummy[i - 1] == i : "Start byte stream corrupted!";
+ cs2.fromStream(new UnclosableObjectInputStream(oi));
+ bytesRead = oi.read(dummy, 0, 8);
+ assert bytesRead == 8;
+ for (int i = 8; i > 0; i--) assert dummy[8 - i] == i : "Start byte stream corrupted!";
+ } finally {
+ marshaller.finishObjectInput(oi);
+ in.close();
+ }
+
+ Set<InternalCacheEntry> set = cs2.loadAll();
+ assertEquals(set.size(), 3);
+ Set expected = new HashSet();
+ expected.add("k1");
+ expected.add("k2");
+ expected.add("k3");
+ for (InternalCacheEntry se : set) assert expected.remove(se.getKey());
+ assert expected.isEmpty();
+ }
+}
\ No newline at end of file
Property changes on: trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/CloudCacheStoreIntegrationTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/CloudCacheStoreIntegrationVamTest.java
===================================================================
--- trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/CloudCacheStoreIntegrationVamTest.java (rev 0)
+++ trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/CloudCacheStoreIntegrationVamTest.java 2009-12-24 00:01:56 UTC (rev 1322)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.loaders.cloud;
+
+import org.infinispan.commands.RemoteCommandsFactory;
+import org.infinispan.marshall.Marshaller;
+import org.infinispan.marshall.VersionAwareMarshaller;
+import org.testng.annotations.Test;
+
+/**
+ * CloudCacheStoreIntegrationTest using production level marshaller.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Test(groups = "unit", sequential = true, testName = "loaders.cloud.CloudCacheStoreIntegrationVamTest")
+public class CloudCacheStoreIntegrationVamTest extends CloudCacheStoreIntegrationTest {
+ @Override
+ protected Marshaller getMarshaller() {
+ VersionAwareMarshaller marshaller = new VersionAwareMarshaller();
+ marshaller.inject(Thread.currentThread().getContextClassLoader(), new RemoteCommandsFactory());
+ marshaller.start();
+ return marshaller;
+ }
+}
Property changes on: trunk/cachestore/cloud/src/test/java/org/infinispan/loaders/cloud/CloudCacheStoreIntegrationVamTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Deleted: trunk/cachestore/cloud/src/test/resources/log4j.xml
===================================================================
--- trunk/cachestore/s3/src/test/resources/log4j.xml 2009-12-16 15:02:14 UTC (rev 1303)
+++ trunk/cachestore/cloud/src/test/resources/log4j.xml 2009-12-24 00:01:56 UTC (rev 1322)
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
-
-<!--
- For more configuration infromation and examples see the Apache Log4j website: http://logging.apache.org/log4j/
- -->
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
-
- <!-- A time/date based rolling appender -->
- <appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
- <param name="File" value="s3_cache_store.log"/>
- <param name="Append" value="false"/>
-
- <!-- Rollover at midnight each day -->
- <param name="DatePattern" value="'.'yyyy-MM-dd"/>
-
- <!-- Rollover at the top of each hour
- <param name="DatePattern" value="'.'yyyy-MM-dd-HH"/>
- -->
- <param name="Threshold" value="TRACE"/>
-
- <layout class="org.apache.log4j.PatternLayout">
- <!-- The default pattern: Date Priority [Category] Message\n -->
- <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
-
- <!-- The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
- <param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
- -->
- </layout>
- </appender>
-
- <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
- <param name="Threshold" value="TRACE"/>
- <param name="Target" value="System.out"/>
-
- <layout class="org.apache.log4j.PatternLayout">
- <!-- The default pattern: Date Priority [Category] Message\n -->
- <param name="ConversionPattern" value="%d %-5p [%c{1}] (%t) %m%n"/>
- </layout>
- </appender>
-
-
- <!-- ================ -->
- <!-- Limit categories -->
- <!-- ================ -->
-
- <category name="org.jclouds">
- <priority value="INFO"/>
- </category>
-
- <category name="org.infinispan">
- <priority value="INFO"/>
- </category>
-
- <category name="org.infinispan.profiling">
- <priority value="WARN"/>
- </category>
-
- <category name="org.infinispan.jmx">
- <priority value="WARN"/>
- </category>
-
- <category name="org.infinispan.factories">
- <priority value="WARN"/>
- </category>
-
- <!-- ======================= -->
- <!-- Setup the Root category -->
- <!-- ======================= -->
-
- <root>
- <priority value="WARN"/>
- <!--<appender-ref ref="CONSOLE"/>-->
- <appender-ref ref="FILE"/>
- </root>
-
-</log4j:configuration>
Modified: trunk/core/src/main/resources/xslt/jbc3x2infinispan4x.xslt
===================================================================
--- trunk/core/src/main/resources/xslt/jbc3x2infinispan4x.xslt 2009-12-23 23:52:03 UTC (rev 1321)
+++ trunk/core/src/main/resources/xslt/jbc3x2infinispan4x.xslt 2009-12-24 00:01:56 UTC (rev 1322)
@@ -301,7 +301,7 @@
<xsl:otherwise>
<xsl:choose>
<xsl:when test="@class='org.jboss.cache.loader.s3.S3CacheLoader'">
- <xsl:text>org.infinispan.loaders.s3.S3CacheStore</xsl:text>
+ <xsl:text>org.infinispan.loaders.cloud.CloudCacheStore</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="no">WARNING! Cannot convert classloader's class, please do it manually!</xsl:message>
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2009-12-23 23:52:03 UTC (rev 1321)
+++ trunk/pom.xml 2009-12-24 00:01:56 UTC (rev 1322)
@@ -26,7 +26,7 @@
<module>lucene-directory</module>
<module>cachestore</module>
<module>cachestore/bdbje</module>
- <module>cachestore/s3</module>
+ <module>cachestore/cloud</module>
<module>cachestore/jdbc</module>
<module>cachestore/jdbm</module>
<module>server/rest</module>
Modified: trunk/tools/src/test/java/org/infinispan/test/fwk/TestNameVerifier.java
===================================================================
--- trunk/tools/src/test/java/org/infinispan/test/fwk/TestNameVerifier.java 2009-12-23 23:52:03 UTC (rev 1321)
+++ trunk/tools/src/test/java/org/infinispan/test/fwk/TestNameVerifier.java 2009-12-24 00:01:56 UTC (rev 1322)
@@ -207,7 +207,7 @@
// method that populates the list of module names
private void populateModuleList() {
modules.add("core");
- modules.add("cachestore/s3");
+ modules.add("cachestore/cloud");
modules.add("cachestore/bdbje");
modules.add("cachestore/jdbc");
modules.add("cachestore/jdbm");
More information about the infinispan-commits
mailing list