@Override public void delete(K key) throws Exception { delegate.delete(key); }
@Override public ValueHolder<V> computeAndGet(K key, BiFunction<? super K, ? super V, ? extends V> mappingFunction, Supplier<Boolean> replaceEqual, Supplier<Boolean> invokeWriter) throws StoreAccessException { BiFunction<? super K, ? super V, ? extends V> remappingFunction = (mappedKey, mappedValue) -> { V newValue = mappingFunction.apply(mappedKey, mappedValue); if (invokeWriter.get()) { try { if (newValue != null) { cacheLoaderWriter.write(mappedKey, newValue); } else { cacheLoaderWriter.delete(mappedKey); } } catch (Exception e) { throw new StorePassThroughException(newCacheWritingException(e)); } } return newValue; }; return delegate.computeAndGet(key, remappingFunction, replaceEqual, SUPPLY_FALSE); }
/** * {@inheritDoc} */ public void performOperation(CacheLoaderWriter<K, V> cacheLoaderWriter) throws BulkCacheWritingException, Exception { cacheLoaderWriter.deleteAll(entries); }
@Test public void testReplace2ArgsWithNoCacheEntry_should_not_call_writer() throws Exception { doThrow(new Exception("Mock Exception: cannot write 1")).when(cacheLoaderWriter).write(eq(1), eq("one#2")); testCache.replace(1, "one#2"); }
@Override public ValueHolder<V> get(K key) throws StoreAccessException { Function<K, V> mappingFunction = k -> { try { return cacheLoaderWriter.load(k); } catch (Exception e) { throw new StorePassThroughException(newCacheLoadingException(e)); } }; return delegate.computeIfAbsent(key, mappingFunction); }
@Test public void testGetAll_with_cache_loader() throws Exception { CacheConfigurationBuilder cacheConfigurationBuilder = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class, heap(100)); CacheLoaderWriterProvider cacheLoaderWriterProvider = mock(CacheLoaderWriterProvider.class); CacheLoaderWriter cacheLoaderWriter = mock(CacheLoaderWriter.class); when(cacheLoaderWriter.load(ArgumentMatchers.any())).thenThrow(new RuntimeException("We should not have called .load() but .loadAll()")); when(cacheLoaderWriterProvider.createCacheLoaderWriter(anyString(), ArgumentMatchers.any(CacheConfiguration.class))).thenReturn(cacheLoaderWriter); CacheManagerBuilder<CacheManager> managerBuilder = CacheManagerBuilder.newCacheManagerBuilder().using(cacheLoaderWriterProvider); CacheConfiguration<String, String> cacheConfiguration = cacheConfigurationBuilder.withLoaderWriter(cacheLoaderWriter).build(); CacheManager cacheManager = managerBuilder.withCache("myCache", cacheConfiguration).build(true); when(cacheLoaderWriter.loadAll(argThat(IsCollectionContaining.<String>hasItem("key0")))).thenReturn(new HashMap(){{put("key0","value0");}}); when(cacheLoaderWriter.loadAll(argThat(IsCollectionContaining.<String>hasItem("key2")))).thenReturn(new HashMap(){{put("key2","value2");}}); Cache<String, String> myCache = cacheManager.getCache("myCache", String.class, String.class); Set<String> fewKeysSet = new HashSet<String>() { { add("key0"); add("key2"); } }; // the call to getAll Map<String, String> fewEntries = myCache.getAll(fewKeysSet); assertThat(fewEntries.size(), is(2)); assertThat(fewEntries.get("key0"), is("value0")); assertThat(fewEntries.get("key2"), is("value2")); }
doThrow(new RuntimeException("We should not have called .write() but .writeAll()")).when(cacheLoaderWriter).write(ArgumentMatchers .any(), ArgumentMatchers.any()); when(cacheLoaderWriterProvider.createCacheLoaderWriter(anyString(), ArgumentMatchers.any(CacheConfiguration.class))).thenReturn(cacheLoaderWriter); verify(cacheLoaderWriter, times(3)).writeAll(ArgumentMatchers.any(Iterable.class)); Set set = new HashSet(){{add(entry("key0", "value0"));}}; verify(cacheLoaderWriter).writeAll(set); set = new HashSet(){{add(entry("key1", "value1"));}}; verify(cacheLoaderWriter).writeAll(set); set = new HashSet(){{add(entry("key2", "value2"));}}; verify(cacheLoaderWriter).writeAll(set);
@Override public Map<K, V> loadAll(Iterable<? extends K> keys) throws BulkCacheLoadingException, Exception { return delegate.loadAll(keys); }
@Override public void writeAll(Iterable<? extends Map.Entry<? extends K, ? extends V>> entries) throws BulkCacheWritingException, Exception { delegate.writeAll(entries); }
doThrow(new Exception("Simulating an exception from the cache writer")).when(cacheLoaderWriterThatThrows).deleteAll(ArgumentMatchers.any(Iterable.class)); when(cacheLoaderWriterProvider.createCacheLoaderWriter(anyString(), ArgumentMatchers.any(CacheConfiguration.class))).thenReturn(cacheLoaderWriterThatThrows); doThrow(new RuntimeException("We should not have called .write() but .writeAll()")).when(cacheLoaderWriterThatThrows).write(ArgumentMatchers .any(), ArgumentMatchers.any());
doThrow(new RuntimeException("We should not have called .write() but .writeAll()")).when(cacheLoaderWriter).delete(ArgumentMatchers.any()); when(cacheLoaderWriterProvider.createCacheLoaderWriter(anyString(), ArgumentMatchers.any(CacheConfiguration.class))).thenReturn(cacheLoaderWriter); verify(cacheLoaderWriter).deleteAll(set); set = new HashSet(){{add("key2");}}; verify(cacheLoaderWriter).deleteAll(set);
@Test public void replaceFailure_writeFails() throws Exception { when(loaderWriter.load(1)).thenReturn(2L); doThrow(exception).when(loaderWriter).write(1, 1L); assertThatThrownBy(() -> strategy.replaceFailure(1, 1L, accessException)) .isExactlyInstanceOf(CacheWritingException.class) .hasCause(exception); verify(store).obliterate(1); verify(loaderWriter).load(1); verify(loaderWriter).write(1, 1L); }
@Test public void removeFailure1_deleteFails() throws Exception { when(loaderWriter.load(1)).thenReturn(1L); doThrow(exception).when(loaderWriter).delete(1); assertThatThrownBy(() -> strategy.removeFailure(1, 1L, accessException)) .isExactlyInstanceOf(CacheWritingException.class) .hasCause(exception); verify(store).obliterate(1); verify(loaderWriter).load(1); verify(loaderWriter).delete(1); }
@Test public void testReplace3ArgsWithNoCacheEntry_should_not_call_writer() throws Exception { doThrow(new Exception("Mock Exception: cannot write 1")).when(cacheLoaderWriter).write(eq(1), eq("one#2")); testCache.replace(1, "one", "one#2"); }
@Test public void testGetWithLoaderException() throws Exception { when(cacheLoaderWriter.load(eq(1))).thenThrow(new Exception("TestException: cannot load data")); try { testCache.get(1); fail("expected CacheLoadingException"); } catch (CacheLoadingException ex) { // expected } verify(cacheLoaderWriter, times(1)).load(eq(1)); }
@Test public void testGetAll_cache_loader_throws_exception() throws Exception { CacheConfigurationBuilder cacheConfigurationBuilder = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class, heap(100)); CacheLoaderWriterProvider cacheLoaderWriterProvider = mock(CacheLoaderWriterProvider.class); CacheLoaderWriter cacheLoaderWriter = mock(CacheLoaderWriter.class); when(cacheLoaderWriter.load(ArgumentMatchers.any())).thenThrow(new RuntimeException("We should not have called .load() but .loadAll()")); when(cacheLoaderWriter.loadAll(ArgumentMatchers.any(Iterable.class))).thenThrow(new Exception("Simulating an exception from the cache loader")); when(cacheLoaderWriterProvider.createCacheLoaderWriter(anyString(), ArgumentMatchers.any(CacheConfiguration.class))).thenReturn(cacheLoaderWriter); CacheManagerBuilder<CacheManager> managerBuilder = CacheManagerBuilder.newCacheManagerBuilder().using(cacheLoaderWriterProvider); CacheConfiguration<String, String> cacheConfiguration = cacheConfigurationBuilder.withLoaderWriter(cacheLoaderWriter).build(); CacheManager cacheManager = managerBuilder.withCache("myCache", cacheConfiguration).build(true); Cache<String, String> myCache = cacheManager.getCache("myCache", String.class, String.class); Set<String> fewKeysSet = new HashSet<String>() { { add("key0"); add("key2"); } }; // the call to getAll try { myCache.getAll(fewKeysSet); fail(); } catch (BulkCacheLoadingException bcwe) { // since onHeapStore.bulkComputeIfAbsent sends batches of 1 element, assertThat(bcwe.getFailures().size(), is(2)); assertThat(bcwe.getSuccesses().size(), is(0)); } }
@Test public void testPutAll_with_cache_writer_that_throws_exception() throws Exception { CacheConfigurationBuilder cacheConfigurationBuilder = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class, heap(100)); CacheLoaderWriterProvider cacheLoaderWriterProvider = mock(CacheLoaderWriterProvider.class); CacheLoaderWriter cacheLoaderWriterThatThrows = mock(CacheLoaderWriter.class); doThrow(new RuntimeException("We should not have called .write() but .writeAll()")).when(cacheLoaderWriterThatThrows).write(ArgumentMatchers .any(), ArgumentMatchers.any()); doThrow(new Exception("Simulating an exception from the cache writer")).when(cacheLoaderWriterThatThrows).writeAll(ArgumentMatchers.any(Iterable.class)); when(cacheLoaderWriterProvider.createCacheLoaderWriter(anyString(), ArgumentMatchers.any(CacheConfiguration.class))).thenReturn(cacheLoaderWriterThatThrows); CacheManagerBuilder<CacheManager> managerBuilder = CacheManagerBuilder.newCacheManagerBuilder().using(cacheLoaderWriterProvider); CacheConfiguration<String, String> cacheConfiguration = cacheConfigurationBuilder.withLoaderWriter(cacheLoaderWriterThatThrows).build(); CacheManager cacheManager = managerBuilder.withCache("myCache", cacheConfiguration).build(true); Cache<String, String> myCache = cacheManager.getCache("myCache", String.class, String.class); HashMap<String, String> stringStringHashMap = new HashMap<>(); for (int i = 0; i < 3; i++) { stringStringHashMap.put("key" + i, "value" + i); } // the call to putAll try { myCache.putAll(stringStringHashMap); fail(); } catch (BulkCacheWritingException bcwe) { assertThat(bcwe.getFailures().size(), is(3)); assertThat(bcwe.getSuccesses().size(), is(0)); } }
@Override public Map<K, V> loadAllAlways(Iterable<? extends K> keys) throws BulkCacheLoadingException, Exception { return delegate.loadAll(keys); }