Author: iocanel
Date: Sun Jan 30 14:27:47 2011
New Revision: 1065292
URL: http://svn.apache.org/viewvc?rev=1065292&view=rev
Log:
[SM-2047] Added Hazelcast memory store, which is a clustered in memory store.
Added:
servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/hazelcast/
servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/hazelcast/HazelcastStore.java
servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/hazelcast/HazelcastStoreFactory.java
servicemix/utils/trunk/src/test/java/org/apache/servicemix/store/hazelcast/
servicemix/utils/trunk/src/test/java/org/apache/servicemix/store/hazelcast/HazelcastStoreTest.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=1065292&r1=1065291&r2=1065292&view=diff
==============================================================================
--- servicemix/utils/trunk/pom.xml (original)
+++ servicemix/utils/trunk/pom.xml Sun Jan 30 14:27:47 2011
@@ -150,6 +150,11 @@
<artifactId>mongo-java-driver</artifactId>
<version>2.3</version>
</dependency>
+ <dependency>
+ <groupId>com.hazelcast</groupId>
+ <artifactId>hazelcast</artifactId>
+ <version>1.9.1</version>
+ </dependency>
<!-- test dependencies -->
<dependency>
<groupId>junit</groupId>
Added:
servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/hazelcast/HazelcastStore.java
URL:
http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/hazelcast/HazelcastStore.java?rev=1065292&view=auto
==============================================================================
---
servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/hazelcast/HazelcastStore.java
(added)
+++
servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/hazelcast/HazelcastStore.java
Sun Jan 30 14:27:47 2011
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2011 iocanel.
+ *
+ * Licensed 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.
+ * under the License.
+ */
+
+package org.apache.servicemix.store.hazelcast;
+
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.core.IdGenerator;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.store.Entry;
+import org.apache.servicemix.store.Store;
+
+/**
+ *
+ * @author iocanel
+ */
+public class HazelcastStore implements Store, Serializable {
+
+ private static final Log LOG = LogFactory.getLog(HazelcastStore.class);
+
+ private Map<String, Entry> datas;
+
+ private IdGenerator idGenerator;
+ private final long timeout;
+
+ /**
+ * Constructor
+ * @param idGenerator
+ * @param name
+ */
+ public HazelcastStore(IdGenerator idGenerator,String name) {
+ this.idGenerator = idGenerator;
+ this.datas = Hazelcast.getMap(name);
+ this.timeout=-1;
+ }
+
+ /**
+ * Constructor
+ * @param idGenerator
+ * @param name
+ * @param timemout
+ */
+ public HazelcastStore(IdGenerator idGenerator,String name, long timemout) {
+ this.idGenerator = idGenerator;
+ this.datas = Hazelcast.getMap(name);
+ this.timeout=timemout;
+ }
+
+
+ /**
+ * <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 (CLUSTERED.equals(feature))
+ return true;
+ return false;
+ }
+
+
+ /**
+ * <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);
+ datas.put(id, new Entry(data));
+ }
+
+ /**
+ * <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 = String.valueOf(idGenerator.newId());
+ 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/Removing object with id: " + id);
+ if(timeout > 0) {
+ evict();
+ }
+ Entry entry = datas.remove(id);
+ return entry != null ? entry.getData() : null;
+ }
+
+ /**
+ * <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);
+ Entry entry = datas.get(id);
+ return entry != null ? entry.getData() : null;
+ }
+
+ private void evict() {
+ long now = System.currentTimeMillis();
+ for (String key : datas.keySet()) {
+ long age = now - datas.get(key).getTime();
+ if (age > timeout) {
+ LOG.debug("Removing object with id " + key + " from store
after " + age + " ms");
+ datas.remove(key);
+ }
+ }
+ }
+}
\ No newline at end of file
Added:
servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/hazelcast/HazelcastStoreFactory.java
URL:
http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/hazelcast/HazelcastStoreFactory.java?rev=1065292&view=auto
==============================================================================
---
servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/hazelcast/HazelcastStoreFactory.java
(added)
+++
servicemix/utils/trunk/src/main/java/org/apache/servicemix/store/hazelcast/HazelcastStoreFactory.java
Sun Jan 30 14:27:47 2011
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2011 iocanel.
+ *
+ * Licensed 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.
+ * under the License.
+ */
+
+package org.apache.servicemix.store.hazelcast;
+
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.core.IdGenerator;
+import java.io.IOException;
+import java.util.Map;
+import org.apache.servicemix.store.Store;
+
+
+/**
+ *
+ * @author iocanel
+ */
+public class HazelcastStoreFactory {
+
+ private Map<String, HazelcastStore> stores =
Hazelcast.getMap(STORE_PREFIX);
+ private long timeout = -1;
+
+ public static final String STORE_PREFIX="org.apache.servicemix.stores";
+
+ public synchronized Store open(String name) throws IOException {
+ HazelcastStore store = stores.get(name);
+ String storeName = STORE_PREFIX+"."+name;
+ if (store == null) {
+ if (timeout <= 0) {
+ store = new
HazelcastStore(Hazelcast.getIdGenerator(storeName),storeName);
+ } else {
+ store = new
HazelcastStore(Hazelcast.getIdGenerator(storeName), storeName, timeout);
+ }
+ stores.put(name, store);
+ }
+ return store;
+ }
+
+ /* (non-Javadoc)
+ * @see
org.apache.servicemix.store.ExchangeStoreFactory#release(org.apache.servicemix.store.ExchangeStore)
+ */
+ public synchronized void close(Store store) throws IOException {
+ stores.remove(store);
+ }
+
+ public void setTimeout(long timeout) {
+ this.timeout = timeout;
+ }
+
+
+}
Added:
servicemix/utils/trunk/src/test/java/org/apache/servicemix/store/hazelcast/HazelcastStoreTest.java
URL:
http://svn.apache.org/viewvc/servicemix/utils/trunk/src/test/java/org/apache/servicemix/store/hazelcast/HazelcastStoreTest.java?rev=1065292&view=auto
==============================================================================
---
servicemix/utils/trunk/src/test/java/org/apache/servicemix/store/hazelcast/HazelcastStoreTest.java
(added)
+++
servicemix/utils/trunk/src/test/java/org/apache/servicemix/store/hazelcast/HazelcastStoreTest.java
Sun Jan 30 14:27:47 2011
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2011 iocanel.
+ *
+ * Licensed 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.
+ * under the License.
+ */
+
+package org.apache.servicemix.store.hazelcast;
+
+import org.apache.servicemix.store.Entry;
+import java.util.Map;
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.core.HazelcastInstance;
+import junit.framework.TestCase;
+import org.apache.servicemix.store.Store;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author iocanel
+ */
+public class HazelcastStoreTest extends TestCase {
+
+ private static final long TIMEOUT = 250L;
+
+ private Store store;
+ private final HazelcastStoreFactory factory = new HazelcastStoreFactory();
+
+ public HazelcastStoreTest() {
+ super();
+ factory.setTimeout(TIMEOUT);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ store = factory.open("test");
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ factory.close(store);
+ }
+
+
+ public void testTimeout() throws Exception {
+ String id = store.store("Any kind of data...");
+ Object data = store.load(id);
+ assertNotNull(data);
+ //now store it again and load it after the timeout
+ store.store(id, data);
+ synchronized (this) {
+ wait(TIMEOUT * 2);
+ }
+ assertNull("Data should have been removed from store after timeout",
store.load(id));
+ }
+
+
+ public void testDistributesStoreAndLoad() throws Exception {
+ //Create a new Hazelcast instance
+ HazelcastInstance instance = Hazelcast.newHazelcastInstance(null);
+ Map map = instance.getMap(HazelcastStoreFactory.STORE_PREFIX+".test");
+
+ String id = "testId";
+ String data = "testData";
+ map.put(id,new Entry(data));
+ Object result = store.load(id);
+ assertNotNull(data);
+ assertEquals(data, result);
+ }
+}
\ No newline at end of file