You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by ni...@apache.org on 2017/10/29 09:41:49 UTC
[8/8] polygene-java git commit: Added Berkeley DB (Java Edition)
Entity Store.
Added Berkeley DB (Java Edition) Entity Store.
Project: http://git-wip-us.apache.org/repos/asf/polygene-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/polygene-java/commit/879580c3
Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/879580c3
Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/879580c3
Branch: refs/heads/es-bdbje
Commit: 879580c3d7201fb59fac92d3567dfea8b3b91370
Parents: e0825fe
Author: niclas <ni...@hedhman.org>
Authored: Sun Oct 29 17:34:44 2017 +0800
Committer: niclas <ni...@hedhman.org>
Committed: Sun Oct 29 17:34:44 2017 +0800
----------------------------------------------------------------------
dependencies.gradle | 3 +
extensions/entitystore-bdbje/build.gradle | 41 ++
extensions/entitystore-bdbje/dev-status.xml | 38 ++
.../bdbje/BdbJeEntityStoreActivation.java | 59 +++
.../bdbje/BdbJeEntityStoreConfiguration.java | 383 +++++++++++++++++++
.../bdbje/BdbJeEntityStoreMixin.java | 342 +++++++++++++++++
.../bdbje/BdbJeEntityStoreService.java | 52 +++
.../assembly/BdbJeEntityStoreAssembler.java | 45 +++
.../entitystore/bdbje/assembly/package.html | 24 ++
.../polygene/entitystore/bdbje/package.html | 24 ++
.../entitystore/bdbje/BdbJeEntityStoreTest.java | 60 +++
.../bdbje/BdbJeEntityStoreTestSuite.java | 47 +++
settings.gradle | 1 +
13 files changed, 1119 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/879580c3/dependencies.gradle
----------------------------------------------------------------------
diff --git a/dependencies.gradle b/dependencies.gradle
index 0664ace..b4a8c86 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -27,6 +27,7 @@ dependencies.repositoriesUrls << [
mavenCentral: "https://repo1.maven.org/maven2/",
restlet : 'https://maven.restlet.com/',
clojars : "https://clojars.org/repo/",
+ oracle : "http://download.oracle.com/maven/"
]
// Core dependencies
@@ -42,6 +43,7 @@ dependencies.libraries << [
]
// Extensions, Libraries and Tools dependencies
+def bdbjeVersion = '7.4.5'
def bonecpVersion = '0.8.0.RELEASE'
def bouncyVersion = '1.57'
def cassandraClientVersion = '3.3.0'
@@ -81,6 +83,7 @@ def springVersion = '4.3.9.RELEASE'
def spymemcachedVersion = '2.12.3'
def velocityVersion = '1.7'
dependencies.libraries << [
+ bdb_je : "com.sleepycat:je:$bdbjeVersion",
bonecp : "com.jolbox:bonecp:$bonecpVersion",
bouncy_castle : [
"org.bouncycastle:bcprov-jdk15on:$bouncyVersion",
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/879580c3/extensions/entitystore-bdbje/build.gradle
----------------------------------------------------------------------
diff --git a/extensions/entitystore-bdbje/build.gradle b/extensions/entitystore-bdbje/build.gradle
new file mode 100644
index 0000000..ea14aef
--- /dev/null
+++ b/extensions/entitystore-bdbje/build.gradle
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ *
+ *
+ */
+
+apply plugin: 'polygene-extension'
+
+description = "Apache Polygene™ Berkeley DB (Java Edition) EntityStore Extension"
+
+jar { manifest { name = "Apache Polygene™ Extension - EntityStore - BDB/JE" } }
+
+dependencies {
+ api polygene.core.bootstrap
+ api libraries.bdb_je
+ api polygene.library( 'constraints' )
+ api polygene.library( 'fileconfig' )
+
+ implementation polygene.library( 'locking' )
+ implementation libraries.jackson_mapper
+
+ runtimeOnly polygene.core.runtime
+
+ testImplementation polygene.internals.testsupport
+
+ testRuntimeOnly libraries.logback
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/879580c3/extensions/entitystore-bdbje/dev-status.xml
----------------------------------------------------------------------
diff --git a/extensions/entitystore-bdbje/dev-status.xml b/extensions/entitystore-bdbje/dev-status.xml
new file mode 100644
index 0000000..fcc2930
--- /dev/null
+++ b/extensions/entitystore-bdbje/dev-status.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ ~ 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.
+ ~
+ ~
+ -->
+<module xmlns="http://polygene.apache.org/schemas/2008/dev-status/1"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://polygene.apache.org/schemas/2008/dev-status/1
+ http://polygene.apache.org/schemas/2008/dev-status/1/dev-status.xsd">
+ <status>
+ <!--none,early,beta,stable,mature-->
+ <codebase>beta</codebase>
+
+ <!-- none, brief, good, complete -->
+ <documentation>none</documentation>
+
+ <!-- none, some, good, complete -->
+ <unittests>good</unittests>
+ </status>
+ <licenses>
+ <license>ALv2</license>
+ </licenses>
+</module>
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/879580c3/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreActivation.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreActivation.java b/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreActivation.java
new file mode 100644
index 0000000..92b829a
--- /dev/null
+++ b/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreActivation.java
@@ -0,0 +1,59 @@
+/*
+ * 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.polygene.entitystore.bdbje;
+
+import org.apache.polygene.api.activation.ActivatorAdapter;
+import org.apache.polygene.api.activation.Activators;
+import org.apache.polygene.api.service.ServiceReference;
+
+/**
+ * Activation for BdbJeEntityStoreMixin.
+ */
+@Activators( { BdbJeEntityStoreActivation.Activator.class } )
+public interface BdbJeEntityStoreActivation
+{
+
+ void setUpBdbJe()
+ throws Exception;
+
+ void tearDownBdbJe()
+ throws Exception;
+
+ class Activator
+ extends ActivatorAdapter<ServiceReference<BdbJeEntityStoreActivation>>
+ {
+
+ @Override
+ public void afterActivation( ServiceReference<BdbJeEntityStoreActivation> activated )
+ throws Exception
+ {
+ activated.get().setUpBdbJe();
+ }
+
+ @Override
+ public void beforePassivation( ServiceReference<BdbJeEntityStoreActivation> passivating )
+ throws Exception
+ {
+ passivating.get().tearDownBdbJe();
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/879580c3/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreConfiguration.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreConfiguration.java b/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreConfiguration.java
new file mode 100644
index 0000000..82fb682
--- /dev/null
+++ b/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreConfiguration.java
@@ -0,0 +1,383 @@
+/*
+ * 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.polygene.entitystore.bdbje;
+
+import com.sleepycat.je.CacheMode;
+import com.sleepycat.je.Durability;
+import org.apache.polygene.api.common.Optional;
+import org.apache.polygene.api.common.UseDefaults;
+import org.apache.polygene.api.property.Property;
+
+/**
+ * Configuration for the BdbJeEntityStoreService.
+ */
+// START SNIPPET: config
+public interface BdbJeEntityStoreConfiguration
+{
+ /**
+ * Name of the database containing the Polygene entities.
+ */
+ @UseDefaults("polygene")
+ Property<String> databaseName();
+
+ /**
+ * The file where the BDB JE data will be stored
+ * <p>
+ * Default: System.getProperty( "user.dir" ) + "/polygene/bdbjestore.data";
+ * </p>
+ *
+ * @return path to data file relative to current path
+ */
+ @Optional
+ Property<String> homeDirectory();
+
+ /**
+ * If true, creates the database environment if it doesn't already exist.
+ */
+ @UseDefaults("true")
+ Property<Boolean> allowCreate();
+
+ /**
+ * Configures the database environment for no locking.
+ * <p>
+ * If true, create the environment with record locking. This property should be set to false only in special
+ * circumstances when it is safe to run without record locking.
+ * </p>
+ * <p>
+ * This configuration option should be used when locking guarantees such as consistency and isolation are not
+ * important. If locking mode is disabled (it is enabled by default), the cleaner is automatically disabled.
+ * The user is responsible for invoking the cleaner and ensuring that there are no concurrent operations while
+ * the cleaner is running.
+ * </p>
+ */
+ @UseDefaults("true")
+ Property<Boolean> locking();
+
+ /**
+ * Configures the default lock timeout.
+ * <p>
+ * A value of zero disables lock timeouts. This is not recommended, even when the application expects that
+ * deadlocks will not occur or will be easily resolved. A lock timeout is a fall-back that guards against
+ * unexpected "live lock", unresponsive threads, or application failure to close a cursor or to commit or
+ * abort a transaction.
+ * </p>
+ * <p>
+ * Expressed in milliseconds. Default: 500ms
+ * </p>
+ */
+ @UseDefaults("500")
+ Property<Long> lockTimeout();
+
+ /**
+ * Sets the user defined nodeName for the Environment.
+ * <p>
+ * If set, exception messages, logging messages, and thread names will have this nodeName included in them.
+ * If a user has multiple Environments in a single JVM, setting this to a string unique to each Environment
+ * may make it easier to diagnose certain exception conditions as well as thread dumps.
+ * </p>
+ */
+ @Optional
+ Property<String> nodeName();
+
+ /**
+ * Configures the database environment to be read-only, and any attempt to modify a database will fail.
+ * <p>
+ * A read-only environment has several limitations and is recommended only in special circumstances. Note that
+ * there is no performance advantage to opening an environment read-only.
+ * </p>
+ * <p>
+ * The primary reason for opening an environment read-only is to open a single environment in multiple JVM
+ * processes. Only one JVM process at a time may open the environment read-write. See EnvironmentLockedException.
+ * </p>
+ * <p>
+ * When the environment is open read-only, the following limitations apply.
+ * </p>
+ * <p>
+ * In the read-only environment no writes may be performed, as expected, and databases must be opened read-only
+ * using DatabaseConfig.setReadOnly.
+ * </p>
+ * <p>
+ * The read-only environment receives a snapshot of the data that is effectively frozen at the time the environment
+ * is opened. If the application has the environment open read-write in another JVM process and modifies the
+ * environment's databases in any way, the read-only version of the data will not be updated until the read-only
+ * JVM process closes and reopens the environment (and by extension all databases in that environment).
+ * </p>
+ * <p>
+ * If the read-only environment is opened while the environment is in use by another JVM process in read-write mode,
+ * opening the environment read-only (recovery) is likely to take longer than it does after a clean shutdown. This
+ * is due to the fact that the read-write JVM process is writing and checkpoints are occurring that are not
+ * coordinated with the read-only JVM process. The effect is similar to opening an environment after a crash.
+ * </p>
+ * <p>
+ * In a read-only environment, the JE cache will contain information that cannot be evicted because it was
+ * reconstructed by recovery and cannot be flushed to disk. This means that the read-only environment may not be
+ * suitable for operations that use large amounts of memory, and poor performance may result if this is attempted.
+ * </p>
+ * <p>
+ * In a read-write environment, the log cleaner will be prohibited from deleting log files for as long as the
+ * environment is open read-only in another JVM process. This may cause disk usage to rise, and for this reason
+ * it is not recommended that an environment is kept open read-only in this manner for long periods.
+ * </p>
+ * <p>
+ * For these reasons, it is recommended that a read-only environment be used only for short periods and for
+ * operations that are not performance critical or memory intensive. With few exceptions, all application functions
+ * that require access to a JE environment should be built into a single application so that they can be performed
+ * in the JVM process where the environment is open read-write.
+ * </p>
+ * <p>
+ * In most applications, opening an environment read-only can and should be avoided.
+ * </p>
+ */
+ @UseDefaults
+ Property<Boolean> readOnly();
+
+ /**
+ * If true, the shared cache is used by this environment.
+ * <p>
+ * By default this parameter is false and this environment uses a private cache. If this parameter is set to true,
+ * this environment will use a cache that is shared with all other open environments in this process that also set
+ * this parameter to true. There is a single shared cache per process.
+ * </p>
+ * <p>
+ * By using the shared cache, multiple open environments will make better use of memory because the cache LRU
+ * algorithm is applied across all information in all environments sharing the cache. For example, if one
+ * environment is open but not recently used, then it will only use a small portion of the cache, leaving the rest
+ * of the cache for environments that have been recently used.
+ * </p>
+ */
+ @UseDefaults
+ Property<Boolean> sharedCache();
+
+ /**
+ * Configures the use of transactions.
+ * <p>
+ * This should be set to true when transactional guarantees such as atomicity of multiple operations and durability
+ * are important.
+ * </p>
+ * <p>
+ * If true, create an environment that is capable of performing transactions. If true is not passed, transactions
+ * may not be used. For licensing purposes, the use of this method distinguishes the use of the Transactional
+ * product. Note that if transactions are not used, specifying true does not create additional overhead in the
+ * environment.
+ * </p>
+ */
+ @UseDefaults("true")
+ Property<Boolean> transactional();
+
+ /**
+ * The transaction timeout.
+ * <p>
+ * A value of 0 turns off transaction timeouts.
+ * </p>
+ * <p>
+ * Expressed in milliseconds.
+ * </p>
+ */
+ @UseDefaults
+ Property<Long> txnTimeout();
+
+ /**
+ * Configures all transactions for this environment to have Serializable (Degree 3) isolation.
+ * <p>
+ * By setting Serializable isolation, phantoms will be prevented. By default transactions provide Repeatable Read
+ * isolation. The default is false for the database environment.
+ * </p>
+ */
+ @UseDefaults
+ Property<Boolean> txnSerializableIsolation();
+
+ /**
+ * The default CacheMode used for operations performed in this environment.
+ * <p>
+ * The default cache mode may be overridden on a per-database basis using DatabaseConfig.setCacheMode, and on a
+ * per-record or per-operation basis using Cursor.setCacheMode, ReadOptions.setCacheMode(CacheMode) or
+ * WriteOptions.setCacheMode(CacheMode).
+ * </p>
+ */
+ @UseDefaults("DEFAULT")
+ Property<CacheMode> cacheMode();
+
+ /**
+ * Configures the memory available to the database system, as a percentage of the JVM maximum memory.
+ * <p>
+ * The system will evict database objects when it comes within a prescribed margin of the limit.
+ * </p>
+ * <p>
+ * By default, JE sets the cache size to:
+ * </p>
+ * <p>
+ * <code>(MAX_MEMORY_PERCENT * JVM maximum memory) / 100</code>
+ * </p>
+ * <p>
+ * where JVM maximum memory is specified by the JVM -Xmx flag. However, setting MAX_MEMORY to a non-zero value
+ * overrides the percentage based calculation and sets the cache size explicitly.
+ * </p>
+ * <p>
+ * The following details apply to setting the cache size to a percentage of the JVM heap size byte size (this
+ * parameter) as well as to a byte size (MAX_MEMORY
+ * </p>
+ * <p>
+ * Note that the log buffer cache may be cleared if the cache size is changed after the environment has been opened.
+ * </p>
+ * <p>
+ * If SHARED_CACHE is set to true, MAX_MEMORY and MAX_MEMORY_PERCENT specify the total size of the shared cache,
+ * and changing these parameters will change the size of the shared cache.
+ * </p>
+ * <p>
+ * When using the shared cache feature, new environments that join the cache may alter the cache percent setting
+ * if their configuration is set to a different value.
+ * </p>
+ * <p>
+ * To take full advantage of JE cache memory, it is strongly recommended that compressed oops
+ * (-XX:+UseCompressedOops) is specified when a 64-bit JVM is used and the maximum heap size is less than 32 GB.
+ * As described in the referenced documentation, compressed oops is sometimes the default JVM mode even when it is
+ * not explicitly specified in the Java command. However, if compressed oops is desired then it must be explicitly
+ * specified in the Java command when running DbCacheSize or a JE application. If it is not explicitly specified
+ * then JE will not aware of it, even if it is the JVM default setting, and will not take it into account when
+ * calculating cache memory sizes.
+ * </p>
+ */
+ @UseDefaults("60")
+ Property<Integer> cachePercent();
+
+ /**
+ * Configures the memory available to the database system, in bytes.
+ * <p>
+ * See MAX_MEMORY_PERCENT for more information.
+ * </p>
+ */
+ @UseDefaults
+ Property<Long> cacheSize();
+
+ /**
+ * Configures the number of bytes to be used as a secondary, off-heap cache.
+ * <p>
+ * The off-heap cache is used to hold record data and Btree nodes when these are evicted from the "main cache"
+ * because it overflows. Eviction occurs according to an LRU algorithm and takes into account the user- specified
+ * CacheMode. When the off-heap cache overflows, eviction occurs there also according to the same algorithm.
+ * </p>
+ * <p>
+ * The main cache is in the Java heap and consists primarily of the Java objects making up the in-memory Btree
+ * data structure. Btree objects are not serialized the main cache, so no object materialization is needed to
+ * access the Btree there. Access to records in the main cache is therefore very fast, but the main cache has
+ * drawbacks as well:
+ * <ol>
+ * <li>
+ * The larger the main cache, the more likely it is to have Java GC performance problems.
+ * </li>
+ * <li>
+ * When the Java heap exceeds 32GB, the "compressed OOPs" setting no longer applies and less data will fit in the
+ * same amount of memory. For these reasons, JE applications often configure a heap of 32GB or less, and a main
+ * cache that is significantly less than 32GB, leaving any additional machine memory for use by the file system
+ * cache.
+ * </li>
+ * </ol>
+ * </p>
+ * <p>
+ * The use of the file system cache has performance benefits, but also has its own drawbacks:
+ * <ol>
+ * <li>
+ * There is a significant redundancy between the main cache and the file system cache because all data and Btree
+ * information that is logged (written) by JE appears in the file system and may also appear in the main cache.
+ * </li>
+ * <li>
+ * It is not possible for dirty Btree information to be placed in the file system cache without logging it, this
+ * logging may be otherwise unnecessary, and the logging creates additional work for the JE cleaner; in other
+ * words, the size of the main cache alone determines the maximum size of the in-memory "dirty set".
+ * </li>
+ * </ol>
+ * </p>
+ * <p>
+ * The off-heap cache is stored outside the Java heap using a native platform memory allocator. The current
+ * implementation relies on internals that are specific to the Oracle and IBM JDKs; however, a memory allocator
+ * interface that can be implemented for other situations is being considered for a future release. Records and
+ * Btree objects are serialized when they are placed in the off-heap cache, and they must be materialized when
+ * they are moved back to the main cache in order to access them. This serialization and materialization adds
+ * some CPU overhead and thread contention, as compared to accessing data directly in the main cache. The off-heap
+ * cache can contain dirty Btree information, so it can be used to increase the maximum size of the in-memory
+ * "dirty set".
+ * </p>
+ * <p>
+ * NOTE: If an off-heap cache is configured but cannot be used because that native allocator is not available in
+ * the JDK that is used, an IllegalStateException will be thrown by the Environment or
+ * com.sleepycat.je.rep.ReplicatedEnvironment constructor. In the current release, this means that the
+ * sun.misc.Unsafe class must contain the allocateMemory method and related methods, as defined in the Oracle JDK.
+ * </p>
+ * <p>
+ * When configuring an off-heap cache you can think of the performance trade-offs in two ways. First, if the
+ * off-heap cache is considered to be a replacement for the file system cache, the serialization and
+ * materialization overhead is not increased. In this case, the use of the off-heap cache is clearly beneficial,
+ * and using the off-heap cache "instead of" the file system cache is normally recommended. Second, the off-heap
+ * cache can be used along with a main cache that is reduced in size in order to compensate for Java GC problems.
+ * In this case, the trade-off is between the additional serialization, materialization and contention overheads
+ * of the off-heap cache, as compared to the Java GC overhead.
+ * </p>
+ * <p>
+ * When dividing up available memory for the JVM heap, the off-heap cache, and for other uses, please be aware
+ * that the file system cache and the off-heap cache are different in one important respect. The file system cache
+ * automatically shrinks when memory is needed by the OS or other processes, while the off-heap cache does not.
+ * Therefore, it is best to be conservative about leaving memory free for other uses, and it is not a good idea to
+ * size the off-heap cache such that all machine memory will be allocated. If off-heap allocations or other
+ * allocations fail because there is no available memory, the process is likely to die without any exception
+ * being thrown. In one test on Linux, for example, the process was killed abruptly by the OS and the only
+ * indication of the problem was the following shown by dmesg.
+ * </p>
+ * <pre><code>
+ * Out of memory: Kill process 28768 (java) score 974 or sacrifice child
+ * Killed process 28768 (java)
+ * total-vm:278255336kB, anon-rss:257274420kB, file-rss:0kB
+ * </code></pre>
+ * WARNING: Although this configuration property is mutable, it cannot be changed from zero to non-zero, or
+ * non-zero to zero. In other words, the size of the off-heap cache can be changed after initially configuring
+ * a non-zero size, but the off-heap cache cannot be turned on and off dynamically. An attempt to do so will
+ * cause an IllegalArgumentException to be thrown by the Environment or com.sleepycat.je.rep.ReplicatedEnvironment
+ * constructor.
+ */
+ @UseDefaults
+ Property<Long> cacheHeapCacheSize();
+
+ /**
+ * Configures the default durability associated with transactions.
+ * <p>
+ * The string must have the following format:
+ * </p>
+ * <pre><code>
+ * SyncPolicy[,SyncPolicy[,ReplicaAckPolicy]]
+ * </code></pre>
+ * <p>
+ * The first SyncPolicy in the above format applies to the Master, and the optional second SyncPolicy to the
+ * replica. Specific SyncPolicy or ReplicaAckPolicy values are denoted by the name of the enumeration value.
+ * </p>
+ * <p>
+ * For example, the string:sync,sync,quorum describes a durability policy where the master and replica both use
+ * Durability.SyncPolicy.SYNC to commit transactions and Durability.ReplicaAckPolicy.SIMPLE_MAJORITY to acknowledge
+ * a transaction commit.
+ * </p>
+ * <p>
+ * Durability.SyncPolicy.NO_SYNC, is the default value for a node's SyncPolicy.
+ * </p>
+ * <p>
+ * Durability.ReplicaAckPolicy.SIMPLE_MAJORITY is the default for the ReplicaAckPolicy.
+ * </p>
+ */
+ @Optional
+ Property<String> durability();
+}
+// END SNIPPET: config
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/879580c3/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreMixin.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreMixin.java b/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreMixin.java
new file mode 100644
index 0000000..8459161
--- /dev/null
+++ b/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreMixin.java
@@ -0,0 +1,342 @@
+/*
+ * 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.polygene.entitystore.bdbje;
+
+import com.sleepycat.je.Cursor;
+import com.sleepycat.je.Database;
+import com.sleepycat.je.DatabaseConfig;
+import com.sleepycat.je.DatabaseEntry;
+import com.sleepycat.je.DatabaseException;
+import com.sleepycat.je.Durability;
+import com.sleepycat.je.Environment;
+import com.sleepycat.je.EnvironmentConfig;
+import com.sleepycat.je.LockMode;
+import com.sleepycat.je.OperationStatus;
+import com.sleepycat.je.Transaction;
+import com.sleepycat.je.TransactionConfig;
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.Iterator;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import org.apache.polygene.api.common.Optional;
+import org.apache.polygene.api.configuration.Configuration;
+import org.apache.polygene.api.entity.EntityDescriptor;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.injection.scope.Service;
+import org.apache.polygene.api.injection.scope.This;
+import org.apache.polygene.api.injection.scope.Uses;
+import org.apache.polygene.api.service.ServiceDescriptor;
+import org.apache.polygene.library.fileconfig.FileConfiguration;
+import org.apache.polygene.library.locking.ReadLock;
+import org.apache.polygene.library.locking.WriteLock;
+import org.apache.polygene.spi.entitystore.EntityNotFoundException;
+import org.apache.polygene.spi.entitystore.EntityStoreException;
+import org.apache.polygene.spi.entitystore.helpers.MapEntityStore;
+
+/**
+ * BDB JE implementation of MapEntityStore.
+ */
+public class BdbJeEntityStoreMixin
+ implements BdbJeEntityStoreActivation, MapEntityStore
+{
+ @Optional
+ @Service
+ private FileConfiguration fileConfiguration;
+
+ @This
+ private Configuration<BdbJeEntityStoreConfiguration> config;
+
+ @Uses
+ private ServiceDescriptor descriptor;
+
+ private Database database;
+ private Environment envHandle;
+
+ @Override
+ public void setUpBdbJe()
+ throws Exception
+ {
+ initialize();
+ }
+
+ @Override
+ public void tearDownBdbJe()
+ throws Exception
+ {
+ closeDown();
+ }
+
+ @ReadLock
+ @Override
+ public Reader get( EntityReference entityReference )
+ throws EntityStoreException
+ {
+ try
+ {
+ String indexKey = entityReference.toString();
+ DatabaseEntry key = new DatabaseEntry( indexKey.getBytes( "UTF-8" ) );
+ DatabaseEntry result = new DatabaseEntry();
+ OperationStatus operationStatus = database.get( null, key, result, LockMode.DEFAULT );
+ if( operationStatus == OperationStatus.NOTFOUND )
+ {
+ throw new EntityNotFoundException( entityReference );
+ }
+ return new StringReader( new String( result.getData(), "UTF-8" ) );
+ }
+ catch( IOException e )
+ {
+ throw new EntityStoreException( e );
+ }
+ }
+
+ @WriteLock
+ @Override
+ public void applyChanges( MapChanges changes )
+ throws IOException
+ {
+ Transaction transaction = envHandle.beginTransaction( null, TransactionConfig.DEFAULT );
+ try
+ {
+ changes.visitMap( new MapChanger()
+ {
+ @Override
+ public Writer newEntity( EntityReference ref, EntityDescriptor descriptor )
+ throws IOException
+ {
+ return new StringWriter( 1000 )
+ {
+ @Override
+ public void close()
+ throws IOException
+ {
+ super.close();
+ String indexKey = ref.toString();
+ DatabaseEntry theKey = new DatabaseEntry( indexKey.getBytes( "UTF-8" ) );
+ DatabaseEntry theData = new DatabaseEntry( toString().getBytes( "UTF-8" ) );
+ database.put( transaction, theKey, theData );
+ }
+ };
+ }
+
+ @Override
+ public Writer updateEntity( MapChange mapChange )
+ throws IOException
+ {
+ return new StringWriter( 1000 )
+ {
+ @Override
+ public void close()
+ throws IOException
+ {
+ super.close();
+ String indexKey = mapChange.reference().identity().toString();
+ DatabaseEntry theKey = new DatabaseEntry( indexKey.getBytes( "UTF-8" ) );
+ DatabaseEntry theData = new DatabaseEntry( toString().getBytes( "UTF-8" ) );
+ database.put( transaction, theKey, theData );
+ }
+ };
+ }
+
+ @Override
+ public void removeEntity( EntityReference ref, EntityDescriptor descriptor )
+ throws EntityNotFoundException
+ {
+ try
+ {
+ String indexKey = ref.toString();
+ DatabaseEntry theKey = new DatabaseEntry( indexKey.getBytes( "UTF-8" ) );
+ database.delete( transaction, theKey );
+ }
+ catch( IOException e )
+ {
+ throw new EntityStoreException( e );
+ }
+ }
+ } );
+ transaction.commit();
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ transaction.abort();
+ if( ( e instanceof IOException ) )
+ {
+ throw (IOException) e;
+ }
+ else if( !( e instanceof EntityStoreException ) )
+ {
+ throw new IOException( e );
+ }
+ else
+ {
+ throw (EntityStoreException) e;
+ }
+ }
+ }
+
+ @Override
+ public Stream<Reader> entityStates()
+ throws IOException
+ {
+ return StreamSupport.stream( new RecordIterable( database ).spliterator(), false );
+ }
+
+ private File getDatabaseHome()
+ {
+ String pathname = config.get().homeDirectory().get();
+ if( pathname == null )
+ {
+ if( fileConfiguration != null )
+ {
+ File dataDir = fileConfiguration.dataDirectory();
+ File bdbJeDir = new File( dataDir, descriptor.identity() + "/bdbje_data" );
+ pathname = bdbJeDir.getAbsolutePath();
+ }
+ else
+ {
+ pathname = System.getProperty( "user.dir" ) + "/polygene/bdbje_data";
+ }
+ }
+
+ File directory = new File( pathname ).getAbsoluteFile();
+ //noinspection ResultOfMethodCallIgnored
+ directory.mkdirs();
+ return directory;
+ }
+
+ private void closeDown()
+ {
+ if( database != null )
+ {
+ database.close();
+ }
+ if( envHandle != null )
+ {
+ envHandle.close();
+ }
+ }
+
+ private void initialize()
+ throws IOException
+ {
+ File homeDir = getDatabaseHome();
+ EnvironmentConfig configuration = createConfiguration();
+
+ envHandle = new Environment( homeDir, configuration );
+ DatabaseConfig dbConfig = new DatabaseConfig();
+ dbConfig.setAllowCreate( configuration.getAllowCreate() );
+ dbConfig.setTransactional( configuration.getTransactional() );
+ database = envHandle.openDatabase( null, config.get().databaseName().get(), dbConfig );
+ }
+
+ private EnvironmentConfig createConfiguration()
+ {
+ EnvironmentConfig environmentConfig = new EnvironmentConfig();
+ BdbJeEntityStoreConfiguration storeConfiguration = config.get();
+ Boolean allowCreate = storeConfiguration.allowCreate().get();
+ environmentConfig.setAllowCreate( allowCreate );
+ environmentConfig.setLocking( storeConfiguration.locking().get() );
+ environmentConfig.setLockTimeout( storeConfiguration.lockTimeout().get(), TimeUnit.MILLISECONDS );
+ environmentConfig.setNodeName( storeConfiguration.nodeName().get() );
+ environmentConfig.setReadOnly( storeConfiguration.readOnly().get() );
+ environmentConfig.setSharedCache( storeConfiguration.sharedCache().get() );
+ environmentConfig.setTransactional( storeConfiguration.transactional().get() );
+ environmentConfig.setTxnTimeout( storeConfiguration.txnTimeout().get(), TimeUnit.MILLISECONDS );
+ environmentConfig.setTxnSerializableIsolation( storeConfiguration.txnSerializableIsolation().get() );
+ environmentConfig.setCacheMode( storeConfiguration.cacheMode().get() );
+ environmentConfig.setCachePercent( storeConfiguration.cachePercent().get() );
+ environmentConfig.setCacheSize( storeConfiguration.cacheSize().get() );
+ environmentConfig.setOffHeapCacheSize( storeConfiguration.cacheHeapCacheSize().get() );
+ environmentConfig.setDurability( Durability.parse( storeConfiguration.durability().get() ) );
+ return environmentConfig;
+ }
+
+ private static class RecordIterable
+ implements Iterable<Reader>, Iterator<Reader>
+ {
+ private Cursor cursor;
+ private DatabaseEntry foundKey;
+ private DatabaseEntry foundData;
+ private boolean success;
+
+ private RecordIterable( Database db )
+ throws IOException
+ {
+ try
+ {
+ cursor = db.openCursor( null, null );
+ foundKey = new DatabaseEntry();
+ foundData = new DatabaseEntry();
+ }
+ catch( DatabaseException e )
+ {
+ throw new IOException( "Unknown problem in Berkeley DB", e );
+ }
+ }
+
+ @Override
+ @SuppressWarnings( "NullableProblems" )
+ public Iterator<Reader> iterator()
+ {
+ forward();
+ return this;
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return success;
+ }
+
+ @Override
+ public Reader next()
+ {
+ byte[] data = foundData.getData();
+ forward();
+ try
+ {
+ return new StringReader( new String( data, "UTF-8" ) );
+ }
+ catch( UnsupportedEncodingException e )
+ {
+ // can not happen.
+ return new StringReader( "" );
+ }
+ }
+
+ private void forward()
+ {
+ OperationStatus status = cursor.getNext( foundKey, foundData, LockMode.DEFAULT );
+ if( status == OperationStatus.NOTFOUND )
+ {
+ // End of Cursor, and need to close.
+ cursor.close();
+ }
+ success = status == OperationStatus.SUCCESS;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/879580c3/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreService.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreService.java b/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreService.java
new file mode 100644
index 0000000..a45994f
--- /dev/null
+++ b/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreService.java
@@ -0,0 +1,52 @@
+/*
+ * 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.polygene.entitystore.bdbje;
+
+import org.apache.polygene.api.concern.Concerns;
+import org.apache.polygene.api.configuration.Configuration;
+import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.library.locking.LockingAbstractComposite;
+import org.apache.polygene.library.locking.ReadLockConcern;
+import org.apache.polygene.library.locking.WriteLockConcern;
+import org.apache.polygene.spi.entitystore.BackupRestore;
+import org.apache.polygene.spi.entitystore.ConcurrentModificationCheckConcern;
+import org.apache.polygene.spi.entitystore.EntityStateVersions;
+import org.apache.polygene.spi.entitystore.EntityStore;
+import org.apache.polygene.spi.entitystore.StateChangeNotificationConcern;
+import org.apache.polygene.spi.entitystore.helpers.JSONMapEntityStoreActivation;
+import org.apache.polygene.spi.entitystore.helpers.JSONMapEntityStoreMixin;
+import org.apache.polygene.spi.entitystore.helpers.StateStore;
+
+/**
+ * EntityStore service backed by BDB JE store.
+ * <p>Based on @{@link JSONMapEntityStoreMixin}.</p>
+ */
+@Concerns( { StateChangeNotificationConcern.class, ConcurrentModificationCheckConcern.class, ReadLockConcern.class, WriteLockConcern.class } )
+@Mixins( { JSONMapEntityStoreMixin.class, BdbJeEntityStoreMixin.class } )
+public interface BdbJeEntityStoreService
+ extends BdbJeEntityStoreActivation,
+ JSONMapEntityStoreActivation,
+ EntityStore,
+ EntityStateVersions,
+ StateStore,
+ LockingAbstractComposite,
+ Configuration<BdbJeEntityStoreConfiguration>
+{
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/879580c3/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/assembly/BdbJeEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/assembly/BdbJeEntityStoreAssembler.java b/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/assembly/BdbJeEntityStoreAssembler.java
new file mode 100644
index 0000000..db029a3
--- /dev/null
+++ b/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/assembly/BdbJeEntityStoreAssembler.java
@@ -0,0 +1,45 @@
+/*
+ * 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.polygene.entitystore.bdbje.assembly;
+
+import org.apache.polygene.bootstrap.Assemblers;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.bootstrap.ServiceDeclaration;
+import org.apache.polygene.entitystore.bdbje.BdbJeEntityStoreConfiguration;
+import org.apache.polygene.entitystore.bdbje.BdbJeEntityStoreService;
+
+public class BdbJeEntityStoreAssembler
+ extends Assemblers.VisibilityIdentityConfig<BdbJeEntityStoreAssembler>
+{
+ @Override
+ public void assemble( ModuleAssembly module )
+ {
+ super.assemble( module );
+ ServiceDeclaration service = module.services( BdbJeEntityStoreService.class ).visibleIn( visibility() );
+ if( hasIdentity() )
+ {
+ service.identifiedBy( identity() );
+ }
+ if( hasConfig() )
+ {
+ configModule().entities( BdbJeEntityStoreConfiguration.class ).visibleIn( configVisibility() );
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/879580c3/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/assembly/package.html
----------------------------------------------------------------------
diff --git a/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/assembly/package.html b/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/assembly/package.html
new file mode 100644
index 0000000..298493f
--- /dev/null
+++ b/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/assembly/package.html
@@ -0,0 +1,24 @@
+<!--
+ ~ 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.
+ ~
+ ~
+ -->
+<html>
+ <body>
+ <h2>Berkeley DB (Java Edition) EntityStore Assembly.</h2>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/879580c3/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/package.html
----------------------------------------------------------------------
diff --git a/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/package.html b/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/package.html
new file mode 100644
index 0000000..17b4142
--- /dev/null
+++ b/extensions/entitystore-bdbje/src/main/java/org/apache/polygene/entitystore/bdbje/package.html
@@ -0,0 +1,24 @@
+<!--
+ ~ 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.
+ ~
+ ~
+ -->
+<html>
+ <body>
+ <h2>Berkley DB (Java Edition) EntityStore.</h2>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/879580c3/extensions/entitystore-bdbje/src/test/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-bdbje/src/test/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreTest.java b/extensions/entitystore-bdbje/src/test/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreTest.java
new file mode 100644
index 0000000..c2a590f
--- /dev/null
+++ b/extensions/entitystore-bdbje/src/test/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.polygene.entitystore.bdbje;
+
+import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.bootstrap.AssemblyException;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.bdbje.assembly.BdbJeEntityStoreAssembler;
+import org.apache.polygene.library.fileconfig.FileConfigurationAssembler;
+import org.apache.polygene.library.fileconfig.FileConfigurationOverride;
+import org.apache.polygene.test.EntityTestAssembler;
+import org.apache.polygene.test.entity.AbstractEntityStoreTest;
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+
+public class BdbJeEntityStoreTest
+ extends AbstractEntityStoreTest
+{
+ @Rule
+ public final TemporaryFolder tmpDir = new TemporaryFolder();
+
+ @Override
+ public void assemble( ModuleAssembly module )
+ throws AssemblyException
+ {
+ super.assemble( module );
+
+ ModuleAssembly config = module.layer().module( "config" );
+ new EntityTestAssembler().defaultServicesVisibleIn( Visibility.layer ).assemble( config );
+
+ new FileConfigurationAssembler()
+ .withOverride( new FileConfigurationOverride().withConventionalRoot( tmpDir.getRoot() ) )
+ .assemble( module );
+ new BdbJeEntityStoreAssembler().withConfig( config, Visibility.layer ).assemble( module );
+ }
+
+ @After
+ public void cleanup()
+ {
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/879580c3/extensions/entitystore-bdbje/src/test/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-bdbje/src/test/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreTestSuite.java b/extensions/entitystore-bdbje/src/test/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreTestSuite.java
new file mode 100644
index 0000000..6fb54bd
--- /dev/null
+++ b/extensions/entitystore-bdbje/src/test/java/org/apache/polygene/entitystore/bdbje/BdbJeEntityStoreTestSuite.java
@@ -0,0 +1,47 @@
+/*
+ * 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.polygene.entitystore.bdbje;
+
+import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.bdbje.assembly.BdbJeEntityStoreAssembler;
+import org.apache.polygene.library.fileconfig.FileConfigurationAssembler;
+import org.apache.polygene.library.fileconfig.FileConfigurationOverride;
+import org.apache.polygene.test.entity.model.EntityStoreTestSuite;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+
+public class BdbJeEntityStoreTestSuite extends EntityStoreTestSuite
+{
+ @Rule
+ public final TemporaryFolder tmpDir = new TemporaryFolder();
+
+ @Override
+ protected void defineStorageModule( ModuleAssembly module )
+ {
+ module.defaultServices();
+ new FileConfigurationAssembler()
+ .withOverride( new FileConfigurationOverride().withConventionalRoot( tmpDir.getRoot() ) )
+ .assemble( module );
+ new BdbJeEntityStoreAssembler().visibleIn( Visibility.application )
+ .withConfig( configModule, Visibility.application )
+ .assemble( module );
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/879580c3/settings.gradle
----------------------------------------------------------------------
diff --git a/settings.gradle b/settings.gradle
index 3a4067c..3fa0179 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -55,6 +55,7 @@ include 'core:api',
'libraries:uowfile',
'extensions:cache-ehcache',
'extensions:cache-memcache',
+ 'extensions:entitystore-bdbje',
'extensions:entitystore-cassandra',
'extensions:entitystore-file',
'extensions:entitystore-geode',