[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