From ee5e61da44205561edb8e6252019f79e8c3b9548 Mon Sep 17 00:00:00 2001 From: Mark Fisher Date: Thu, 27 Mar 2008 19:11:54 +0000 Subject: [PATCH] Added MessageStore strategy and SimpleMessageStore implementation for in-memory storage with a BoundedHashMap. --- .../integration/message/MessageStore.java | 34 ++++++++ .../message/SimpleMessageStore.java | 64 +++++++++++++++ .../integration/util/BoundedHashMap.java | 7 +- .../message/SimpleMessageStoreTests.java | 82 +++++++++++++++++++ .../integration/util/BoundedHashMapTests.java | 48 +++++++++++ 5 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 spring-integration-core/src/main/java/org/springframework/integration/message/MessageStore.java create mode 100644 spring-integration-core/src/main/java/org/springframework/integration/message/SimpleMessageStore.java create mode 100644 spring-integration-core/src/test/java/org/springframework/integration/message/SimpleMessageStoreTests.java create mode 100644 spring-integration-core/src/test/java/org/springframework/integration/util/BoundedHashMapTests.java diff --git a/spring-integration-core/src/main/java/org/springframework/integration/message/MessageStore.java b/spring-integration-core/src/main/java/org/springframework/integration/message/MessageStore.java new file mode 100644 index 0000000000..dc14b84a39 --- /dev/null +++ b/spring-integration-core/src/main/java/org/springframework/integration/message/MessageStore.java @@ -0,0 +1,34 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * 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. + */ + +package org.springframework.integration.message; + +/** + * Strategy interface for storing and retrieving messages. + * + * @author Mark Fisher + */ +public interface MessageStore { + + Message put(Object key, Message message); + + Message get(Object key); + + Message remove(Object key); + + int size(); + +} diff --git a/spring-integration-core/src/main/java/org/springframework/integration/message/SimpleMessageStore.java b/spring-integration-core/src/main/java/org/springframework/integration/message/SimpleMessageStore.java new file mode 100644 index 0000000000..44a9dd0fd4 --- /dev/null +++ b/spring-integration-core/src/main/java/org/springframework/integration/message/SimpleMessageStore.java @@ -0,0 +1,64 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * 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. + */ + +package org.springframework.integration.message; + +import java.util.Map; + +import org.springframework.integration.util.BoundedHashMap; +import org.springframework.util.Assert; + +/** + * Map-based implementation of {@link MessageStore} that enforces capacity. + * + * @author Mark Fisher + */ +public class SimpleMessageStore implements MessageStore { + + private static final int DEFAULT_CAPACITY = 1000; + + + private final Map> map; + + + public SimpleMessageStore() { + this(DEFAULT_CAPACITY); + } + + public SimpleMessageStore(int capacity) { + this.map = new BoundedHashMap>(capacity); + } + + + public Message put(Object key, Message message) { + Assert.notNull(key, "'key' must not be null"); + Assert.notNull(message, "'message' must not be null"); + return this.map.put(key, message); + } + + public Message get(Object key) { + return (key != null) ? this.map.get(key) : null; + } + + public Message remove(Object key) { + return (key != null) ? this.map.remove(key) : null; + } + + public int size() { + return this.map.size(); + } + +} diff --git a/spring-integration-core/src/main/java/org/springframework/integration/util/BoundedHashMap.java b/spring-integration-core/src/main/java/org/springframework/integration/util/BoundedHashMap.java index abb59dfd37..0bd5df50d0 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/util/BoundedHashMap.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/util/BoundedHashMap.java @@ -19,6 +19,8 @@ package org.springframework.integration.util; import java.util.LinkedHashMap; import java.util.Map.Entry; +import org.springframework.util.Assert; + /** * A Map implementation that enforces the specified capacity. * @@ -26,10 +28,11 @@ import java.util.Map.Entry; */ public class BoundedHashMap extends LinkedHashMap { - private final long capacity; + private final int capacity; - public BoundedHashMap(long capacity) { + public BoundedHashMap(int capacity) { + Assert.isTrue(capacity > 0, "capacity must be a positive value"); this.capacity = capacity; } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/message/SimpleMessageStoreTests.java b/spring-integration-core/src/test/java/org/springframework/integration/message/SimpleMessageStoreTests.java new file mode 100644 index 0000000000..9f415ae12c --- /dev/null +++ b/spring-integration-core/src/test/java/org/springframework/integration/message/SimpleMessageStoreTests.java @@ -0,0 +1,82 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * 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. + */ + +package org.springframework.integration.message; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +/** + * @author Mark Fisher + */ +public class SimpleMessageStoreTests { + + @Test + public void testPut() { + SimpleMessageStore store = new SimpleMessageStore(); + Message message1 = new StringMessage("message-1"); + Message previous = store.put(1, message1); + assertNull(previous); + assertNotNull(store.get(1)); + assertEquals(message1, store.get(1)); + } + + @Test + public void testReplace() { + SimpleMessageStore store = new SimpleMessageStore(); + Message messageA = new StringMessage("message-a"); + Message messageB = new StringMessage("message-b"); + store.put(1, messageA); + Message previous = store.put(1, messageB); + assertEquals(messageA, previous); + assertEquals(messageB, store.get(1)); + } + + @Test + public void testRemove() { + SimpleMessageStore store = new SimpleMessageStore(); + Message message = new StringMessage("message"); + assertNull(store.remove(1)); + store.put(1, message); + assertEquals(message, store.remove(1)); + } + + @Test + public void testCapacityEnforced() { + SimpleMessageStore store = new SimpleMessageStore(3); + Message message1 = new StringMessage("message-1"); + Message message2 = new StringMessage("message-2"); + Message message3 = new StringMessage("message-3"); + Message message4 = new StringMessage("message-4"); + store.put(1, message1); + store.put(2, message2); + store.put(3, message3); + assertEquals(3, store.size()); + assertEquals(message1, store.get(1)); + assertEquals(message2, store.get(2)); + assertEquals(message3, store.get(3)); + store.put(4, message4); + assertEquals(3, store.size()); + assertNull(store.get(1)); + assertEquals(message2, store.get(2)); + assertEquals(message3, store.get(3)); + assertEquals(message4, store.get(4)); + } + +} diff --git a/spring-integration-core/src/test/java/org/springframework/integration/util/BoundedHashMapTests.java b/spring-integration-core/src/test/java/org/springframework/integration/util/BoundedHashMapTests.java new file mode 100644 index 0000000000..f0d1ad2284 --- /dev/null +++ b/spring-integration-core/src/test/java/org/springframework/integration/util/BoundedHashMapTests.java @@ -0,0 +1,48 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * 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. + */ + +package org.springframework.integration.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * @author Mark Fisher + */ +public class BoundedHashMapTests { + + @Test + public void testCapacityEnforced() { + BoundedHashMap map = new BoundedHashMap(3); + map.put("A", 1); + map.put("B", 2); + map.put("C", 3); + assertEquals(3, map.size()); + assertTrue(map.containsKey("A")); + assertTrue(map.containsKey("B")); + assertTrue(map.containsKey("C")); + map.put("D", 4); + assertEquals(3, map.size()); + assertFalse(map.containsKey("A")); + assertTrue(map.containsKey("B")); + assertTrue(map.containsKey("C")); + assertTrue(map.containsKey("D")); + } + +}