CAMEL-8478: IdempotentRepository - Add clear operation
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/4f1cf5a9 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/4f1cf5a9 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/4f1cf5a9 Branch: refs/heads/fix-8478 Commit: 4f1cf5a93e3f059fdae8d66fac5005425c5cbfe7 Parents: 38af955 Author: Andrea Cosentino <anco...@gmail.com> Authored: Thu Jul 2 15:14:57 2015 +0200 Committer: Andrea Cosentino <anco...@gmail.com> Committed: Thu Jul 2 22:46:06 2015 +0200 ---------------------------------------------------------------------- .../mbean/ManagedIdempotentConsumerMBean.java | 4 +- .../mbean/ManagedIdempotentConsumer.java | 5 + .../idempotent/FileIdempotentRepository.java | 7 + .../idempotent/IdempotentConsumer.java | 7 + .../idempotent/MemoryIdempotentRepository.java | 7 + .../apache/camel/spi/IdempotentRepository.java | 8 + .../file/FileConsumerIdempotentRefTest.java | 5 + .../ManagedFileIdempotentClearTest.java | 139 ++++++++++++++ .../ManagedMemoryIdempotentClearTest.java | 183 +++++++++++++++++++ .../ExchangeIdempotentConsumerTest.java | 5 + .../processor/FileIdempotentClearTest.java | 75 ++++++++ ...potentConsumerUsingCustomRepositoryTest.java | 13 ++ 12 files changed, 457 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/4f1cf5a9/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedIdempotentConsumerMBean.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedIdempotentConsumerMBean.java b/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedIdempotentConsumerMBean.java index fa2bb05..5001486 100644 --- a/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedIdempotentConsumerMBean.java +++ b/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedIdempotentConsumerMBean.java @@ -26,5 +26,7 @@ public interface ManagedIdempotentConsumerMBean extends ManagedProcessorMBean { @ManagedOperation(description = "Reset the current count of duplicate Messages") void resetDuplicateMessageCount(); - + + @ManagedOperation(description = "Clear the repository containing Messages") + void clear(); } http://git-wip-us.apache.org/repos/asf/camel/blob/4f1cf5a9/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedIdempotentConsumer.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedIdempotentConsumer.java b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedIdempotentConsumer.java index ec543bf..4aed45c 100644 --- a/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedIdempotentConsumer.java +++ b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedIdempotentConsumer.java @@ -44,4 +44,9 @@ public class ManagedIdempotentConsumer extends ManagedProcessor implements Manag getProcessor().resetDuplicateMessageCount(); } + @Override + public void clear() { + getProcessor().clear(); + } + } http://git-wip-us.apache.org/repos/asf/camel/blob/4f1cf5a9/camel-core/src/main/java/org/apache/camel/processor/idempotent/FileIdempotentRepository.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/processor/idempotent/FileIdempotentRepository.java b/camel-core/src/main/java/org/apache/camel/processor/idempotent/FileIdempotentRepository.java index 59c6853..301fb0d 100644 --- a/camel-core/src/main/java/org/apache/camel/processor/idempotent/FileIdempotentRepository.java +++ b/camel-core/src/main/java/org/apache/camel/processor/idempotent/FileIdempotentRepository.java @@ -153,6 +153,13 @@ public class FileIdempotentRepository extends ServiceSupport implements Idempote // noop return true; } + + @ManagedOperation(description = "Clear the store") + public void clear() { + synchronized (cache) { + cache.clear(); + } + } public File getFileStore() { return fileStore; http://git-wip-us.apache.org/repos/asf/camel/blob/4f1cf5a9/camel-core/src/main/java/org/apache/camel/processor/idempotent/IdempotentConsumer.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/processor/idempotent/IdempotentConsumer.java b/camel-core/src/main/java/org/apache/camel/processor/idempotent/IdempotentConsumer.java index acbfc27..afa80be 100644 --- a/camel-core/src/main/java/org/apache/camel/processor/idempotent/IdempotentConsumer.java +++ b/camel-core/src/main/java/org/apache/camel/processor/idempotent/IdempotentConsumer.java @@ -198,6 +198,13 @@ public class IdempotentConsumer extends ServiceSupport implements AsyncProcessor } /** + * Clear the idempotent repository + */ + public void clear() { + idempotentRepository.clear(); + } + + /** * A strategy method to allow derived classes to overload the behaviour of * processing a duplicate message * http://git-wip-us.apache.org/repos/asf/camel/blob/4f1cf5a9/camel-core/src/main/java/org/apache/camel/processor/idempotent/MemoryIdempotentRepository.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/processor/idempotent/MemoryIdempotentRepository.java b/camel-core/src/main/java/org/apache/camel/processor/idempotent/MemoryIdempotentRepository.java index 929681b..bbbd42e 100644 --- a/camel-core/src/main/java/org/apache/camel/processor/idempotent/MemoryIdempotentRepository.java +++ b/camel-core/src/main/java/org/apache/camel/processor/idempotent/MemoryIdempotentRepository.java @@ -106,6 +106,13 @@ public class MemoryIdempotentRepository extends ServiceSupport implements Idempo // noop return true; } + + @ManagedOperation(description = "Clear the store") + public void clear() { + synchronized (cache) { + cache.clear(); + } + } public Map<String, Object> getCache() { return cache; http://git-wip-us.apache.org/repos/asf/camel/blob/4f1cf5a9/camel-core/src/main/java/org/apache/camel/spi/IdempotentRepository.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/spi/IdempotentRepository.java b/camel-core/src/main/java/org/apache/camel/spi/IdempotentRepository.java index ff6611e..71f076b 100644 --- a/camel-core/src/main/java/org/apache/camel/spi/IdempotentRepository.java +++ b/camel-core/src/main/java/org/apache/camel/spi/IdempotentRepository.java @@ -80,5 +80,13 @@ public interface IdempotentRepository<E> extends Service { * @return <tt>true</tt> if the key was confirmed */ boolean confirm(E key); + + /** + * Clear the repository. + * <p/> + * <b>Important:</b> Read the class javadoc about eager vs non-eager mode. + * + */ + void clear(); } http://git-wip-us.apache.org/repos/asf/camel/blob/4f1cf5a9/camel-core/src/test/java/org/apache/camel/component/file/FileConsumerIdempotentRefTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/component/file/FileConsumerIdempotentRefTest.java b/camel-core/src/test/java/org/apache/camel/component/file/FileConsumerIdempotentRefTest.java index 456df67..55a8089 100644 --- a/camel-core/src/test/java/org/apache/camel/component/file/FileConsumerIdempotentRefTest.java +++ b/camel-core/src/test/java/org/apache/camel/component/file/FileConsumerIdempotentRefTest.java @@ -103,6 +103,11 @@ public class FileConsumerIdempotentRefTest extends ContextTestSupport { public boolean confirm(String key) { return true; } + + @Override + public void clear() { + return; + } public void start() throws Exception { } http://git-wip-us.apache.org/repos/asf/camel/blob/4f1cf5a9/camel-core/src/test/java/org/apache/camel/management/ManagedFileIdempotentClearTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/management/ManagedFileIdempotentClearTest.java b/camel-core/src/test/java/org/apache/camel/management/ManagedFileIdempotentClearTest.java new file mode 100644 index 0000000..697109b --- /dev/null +++ b/camel-core/src/test/java/org/apache/camel/management/ManagedFileIdempotentClearTest.java @@ -0,0 +1,139 @@ +/** + * 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.camel.management; + +import java.io.File; +import java.util.Set; +import javax.management.MBeanServer; +import javax.management.ObjectName; + +import org.apache.camel.Endpoint; +import org.apache.camel.Exchange; +import org.apache.camel.Message; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.processor.idempotent.FileIdempotentRepository; +import org.apache.camel.spi.IdempotentRepository; +import org.apache.camel.util.FileUtil; + +/** + * @version + */ +public class ManagedFileIdempotentClearTest extends ManagementTestSupport { + protected Endpoint startEndpoint; + protected MockEndpoint resultEndpoint; + private File store = new File("target/idempotentfilestore.dat"); + private IdempotentRepository<String> repo; + + public void testDuplicateMessagesAreFilteredOut() throws Exception { + // JMX tests dont work well on AIX CI servers (hangs them) + if (isPlatform("aix")) { + return; + } + + MBeanServer mbeanServer = getMBeanServer(); + + // services + Set<ObjectName> names = mbeanServer.queryNames(new ObjectName("org.apache.camel" + ":type=services,*"), null); + ObjectName on = null; + for (ObjectName name : names) { + if (name.toString().contains("FileIdempotentRepository")) { + on = name; + break; + } + } + + assertTrue("Should be registered", mbeanServer.isRegistered(on)); + String path = (String) mbeanServer.getAttribute(on, "FilePath"); + assertEquals(FileUtil.normalizePath("target/idempotentfilestore.dat"), FileUtil.normalizePath(path)); + + Integer size = (Integer) mbeanServer.getAttribute(on, "CacheSize"); + assertEquals(1, size.intValue()); + + assertFalse(repo.contains("1")); + assertFalse(repo.contains("2")); + assertFalse(repo.contains("3")); + assertTrue(repo.contains("4")); + + resultEndpoint.expectedBodiesReceived("one", "two", "three"); + + sendMessage("1", "one"); + sendMessage("2", "two"); + sendMessage("3", "three"); + + resultEndpoint.assertIsSatisfied(); + + assertTrue(repo.contains("1")); + assertTrue(repo.contains("2")); + assertTrue(repo.contains("3")); + assertTrue(repo.contains("4")); + + size = (Integer) mbeanServer.getAttribute(on, "CacheSize"); + assertEquals(4, size.intValue()); + + // clear + mbeanServer.invoke(on, "clear", null, null); + + // there should be 0 now + size = (Integer) mbeanServer.getAttribute(on, "CacheSize"); + assertEquals(0, size.intValue()); + + assertFalse(repo.contains("1")); + assertFalse(repo.contains("2")); + assertFalse(repo.contains("3")); + assertFalse(repo.contains("4")); + } + + protected void sendMessage(final Object messageId, final Object body) { + template.send(startEndpoint, new Processor() { + public void process(Exchange exchange) { + // now lets fire in a message + Message in = exchange.getIn(); + in.setBody(body); + in.setHeader("messageId", messageId); + } + }); + } + + @Override + protected void setUp() throws Exception { + // delete file store before testing + if (store.exists()) { + store.delete(); + } + + repo = FileIdempotentRepository.fileIdempotentRepository(store); + + // let's add 4 to start with + repo.add("4"); + + super.setUp(); + startEndpoint = resolveMandatoryEndpoint("direct:start"); + resultEndpoint = getMockEndpoint("mock:result"); + } + + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + public void configure() { + from("direct:start") + .idempotentConsumer(header("messageId"), repo) + .to("mock:result"); + } + }; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/4f1cf5a9/camel-core/src/test/java/org/apache/camel/management/ManagedMemoryIdempotentClearTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/management/ManagedMemoryIdempotentClearTest.java b/camel-core/src/test/java/org/apache/camel/management/ManagedMemoryIdempotentClearTest.java new file mode 100644 index 0000000..9dbf162 --- /dev/null +++ b/camel-core/src/test/java/org/apache/camel/management/ManagedMemoryIdempotentClearTest.java @@ -0,0 +1,183 @@ +/** + * 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.camel.management; + +import java.util.Set; +import javax.management.MBeanServer; +import javax.management.ObjectName; + +import org.apache.camel.Endpoint; +import org.apache.camel.Exchange; +import org.apache.camel.Message; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.processor.idempotent.MemoryIdempotentRepository; +import org.apache.camel.spi.IdempotentRepository; + +/** + * @version + */ +public class ManagedMemoryIdempotentClearTest extends ManagementTestSupport { + protected Endpoint startEndpoint; + protected MockEndpoint resultEndpoint; + private IdempotentRepository<String> repo; + + public void testDuplicateMessagesAreFilteredOut() throws Exception { + // JMX tests dont work well on AIX CI servers (hangs them) + if (isPlatform("aix")) { + return; + } + + MBeanServer mbeanServer = getMBeanServer(); + + // services + Set<ObjectName> names = mbeanServer.queryNames(new ObjectName("org.apache.camel" + ":type=services,*"), null); + ObjectName on = null; + for (ObjectName name : names) { + if (name.toString().contains("MemoryIdempotentRepository")) { + on = name; + break; + } + } + assertTrue("Should be registered", mbeanServer.isRegistered(on)); + + Integer size = (Integer) mbeanServer.getAttribute(on, "CacheSize"); + assertEquals(1, size.intValue()); + + assertFalse(repo.contains("1")); + assertFalse(repo.contains("2")); + assertFalse(repo.contains("3")); + assertTrue(repo.contains("4")); + + resultEndpoint.expectedBodiesReceived("one", "two", "three"); + + sendMessage("1", "one"); + sendMessage("2", "two"); + sendMessage("3", "three"); + + resultEndpoint.assertIsSatisfied(); + + assertTrue(repo.contains("1")); + assertTrue(repo.contains("2")); + assertTrue(repo.contains("3")); + assertTrue(repo.contains("4")); + + size = (Integer) mbeanServer.getAttribute(on, "CacheSize"); + assertEquals(4, size.intValue()); + + // remove one from repo + mbeanServer.invoke(on, "clear", null, null); + + // there should be 0 now + size = (Integer) mbeanServer.getAttribute(on, "CacheSize"); + assertEquals(0, size.intValue()); + + assertFalse(repo.contains("1")); + assertFalse(repo.contains("2")); + assertFalse(repo.contains("3")); + assertFalse(repo.contains("4")); + } + + public void testDuplicateMessagesCountAreCorrectlyCounted() throws Exception { + // JMX tests dont work well on AIX CI servers (hangs them) + if (isPlatform("aix")) { + return; + } + + MBeanServer mbeanServer = getMBeanServer(); + + // processors + Set<ObjectName> names = mbeanServer.queryNames(new ObjectName("org.apache.camel" + ":type=processors,*"), null); + ObjectName on = null; + for (ObjectName name : names) { + if (name.toString().contains("idempotentConsumer")) { + on = name; + break; + } + } + assertTrue("Should be registered", mbeanServer.isRegistered(on)); + + Long count = (Long) mbeanServer.getAttribute(on, "DuplicateMessageCount"); + assertEquals(0L, count.longValue()); + + resultEndpoint.expectedBodiesReceived("one", "two"); + + sendMessage("1", "one"); + sendMessage("2", "two"); + sendMessage("1", "one"); + sendMessage("2", "two"); + + resultEndpoint.assertIsSatisfied(); + + count = (Long) mbeanServer.getAttribute(on, "DuplicateMessageCount"); + assertEquals(2L, count.longValue()); + + // reset the count + mbeanServer.invoke(on, "resetDuplicateMessageCount", null, null); + + // count should be resetted + count = (Long) mbeanServer.getAttribute(on, "DuplicateMessageCount"); + assertEquals(0L, count.longValue()); + + resetMocks(); + + resultEndpoint.expectedBodiesReceived("five"); + + sendMessage("4", "four"); + sendMessage("4", "four"); + sendMessage("5", "five"); + sendMessage("4", "four"); + + resultEndpoint.assertIsSatisfied(); + + count = (Long) mbeanServer.getAttribute(on, "DuplicateMessageCount"); + assertEquals(3L, count.longValue()); + } + + protected void sendMessage(final Object messageId, final Object body) { + template.send(startEndpoint, new Processor() { + public void process(Exchange exchange) { + // now lets fire in a message + Message in = exchange.getIn(); + in.setBody(body); + in.setHeader("messageId", messageId); + } + }); + } + + @Override + protected void setUp() throws Exception { + repo = MemoryIdempotentRepository.memoryIdempotentRepository(); + // lets start with 4 + repo.add("4"); + + super.setUp(); + startEndpoint = resolveMandatoryEndpoint("direct:start"); + resultEndpoint = getMockEndpoint("mock:result"); + } + + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + public void configure() { + from("direct:start") + .idempotentConsumer(header("messageId"), repo) + .to("mock:result"); + } + }; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/4f1cf5a9/camel-core/src/test/java/org/apache/camel/processor/ExchangeIdempotentConsumerTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/processor/ExchangeIdempotentConsumerTest.java b/camel-core/src/test/java/org/apache/camel/processor/ExchangeIdempotentConsumerTest.java index 11f3430..dcd06e2 100644 --- a/camel-core/src/test/java/org/apache/camel/processor/ExchangeIdempotentConsumerTest.java +++ b/camel-core/src/test/java/org/apache/camel/processor/ExchangeIdempotentConsumerTest.java @@ -128,6 +128,11 @@ public class ExchangeIdempotentConsumerTest extends ContextTestSupport { exchanges.add(exchange.getExchangeId()); return delegate.confirm(key); } + + @Override + public void clear() { + delegate.clear(); + } @Override public boolean add(String key) { http://git-wip-us.apache.org/repos/asf/camel/blob/4f1cf5a9/camel-core/src/test/java/org/apache/camel/processor/FileIdempotentClearTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/processor/FileIdempotentClearTest.java b/camel-core/src/test/java/org/apache/camel/processor/FileIdempotentClearTest.java new file mode 100644 index 0000000..4ddd24e --- /dev/null +++ b/camel-core/src/test/java/org/apache/camel/processor/FileIdempotentClearTest.java @@ -0,0 +1,75 @@ +/** + * 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.camel.processor; + +import java.io.File; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.processor.idempotent.FileIdempotentRepository; +import org.apache.camel.spi.IdempotentRepository; + +/** + * @version + */ +public class FileIdempotentClearTest extends ContextTestSupport { + + private File store = new File("target/idempotentfilestore.dat"); + private IdempotentRepository<String> repo; + + @Override + protected void setUp() throws Exception { + // delete file store before testing + if (store.exists()) { + store.delete(); + } + repo = FileIdempotentRepository.fileIdempotentRepository(store); + + super.setUp(); + } + + public void testClear() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:result"); + mock.expectedBodiesReceived("Foo", "Bar"); + + template.sendBodyAndHeader("direct:start", "Foo", "messageId", "A"); + template.sendBodyAndHeader("direct:start", "Camel rocks", "messageId", "A"); + template.sendBodyAndHeader("direct:start", "Bar", "messageId", "B"); + + assertMockEndpointsSatisfied(); + + mock.reset(); + mock.expectedBodiesReceived("Camel rocks"); + + repo.clear(); + + assertFalse(repo.contains("A")); + assertFalse(repo.contains("B")); + } + + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + public void configure() { + from("direct:start") + .idempotentConsumer(header("messageId"), repo) + .to("mock:result"); + } + }; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/4f1cf5a9/camel-core/src/test/java/org/apache/camel/processor/IdempotentConsumerUsingCustomRepositoryTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/processor/IdempotentConsumerUsingCustomRepositoryTest.java b/camel-core/src/test/java/org/apache/camel/processor/IdempotentConsumerUsingCustomRepositoryTest.java index 1fe5376..881c2b4 100644 --- a/camel-core/src/test/java/org/apache/camel/processor/IdempotentConsumerUsingCustomRepositoryTest.java +++ b/camel-core/src/test/java/org/apache/camel/processor/IdempotentConsumerUsingCustomRepositoryTest.java @@ -68,6 +68,14 @@ public class IdempotentConsumerUsingCustomRepositoryTest extends ContextTestSupp assertTrue(customRepo.contains("3")); assertTrue(customRepo.contains("4")); assertFalse(customRepo.contains("5")); + + customRepo.clear(); + + assertFalse(customRepo.contains("1")); + assertFalse(customRepo.contains("2")); + assertFalse(customRepo.contains("3")); + assertFalse(customRepo.contains("4")); + assertFalse(customRepo.contains("5")); } protected void sendMessage(final Object messageId, final Object body) { @@ -104,6 +112,11 @@ public class IdempotentConsumerUsingCustomRepositoryTest extends ContextTestSupp return true; } } + + @Override + public void clear() { + cache.clear(); + } public boolean contains(String key) { return cache.containsKey(key);