servicemix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ioca...@apache.org
Subject svn commit: r1146175 - in /servicemix/utils/trunk: ./ src/main/java/org/apache/servicemix/store/ehcache/ src/test/java/org/apache/servicemix/store/ehcache/
Date Wed, 13 Jul 2011 18:06:52 GMT
Author: iocanel
Date: Wed Jul 13 18:06:51 2011
New Revision: 1146175

URL: http://svn.apache.org/viewvc?rev=1146175&view=rev
Log:
[SM-2109] Added EhCache store. Added StoreListener support to EhCache store. Added unit test
for EhCache store.

Added:
    servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/
    servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/CacheManagerFactory.java
    servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/EhCacheStore.java
    servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/EhCacheStoreFactory.java
    servicemix/utils/trunk/src/test/java/org/apache/servicemix/store/ehcache/
    servicemix/utils/trunk/src/test/java/org/apache/servicemix/store/ehcache/EhCacheStoreTest.java
Modified:
    servicemix/utils/trunk/pom.xml

Modified: servicemix/utils/trunk/pom.xml
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/pom.xml?rev=1146175&r1=1146174&r2=1146175&view=diff
==============================================================================
--- servicemix/utils/trunk/pom.xml (original)
+++ servicemix/utils/trunk/pom.xml Wed Jul 13 18:06:51 2011
@@ -155,7 +155,11 @@
             <artifactId>rjc</artifactId>
             <version>0.6.4</version>
         </dependency>
