From 8993a3064be10e4c5b7d5df665f2cfc9254e16a5 Mon Sep 17 00:00:00 2001 From: Daniel Strmecki Date: Thu, 22 Sep 2022 19:53:16 +0200 Subject: [PATCH] Feature/bael 5653 microstream (#12660) * BAEL-5653: Microstream storage * BAEL-5653: Eager loading * BAEL-5653: Lazy loading * BAEL-5653: Temp dir * BAEL-5653: Refactoring * BAEL-5653: Refactoring * BAEL-5653: Refactoring * BAEL-5653: PR comments --- .../core-java-persistence-2/.gitignore | 3 + .../core-java-persistence-2/pom.xml | 17 ++++ .../java/com/baeldung/microstream/Author.java | 40 +++++++++ .../java/com/baeldung/microstream/Book.java | 46 ++++++++++ .../baeldung/microstream/RootInstance.java | 23 +++++ .../microstream/RootInstanceLazy.java | 26 ++++++ .../baeldung/microstream/StorageManager.java | 60 ++++++++++++++ .../microstream/StorageManagerUnitTest.java | 83 +++++++++++++++++++ 8 files changed, 298 insertions(+) create mode 100644 persistence-modules/core-java-persistence-2/.gitignore create mode 100644 persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/Author.java create mode 100644 persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/Book.java create mode 100644 persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/RootInstance.java create mode 100644 persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/RootInstanceLazy.java create mode 100644 persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/StorageManager.java create mode 100644 persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/microstream/StorageManagerUnitTest.java diff --git a/persistence-modules/core-java-persistence-2/.gitignore b/persistence-modules/core-java-persistence-2/.gitignore new file mode 100644 index 0000000000..3e2e2f0df3 --- /dev/null +++ b/persistence-modules/core-java-persistence-2/.gitignore @@ -0,0 +1,3 @@ +.idea +storage +target \ No newline at end of file diff --git a/persistence-modules/core-java-persistence-2/pom.xml b/persistence-modules/core-java-persistence-2/pom.xml index 1d9852ae53..b92ee0d899 100644 --- a/persistence-modules/core-java-persistence-2/pom.xml +++ b/persistence-modules/core-java-persistence-2/pom.xml @@ -51,6 +51,22 @@ json ${json.version} + + one.microstream + microstream-storage-embedded + ${microstream.storage.version} + + + one.microstream + microstream-storage-embedded-configuration + ${microstream.storage.version} + + + org.assertj + assertj-core + ${assertj.version} + test + @@ -59,6 +75,7 @@ 8.0.22 3.11.11 20220320 + 07.00.00-MS-GA \ No newline at end of file diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/Author.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/Author.java new file mode 100644 index 0000000000..3088ea86e2 --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/Author.java @@ -0,0 +1,40 @@ +package com.baeldung.microstream; + +import java.util.Objects; + +public class Author { + + private final String name; + private final String surname; + + public Author(String name, String surname) { + this.name = name; + this.surname = surname; + } + + public String getName() { + return name; + } + + public String getSurname() { + return surname; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Author author = (Author) o; + return Objects.equals(name, author.name) && Objects.equals(surname, author.surname); + } + + @Override + public int hashCode() { + return Objects.hash(name, surname); + } + +} diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/Book.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/Book.java new file mode 100644 index 0000000000..f01c026c13 --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/Book.java @@ -0,0 +1,46 @@ +package com.baeldung.microstream; + +import java.util.Objects; + +public class Book { + + private final String title; + private final Author author; + private final int year; + + public Book(String title, Author author, int year) { + this.title = title; + this.author = author; + this.year = year; + } + + public String getTitle() { + return title; + } + + public Author getAuthor() { + return author; + } + + public int getYear() { + return year; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Book book = (Book) o; + return year == book.year && Objects.equals(title, book.title) && Objects.equals(author, book.author); + } + + @Override + public int hashCode() { + return Objects.hash(title, author, year); + } + +} diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/RootInstance.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/RootInstance.java new file mode 100644 index 0000000000..e91541b931 --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/RootInstance.java @@ -0,0 +1,23 @@ +package com.baeldung.microstream; + +import java.util.ArrayList; +import java.util.List; + +public class RootInstance { + + private final String name; + private final List books; + + public RootInstance(String name) { + this.name = name; + books = new ArrayList<>(); + } + + public String getName() { + return name; + } + + public List getBooks() { + return books; + } +} diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/RootInstanceLazy.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/RootInstanceLazy.java new file mode 100644 index 0000000000..80c957dc80 --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/RootInstanceLazy.java @@ -0,0 +1,26 @@ +package com.baeldung.microstream; + +import one.microstream.reference.Lazy; + +import java.util.ArrayList; +import java.util.List; + +public class RootInstanceLazy { + + private final String name; + private final Lazy> books; + + public RootInstanceLazy(String name) { + this.name = name; + books = Lazy.Reference(new ArrayList<>()); + } + + public String getName() { + return name; + } + + public List getBooks() { + return Lazy.get(books); + } + +} diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/StorageManager.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/StorageManager.java new file mode 100644 index 0000000000..6a3f0f1d3e --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/microstream/StorageManager.java @@ -0,0 +1,60 @@ +package com.baeldung.microstream; + +import one.microstream.storage.embedded.types.EmbeddedStorage; +import one.microstream.storage.embedded.types.EmbeddedStorageManager; + +import java.nio.file.Path; +import java.util.List; + +public class StorageManager { + + public static final String STORAGE_ROOT_FOLDER = "storage"; + + public static EmbeddedStorageManager initializeStorageWithStringAsRoot(Path directory, String root) { + EmbeddedStorageManager storageManager = EmbeddedStorage.start(directory); + storageManager.setRoot(root); + storageManager.storeRoot(); + return storageManager; + } + + public static EmbeddedStorageManager initializeStorageWithCustomTypeAsRoot(Path directory, String root) { + EmbeddedStorageManager storageManager = EmbeddedStorage.start(directory); + storageManager.setRoot(new RootInstance(root)); + storageManager.storeRoot(); + return storageManager; + } + + public static EmbeddedStorageManager initializeStorageWithCustomTypeAsRoot(Path directory, String root, List booksToStore) { + EmbeddedStorageManager storageManager = EmbeddedStorage.start(directory); + RootInstance rootInstance = new RootInstance(root); + storageManager.setRoot(rootInstance); + storageManager.storeRoot(); + + List books = rootInstance.getBooks(); + books.addAll(booksToStore); + storageManager.store(books); + return storageManager; + } + + public static EmbeddedStorageManager loadOrCreateStorageWithCustomTypeAsRoot(Path directory, String root) { + EmbeddedStorageManager storageManager = EmbeddedStorage.start(directory); + if (storageManager.root() == null) { + RootInstance rootInstance = new RootInstance(root); + storageManager.setRoot(rootInstance); + storageManager.storeRoot(); + } + return storageManager; + } + + public static EmbeddedStorageManager lazyLoadOrCreateStorageWithCustomTypeAsRoot(Path directory, String root, List booksToStore) { + EmbeddedStorageManager storageManager = EmbeddedStorage.start(directory); + if (storageManager.root() == null) { + RootInstanceLazy rootInstance = new RootInstanceLazy(root); + rootInstance.getBooks().addAll(booksToStore); + storageManager.setRoot(rootInstance); + storageManager.storeRoot(); + } + return storageManager; + } + +} diff --git a/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/microstream/StorageManagerUnitTest.java b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/microstream/StorageManagerUnitTest.java new file mode 100644 index 0000000000..868980cc4f --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/microstream/StorageManagerUnitTest.java @@ -0,0 +1,83 @@ +package com.baeldung.microstream; + +import one.microstream.storage.embedded.types.EmbeddedStorageManager; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.*; + +class StorageManagerUnitTest { + + private static final Author AUTHOR = new Author("Joanne", "Rowling"); + private static final Book BOOK_ONE = new Book("Harry Potter and the Philosopher's Stone", AUTHOR, 1997); + private static final Book BOOK_TWO = new Book("Harry Potter and the Chamber of Secrets", AUTHOR, 1998); + + @Test + void givenStorageWithStringAsRoot_whenFetchingRoot_thenExpectedStringIsReturned(@TempDir Path tempDir) { + EmbeddedStorageManager storageManager = StorageManager.initializeStorageWithStringAsRoot(tempDir, "baeldung-demo-1"); + assertThat(storageManager.root()).isEqualTo("baeldung-demo-1"); + storageManager.shutdown(); + } + + @Test + void givenStorageWithCustomTypeAsRoot_whenFetchingRoot_thenCustomTypeWithExpectedValuesIsReturned(@TempDir Path tempDir) { + EmbeddedStorageManager storageManager = StorageManager.initializeStorageWithCustomTypeAsRoot(tempDir, "baeldung-demo-2"); + RootInstance rootInstance = (RootInstance) storageManager.root(); + assertThat(rootInstance.getName()).isEqualTo("baeldung-demo-2"); + assertThat(rootInstance.getBooks()).isEmpty(); + storageManager.shutdown(); + } + + @Test + void givenStorageWithAdditionalObjects_whenLoadingRoot_thenAdditionalObjectsAreSuccessfullyStored(@TempDir Path tempDir) { + EmbeddedStorageManager storageManager = StorageManager.initializeStorageWithCustomTypeAsRoot(tempDir, "baeldung-demo-3", Arrays.asList(BOOK_ONE, BOOK_TWO)); + RootInstance rootInstance = (RootInstance) storageManager.root(); + assertThat(rootInstance.getName()).isEqualTo("baeldung-demo-3"); + assertThat(rootInstance.getBooks()).hasSize(2); + assertThat(rootInstance.getBooks().get(0)).isEqualTo(BOOK_ONE); + assertThat(rootInstance.getBooks().get(1)).isEqualTo(BOOK_TWO); + storageManager.shutdown(); + } + + @Test + void givenStorageWithAdditionalObjects_whenLazyLoadingRoot_thenAdditionalObjectsAreSuccessfullyStored(@TempDir Path tempDir) { + EmbeddedStorageManager storageManager = StorageManager.lazyLoadOrCreateStorageWithCustomTypeAsRoot(tempDir, "baeldung-demo-4", Arrays.asList(BOOK_ONE, BOOK_TWO)); + RootInstanceLazy rootInstance = (RootInstanceLazy) storageManager.root(); + assertThat(rootInstance.getName()).isEqualTo("baeldung-demo-4"); + assertThat(rootInstance.getBooks()).hasSize(2); + assertThat(rootInstance.getBooks().get(0)).isEqualTo(BOOK_ONE); + assertThat(rootInstance.getBooks().get(1)).isEqualTo(BOOK_TWO); + storageManager.shutdown(); + } + + @Test + void givenStorageWithAdditionalObjects_whenRemovingObjectsFromGraph_thenObjectsAreSuccessfullyRemoved(@TempDir Path tempDir) { + EmbeddedStorageManager storageManager = StorageManager.lazyLoadOrCreateStorageWithCustomTypeAsRoot(tempDir, "baeldung-demo-5", Arrays.asList(BOOK_ONE, BOOK_TWO)); + RootInstanceLazy rootInstance = (RootInstanceLazy) storageManager.root(); + List books = rootInstance.getBooks(); + books.remove(1); + storageManager.store(books); + assertThat(rootInstance.getName()).isEqualTo("baeldung-demo-5"); + assertThat(books).hasSize(1); + storageManager.shutdown(); + } + + @Test + void givenStorageWithAdditionalObjects_whenFilteringCollectionFromGraph_thenStreamsCanBeUsed(@TempDir Path tempDir) { + EmbeddedStorageManager storageManager = StorageManager.lazyLoadOrCreateStorageWithCustomTypeAsRoot(tempDir, "baeldung-demo-6", Arrays.asList(BOOK_ONE, BOOK_TWO)); + RootInstanceLazy rootInstance = (RootInstanceLazy) storageManager.root(); + List booksFrom1998 = rootInstance.getBooks().stream() + .filter(book -> book.getYear() == 1998) + .collect(Collectors.toList()); + assertThat(rootInstance.getName()).isEqualTo("baeldung-demo-6"); + assertThat(booksFrom1998).hasSize(1); + assertThat(booksFrom1998.get(0).getYear()).isEqualTo(1998); + storageManager.shutdown(); + } + +}