package org.infinispan.functional; import java.time.Duration; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; import org.infinispan.AdvancedCache; import org.infinispan.commons.api.functional.EntryView.ReadEntryView; import org.infinispan.commons.api.functional.FunctionalMap.ReadOnlyMap; import org.infinispan.commons.api.functional.FunctionalMap.ReadWriteMap; import org.infinispan.commons.api.functional.FunctionalMap.WriteOnlyMap; import org.infinispan.commons.api.functional.MetaParam.MetaLifespan; import org.infinispan.commons.api.functional.Traversable; import org.infinispan.functional.impl.FunctionalMapImpl; import org.infinispan.functional.impl.ReadOnlyMapImpl; import org.infinispan.functional.impl.ReadWriteMapImpl; import org.infinispan.functional.impl.WriteOnlyMapImpl; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.test.SingleCacheManagerTest; import org.infinispan.test.fwk.TestCacheManagerFactory; import org.testng.annotations.Test; @Test(groups = "functional", testName = "functional.FunctionalSimpleTutorialTest") public class FunctionalSimpleTutorialTest extends SingleCacheManagerTest { @Override protected EmbeddedCacheManager createCacheManager() throws Exception { return TestCacheManagerFactory.createCacheManager(); } public void testSimpleTutorial() throws Exception { AdvancedCache<String, String> cache = cacheManager.<String, String>getCache().getAdvancedCache(); FunctionalMapImpl<String, String> functionalMap = FunctionalMapImpl.create(cache); WriteOnlyMap<String, String> writeOnlyMap = WriteOnlyMapImpl.create(functionalMap); ReadOnlyMap<String, String> readOnlyMap = ReadOnlyMapImpl.create(functionalMap); // Execute two parallel write-only operation to store key/value pairs CompletableFuture<Void> writeFuture1 = writeOnlyMap.eval("key1", "value1", (v, writeView) -> writeView.set(v)); CompletableFuture<Void> writeFuture2 = writeOnlyMap.eval("key2", "value2", (v, writeView) -> writeView.set(v)); // When each write-only operation completes, execute a read-only operation to retrieve the value CompletableFuture<String> readFuture1 = writeFuture1.thenCompose(r -> readOnlyMap.eval("key1", ReadEntryView::get)); CompletableFuture<String> readFuture2 = writeFuture2.thenCompose(r -> readOnlyMap.eval("key2", ReadEntryView::get)); // When the read-only operation completes, print it out printf("Created entries: %n"); CompletableFuture<Void> end = readFuture1.thenAcceptBoth(readFuture2, (v1, v2) -> printf("key1 = %s%nkey2 = %s%n", v1, v2)); // Wait for this read/write combination to finish end.get(); // Create a read-write map ReadWriteMap<String, String> readWriteMap = ReadWriteMapImpl.create(functionalMap); // Use read-write multi-key based operation to write new values // together with lifespan and return previous values Map<String, String> data = new HashMap<>(); data.put("key1", "newValue1"); data.put("key2", "newValue2"); Traversable<String> previousValues = readWriteMap.evalMany(data, (v, readWriteView) -> { String prev = readWriteView.find().orElse(null); readWriteView.set(v, new MetaLifespan(Duration.ofHours(1).toMillis())); return prev; }); // Use read-only multi-key operation to read current values for multiple keys Traversable<ReadEntryView<String, String>> entryViews = readOnlyMap.evalMany(data.keySet(), readOnlyView -> readOnlyView); printf("Updated entries: %n"); entryViews.forEach(view -> printf("%s%n", view)); // Finally, print out the previous entry values printf("Previous entry values: %n"); previousValues.forEach(prev -> printf("%s%n", prev)); } private void printf(String format, Object ... args) { log.infof(format, args); } }