-
+        <dependency>
+            <groupId>net.sf.ehcache</groupId>
+            <artifactId>ehcache</artifactId>
+            <version>1.5.0</version>
+        </dependency>
         <!-- test dependencies -->
         <dependency>
             <groupId>junit</groupId>

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/CacheManagerFactory.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/CacheManagerFactory.java?rev=1146175&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/CacheManagerFactory.java
(added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/CacheManagerFactory.java
Wed Jul 13 18:06:51 2011
@@ -0,0 +1,130 @@
+/*
+ * 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.apache.servicemix.store.ehcache;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.config.CacheConfiguration;
+import net.sf.ehcache.config.Configuration;
+import net.sf.ehcache.config.DiskStoreConfiguration;
+
+/**
+ * @author: iocanel
+ */
+public class CacheManagerFactory {
+
+    private Boolean diskPersistent = Boolean.TRUE;
+    private Boolean eternal = Boolean.FALSE;
+    private int maxElementsInMemory=10000;
+    private Boolean overflowToDisk= Boolean.TRUE;
+    private long timeToIdleSeconds=300;
+    private long timeToLiveSeconds=300;
+    private String memoryStoreEvictionPolicy="LRU";
+
+    private String diskStorePath=".";
+
+
+    /**
+     * Builds the default {@ling CacheManager} instace
+     * @return
+     */
+    public CacheManager build() {
+        Configuration configuration = new Configuration();
+        CacheConfiguration defaultCacheConfiguration = new CacheConfiguration();
+        defaultCacheConfiguration.setMaxElementsInMemory(maxElementsInMemory);
+        defaultCacheConfiguration.setEternal(eternal);
+        defaultCacheConfiguration.setTimeToIdleSeconds(timeToIdleSeconds);
+        defaultCacheConfiguration.setTimeToLiveSeconds(timeToLiveSeconds);
+        defaultCacheConfiguration.setOverflowToDisk(overflowToDisk);
+        defaultCacheConfiguration.setDiskPersistent(diskPersistent);
+        defaultCacheConfiguration.setMemoryStoreEvictionPolicy(memoryStoreEvictionPolicy);
+
+        DiskStoreConfiguration diskStoreConfiguration = new DiskStoreConfiguration();
+        diskStoreConfiguration.setPath(diskStorePath);
+        configuration.addDiskStore(diskStoreConfiguration);
+
+        configuration.addDefaultCache(defaultCacheConfiguration);
+
+
+        CacheManager cacheManager = new CacheManager(configuration);
+        return cacheManager;
+    }
+
+    public String getDiskStorePath() {
+        return diskStorePath;
+    }
+
+    public void setDiskStorePath(String diskStorePath) {
+        this.diskStorePath = diskStorePath;
+    }
+
+    public Boolean getDiskPersistent() {
+        return diskPersistent;
+    }
+
+    public void setDiskPersistent(Boolean diskPersistent) {
+        this.diskPersistent = diskPersistent;
+    }
+
+    public Boolean getEternal() {
+        return eternal;
+    }
+
+    public void setEternal(Boolean eternal) {
+        this.eternal = eternal;
+    }
+
+    public int getMaxElementsInMemory() {
+        return maxElementsInMemory;
+    }
+
+    public void setMaxElementsInMemory(int maxElementsInMemory) {
+        this.maxElementsInMemory = maxElementsInMemory;
+    }
+
+    public Boolean getOverflowToDisk() {
+        return overflowToDisk;
+    }
+
+    public void setOverflowToDisk(Boolean overflowToDisk) {
+        this.overflowToDisk = overflowToDisk;
+    }
+
+    public long getTimeToIdleSeconds() {
+        return timeToIdleSeconds;
+    }
+
+    public void setTimeToIdleSeconds(long timeToIdleSeconds) {
+        this.timeToIdleSeconds = timeToIdleSeconds;
+    }
+
+    public long getTimeToLiveSeconds() {
+        return timeToLiveSeconds;
+    }
+
+    public void setTimeToLiveSeconds(long timeToLiveSeconds) {
+        this.timeToLiveSeconds = timeToLiveSeconds;
+    }
+
+    public String getMemoryStoreEvictionPolicy() {
+        return memoryStoreEvictionPolicy;
+    }
+
+    public void setMemoryStoreEvictionPolicy(String memoryStoreEvictionPolicy) {
+        this.memoryStoreEvictionPolicy = memoryStoreEvictionPolicy;
+    }
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/EhCacheStore.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/EhCacheStore.java?rev=1146175&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/EhCacheStore.java
(added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/EhCacheStore.java
Wed Jul 13 18:06:51 2011
@@ -0,0 +1,277 @@
+/*
+ * 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.apache.servicemix.store.ehcache;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheException;
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Element;
+import net.sf.ehcache.event.CacheEventListener;
+import org.apache.servicemix.id.IdGenerator;
+import org.apache.servicemix.store.Store;
+import org.apache.servicemix.store.base.BaseStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+/**
+ * EhCache Store.
+ * <p>Note: The current implementation always "removes" expired items.</p>
+ * @author n.dimos
+ */
+public class EhCacheStore extends BaseStore implements CacheEventListener {
+
+    private static final Logger LOG = LoggerFactory.getLogger(EhCacheStore.class);
+
+    private String name;
+    private Cache cache;
+    private IdGenerator idGenerator;
+
+    public EhCacheStore(Cache cache, IdGenerator idGenerator, String name) {
+        super();
+        this.cache=cache;
+        this.idGenerator=idGenerator;
+        this.name = name;
+        cache.getCacheEventNotificationService().registerListener(this);
+    }
+
+    /**
+     * <p>
+     * Returns true if feature is provided by the store (clustered), false else.
+     * </p>
+     *
+     * @param feature the feature.
+     * @return true if the given feature is provided by the store, false else.
+     */
+    public boolean hasFeature(String feature) {
+        if(Store.PERSISTENT.equals(feature)) return cache.getCacheConfiguration().isDiskPersistent();
+        else return false;
+    }
+
+
+    public synchronized void destroy() throws Exception {
+           cache.flush();
+    }
+
+    /**
+     * <p>
+     * Put an object in the store under the given id. This method must be used
+     * with caution and the behavior is unspecified if an object already exist
+     * for the same id.
+     * </p>
+     *
+     * @param id   the id of the object to store
+     * @param data the object to store
+     * @throws IOException if an error occurs
+     */
+    public void store(String id, Object data) throws IOException {
+        LOG.debug("Storing object with id: " + id);
+        try {
+            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+            ObjectOutputStream out = new ObjectOutputStream(buffer);
+            out.writeObject(data);
+            out.close();
+
+            Element element = new Element(id, buffer.toByteArray());
+            cache.put(element);
+        } catch (Exception e) {
+            throw new IOException(e);
+        }
+
+    }
+
+    /**
+     * <p>
+     * Put an object into the store and return the unique id that may be used at
+     * a later time to retrieve the object.
+     * </p>
+     *
+     * @param data the object to store
+     * @return the id of the object stored
+     * @throws IOException if an error occurs
+     */
+    public String store(Object data) throws IOException {
+        String id = idGenerator.generateId();
+        store(id, data);
+        return id;
+    }
+
+    /**
+     * <p>
+     * Loads an object that has been previously stored under the specified key.
+     * The object is removed from the store.
+     * </p>
+     *
+     * @param id the id of the object
+     * @return the object, or <code>null></code> if the object could not be
found
+     * @throws IOException if an error occurs
+     */
+    public Object load(String id) throws IOException {
+        LOG.debug("Loading object with id: " + id);
+        try {
+            Object result = null;
+            Element element = cache.get(id);
+            if (element != null) {
+                byte[] data = (byte[]) (element.getValue());
+                result = readObject(data);
+                cache.remove(id);
+            }
+            return result;
+        } catch (Exception e) {
+            throw new IOException(e);
+        }
+    }
+
+    /**
+     * <p>
+     * Loads an object that has been previously stored under the specified key.
+     * The object is not removed from the store.
+     * </p>
+     *
+     * @param id the id of the object
+     * @return the object, or <code>null</code> if the object could not be found
+     * @throws IOException if an error occurs
+     */
+    public Object peek(String id) throws IOException {
+        LOG.debug("Peeking object with id: " + id);
+        try {
+            Object result = null;
+            Element element = cache.get(id);
+            if (element != null) {
+                byte[] data = (byte[]) (element.getValue());
+                result = readObject(data);
+            }
+            return result;
+        } catch (Exception e) {
+            throw new IOException(e);
+        }
+    }
+
+    private Object readObject(byte[] data) throws IOException, ClassNotFoundException {
+        Object result = null;
+        if (data != null) {
+            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data));
+            try {
+                result = ois.readObject();
+            } finally {
+                ois.close();
+            }
+        }
+        return result;
+    }
+
+
+    public void notifyElementPut(Ehcache cache, Element element) throws CacheException {
+        String id = (String) element.getKey();
+        byte[] data = (byte[]) element.getObjectValue();
+        try {
+            fireAddedEvent(id, readObject(data));
+        } catch (IOException e) {
+            throw new CacheException(e);
+        } catch (ClassNotFoundException e) {
+            throw new CacheException(e);
+        }
+    }
+
+    public void notifyElementUpdated(Ehcache cache, Element element) throws CacheException
{
+        notifyElementPut(cache,element);
+    }
+
+    public void notifyElementExpired(Ehcache cache, Element element) {
+
+        String id = (String) element.getKey();
+        byte[] bytes = (byte[]) element.getObjectValue();
+        Object data = null;
+        try {
+            data = readObject(bytes);
+            fireEvictedEvent(id, readObject(bytes));
+        } catch (IOException e) {
+            LOG.error("Error reading expired element",e);
+        } catch (ClassNotFoundException e) {
+           LOG.error("Error reading expired element",e);
+        }
+        cache.removeQuiet(id);
+    }
+
+    public void notifyElementEvicted(Ehcache cache, Element element) {
+            String id = (String) element.getKey();
+            byte[] data = (byte[]) element.getObjectValue();
+            try {
+                fireEvictedEvent(id, readObject(data));
+            } catch (IOException e) {
+                throw new CacheException(e);
+            } catch (ClassNotFoundException e) {
+                throw new CacheException(e);
+            }
+    }
+
+    public void notifyRemoveAll(Ehcache cache) {
+    }
+
+    public void dispose() {
+
+    }
+
+   public Object clone() throws CloneNotSupportedException {
+       throw new CloneNotSupportedException();
+   }
+
+    public void notifyElementRemoved(Ehcache cache, Element element) throws CacheException
{
+        String id = (String) element.getKey();
+        byte[] data = (byte[]) element.getObjectValue();
+        try {
+            //I am doing this to work around an issue in EhCache quiet removal.
+            //This cause problems since elements are always removed on expiration.
+            if (data != null) {
+                fireRemovedEvent(id, readObject(data));
+            }
+        } catch (IOException e) {
+           throw new CacheException(e);
+        } catch (ClassNotFoundException e) {
+            throw new CacheException(e);
+        }
+    }
+
+    public Cache getCache() {
+        return cache;
+    }
+
+    public void setCache(Cache cache) {
+        this.cache = cache;
+    }
+
+    public IdGenerator getIdGenerator() {
+        return idGenerator;
+    }
+
+    public void setIdGenerator(IdGenerator idGenerator) {
+        this.idGenerator = idGenerator;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/EhCacheStoreFactory.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/EhCacheStoreFactory.java?rev=1146175&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/EhCacheStoreFactory.java
(added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/ehcache/EhCacheStoreFactory.java
Wed Jul 13 18:06:51 2011
@@ -0,0 +1,93 @@
+/*
+ * 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.apache.servicemix.store.ehcache;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Status;
+import net.sf.ehcache.config.CacheConfiguration;
+import net.sf.ehcache.config.Configuration;
+import net.sf.ehcache.config.DiskStoreConfiguration;
+import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.id.IdGenerator;
+import org.apache.servicemix.store.Store;
+import org.apache.servicemix.store.StoreFactory;
+
+/**
+ * @author n.dimos
+ */
+public class EhCacheStoreFactory implements StoreFactory {
+
+    private static final Log LOG = LogFactory.getLog(EhCacheStoreFactory.class);
+
+    protected IdGenerator idGenerator = new IdGenerator();
+    private Map<String, EhCacheStore> stores = new HashMap<String, EhCacheStore>();
+
+    private CacheManagerFactory cacheManagerFactory = new CacheManagerFactory();
+    private CacheManager cacheManager = cacheManagerFactory.build();
+
+    public EhCacheStoreFactory() {
+
+    }
+
+    public synchronized Store open(String name) throws IOException {
+        EhCacheStore store = stores.get(name);
+        if (store == null) {
+            Cache cache = cacheManager.getCache(name);
+            if(cache == null) {
+                cacheManager.addCache(name);
+                cache = cacheManager.getCache(name);
+            }
+            store = new EhCacheStore(cache,idGenerator, name);
+            stores.put(name, store);
+        }
+        return store;
+    }
+
+    public synchronized void close(Store store) throws IOException {
+        EhCacheStore ehCacheStore = (EhCacheStore) store;
+        try {
+            ehCacheStore.destroy();
+        } catch (Exception e) {
+            throw new IOException(e);
+        }
+        stores.remove(ehCacheStore.getName());
+    }
+
+    public IdGenerator getIdGenerator() {
+        return idGenerator;
+    }
+
+    public void setIdGenerator(IdGenerator idGenerator) {
+        this.idGenerator = idGenerator;
+    }
+
+    public CacheManager getCacheManager() {
+        return cacheManager;
+    }
+
+    public void setCacheManager(CacheManager cacheManager) {
+        this.cacheManager = cacheManager;
+    }
+}

Added: servicemix/utils/trunk/src/test/java/org/apache/servicemix/store/ehcache/EhCacheStoreTest.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/test/java/org/apache/servicemix/store/ehcache/EhCacheStoreTest.java?rev=1146175&view=auto
==============================================================================
--- servicemix/utils/trunk/src/test/java/org/apache/servicemix/store/ehcache/EhCacheStoreTest.java
(added)
+++ servicemix/utils/trunk/src/test/java/org/apache/servicemix/store/ehcache/EhCacheStoreTest.java
Wed Jul 13 18:06:51 2011
@@ -0,0 +1,101 @@
+/*
+ * 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.apache.servicemix.store.ehcache;
+
+import junit.framework.TestCase;
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import org.apache.servicemix.id.IdGenerator;
+import org.apache.servicemix.store.StoreListener;
+import org.easymock.EasyMock;
+
+import static org.easymock.EasyMock.*;
+
+/**
+ * @author: iocanel
+ */
+public class EhCacheStoreTest extends TestCase {
+
+    private static final String TEST_CACHE_NAME = "TEST_CACHE_NAME";
+    IdGenerator idGenerator = new IdGenerator();
+    CacheManagerFactory cacheManagerFactory;
+    CacheManager cacheManager;
+
+    Cache cache = null;
+
+    private StoreListener listener = createMock(StoreListener.class);
+
+    public EhCacheStoreTest() {
+        cacheManagerFactory = new CacheManagerFactory();
+        cacheManagerFactory.setDiskStorePath("target");
+        cacheManager = cacheManagerFactory.build();
+        cacheManager.addCache(TEST_CACHE_NAME);
+        cache = cacheManager.getCache(TEST_CACHE_NAME);
+    }
+
+    public void testStore() throws Exception {
+        EhCacheStore store = new EhCacheStore(cache,idGenerator,"testStore");
+        String id = "1";
+        String data = "Test data ....";
+        store.store(id,data);
+        assertEquals(data,store.peek(id));
+        assertEquals(data,store.load(id));
+        assertEquals(null,store.load(id));
+    }
+
+    public void testEviction() throws Exception {
+        cacheManagerFactory.setTimeToIdleSeconds(2);
+        cacheManagerFactory.setTimeToLiveSeconds(2);
+        cacheManager = cacheManagerFactory.build();
+        cacheManager.addCache(TEST_CACHE_NAME);
+        cache = cacheManager.getCache(TEST_CACHE_NAME);
+
+        EhCacheStore store = new EhCacheStore(cache,idGenerator,"testStore");
+        String id = "1";
+        String data = "Test data ....";
+        store.store(id,data);
+        assertEquals(data,store.peek(id));
+        Thread.sleep(3000);
+        assertEquals(null,store.peek(id));
+    }
+
+    public void testStoreListeners() throws Exception {
+        cacheManagerFactory.setTimeToIdleSeconds(2);
+        cacheManagerFactory.setTimeToLiveSeconds(2);
+        cacheManager = cacheManagerFactory.build();
+        cacheManager.addCache(TEST_CACHE_NAME);
+        cache = cacheManager.getCache(TEST_CACHE_NAME);
+
+        EhCacheStore store = new EhCacheStore(cache,idGenerator,"testStore");
+        store.addListener(listener);
+        String id = "1";
+        String data = "Test data ....";
+
+         //Record behavior
+        listener.onAdd(id,data);
+        expectLastCall().times(1);
+        listener.onEvict(id, data);
+        expectLastCall().once();
+        replay(listener);
+
+        store.store(id,data);
+        assertEquals(data,store.peek(id));
+        Thread.sleep(3000);
+        assertEquals(null,store.peek(id));
+        verify(listener);
+    }
+}



Mime
View raw message