Skip to content

Commit

Permalink
[DROOLS-7482] Experiment H2 persistence (#5368)
Browse files Browse the repository at this point in the history
- Add H2 MVStore persistence
- Has some duplicate test cases with infinispan
  • Loading branch information
tkobayas authored Jul 3, 2023
1 parent 867af77 commit 25c31f3
Show file tree
Hide file tree
Showing 18 changed files with 1,149 additions and 3 deletions.
18 changes: 18 additions & 0 deletions bom/drools-bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,24 @@
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-reliability-h2mvstore</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-reliability-h2mvstore</artifactId>
<version>${project.version}</version>
<classifier>sources</classifier>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-reliability-h2mvstore</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-tms</artifactId>
Expand Down
1 change: 0 additions & 1 deletion drools-reliability/drools-reliability-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
</parent>
<modelVersion>4.0.0</modelVersion>

<groupId>org.drools</groupId>
<artifactId>drools-reliability-core</artifactId>

<name>Drools :: Reliability :: Core</name>
Expand Down
2 changes: 2 additions & 0 deletions drools-reliability/drools-reliability-h2mvstore/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
tmp/
h2mvstore.db
80 changes: 80 additions & 0 deletions drools-reliability/drools-reliability-h2mvstore/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.drools</groupId>
<artifactId>drools-reliability</artifactId>
<version>8.41.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>drools-reliability-h2mvstore</artifactId>

<name>Drools :: Reliability :: H2 MVStore persistence</name>

<properties>
<java.module.name>org.drools.reliability.h2mvstore</java.module.name>
</properties>

<dependencies>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-reliability-core</artifactId>
</dependency>

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>

<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-engine</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>

<dependency><!-- For unit test logging: configure in src/test/resources/logback-test.xml -->
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-model-codegen</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright 2023 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* 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.drools.reliability.h2mvstore;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

import org.drools.core.common.Storage;
import org.h2.mvstore.MVMap;

public class H2MVStoreStorage<K, V> implements Storage<K, V> {

private MVMap<K, V> mvMap;

public static <K1, V1> Storage<K1, V1> fromMVMap(MVMap<K1, V1> mvMap) {
return new H2MVStoreStorage<>(mvMap);
}

private H2MVStoreStorage(MVMap<K, V> mvMap) {
this.mvMap = mvMap;
}

@Override
public V get(K key) {
return mvMap.get(key);
}

@Override
public V getOrDefault(K key, V value) {
return mvMap.getOrDefault(key, value);
}

@Override
public V put(K key, V value) {
V previousValue = mvMap.put(key, value);
mvMap.store.commit();
return previousValue;
}

@Override
public void putAll(Map<? extends K, ? extends V> otherMap) {
mvMap.putAll(otherMap);
mvMap.store.commit();
}

@Override
public boolean containsKey(K key) {
return mvMap.containsKey(key);
}

@Override
public V remove(K key) {
V previousValue = mvMap.remove(key);
mvMap.store.commit();
return previousValue;
}

@Override
public void clear() {
mvMap.clear();
mvMap.store.commit();
}

@Override
public Collection<V> values() {
return mvMap.values();
}

@Override
public Set<K> keySet() {
return mvMap.keySet();
}

@Override
public int size() {
return mvMap.size();
}

@Override
public boolean isEmpty() {
return mvMap.isEmpty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* Copyright 2023 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* 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.drools.reliability.h2mvstore;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;

import org.drools.core.common.ReteEvaluator;
import org.drools.core.common.Storage;
import org.drools.reliability.core.TestableStorageManager;
import org.h2.mvstore.MVMap;
import org.h2.mvstore.MVStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.drools.reliability.core.StorageManager.createStorageId;
import static org.drools.reliability.core.StorageManagerFactory.DELIMITER;
import static org.drools.reliability.core.StorageManagerFactory.SESSION_STORAGE_PREFIX;
import static org.drools.reliability.core.StorageManagerFactory.SHARED_STORAGE_PREFIX;

public class H2MVStoreStorageManager implements TestableStorageManager {

private static final Logger LOG = LoggerFactory.getLogger(H2MVStoreStorageManager.class);

static final H2MVStoreStorageManager INSTANCE = new H2MVStoreStorageManager();

public static final String STORE_FILE_NAME = "h2mvstore.db";

private MVStore mvStore;

private H2MVStoreStorageManager() {
}

@Override
public void initStorageManager() {
LOG.info("Using H2MVStoreStorageManager");
mvStore = MVStore.open(STORE_FILE_NAME);
}

@Override
public <K, V> Storage<K, V> internalGetOrCreateStorageForSession(ReteEvaluator reteEvaluator, String cacheName) {
MVMap<K, V> mvMap = mvStore.openMap(createStorageId(reteEvaluator, cacheName));
return H2MVStoreStorage.fromMVMap(mvMap);
}

@Override
public <K, V> Storage<K, V> getOrCreateSharedStorage(String cacheName) {
MVMap<K, V> mvMap = mvStore.openMap(SHARED_STORAGE_PREFIX + cacheName);
return H2MVStoreStorage.fromMVMap(mvMap);
}

@Override
public void close() {
mvStore.close();
}

@Override
public void removeStorage(String storageName) {
mvStore.removeMap(storageName);
}

@Override
public void removeStoragesBySessionId(String sessionId) {
mvStore.getMapNames()
.stream()
.filter(mapName -> mapName.startsWith(SESSION_STORAGE_PREFIX + sessionId + DELIMITER))
.forEach(this::removeStorage);
}

@Override
public void removeAllSessionStorages() {
mvStore.getMapNames()
.stream()
.filter(mapName -> mapName.startsWith(SESSION_STORAGE_PREFIX))
.forEach(this::removeStorage);
}

@Override
public Set<String> getStorageNames() {
return mvStore.getMapNames();
}

//--- test purpose

@Override
public void restart() {
// JVM crashed
mvStore.close();
mvStore = null;

// Reboot
initStorageManager();
}

@Override
public void restartWithCleanUp() {
// JVM crashed
mvStore.close();
mvStore = null;

// remove database file
cleanUpDatabase();

// Reboot
initStorageManager();
}

@Override
public boolean isRemote() {
return false;
}

public static void cleanUpDatabase() {
// remove database file
Path path = Paths.get(STORE_FILE_NAME);
try {
Files.deleteIfExists(path);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2023 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* 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.drools.reliability.h2mvstore;

import org.drools.reliability.core.StorageManager;
import org.drools.reliability.core.StorageManagerFactory;

public class H2MVStoreStorageManagerFactory implements StorageManagerFactory {

private final StorageManager storageManager;

public H2MVStoreStorageManagerFactory() {
storageManager = H2MVStoreStorageManager.INSTANCE;
storageManager.initStorageManager();
}

@Override
public StorageManager getStorageManager() {
return storageManager;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.drools.reliability.h2mvstore.H2MVStoreStorageManagerFactory
Loading

0 comments on commit 25c31f3

Please sign in to comment.