!per #15884 Make LevelDB an optional dependency

This commit is contained in:
Andrei Pozolotin 2015-03-06 11:58:51 -06:00
parent 1313fb736d
commit 5c5e07ec4e
13 changed files with 196 additions and 56 deletions

View file

@ -41,6 +41,7 @@ object ClusterShardingFailureSpec extends MultiNodeConfig {
dir = "target/journal-ClusterShardingFailureSpec" dir = "target/journal-ClusterShardingFailureSpec"
} }
} }
akka.persistence.snapshot-store.plugin = "akka.persistence.snapshot-store.local"
akka.persistence.snapshot-store.local.dir = "target/snapshots-ClusterShardingFailureSpec" akka.persistence.snapshot-store.local.dir = "target/snapshots-ClusterShardingFailureSpec"
akka.contrib.cluster.sharding.coordinator-failure-backoff = 3s akka.contrib.cluster.sharding.coordinator-failure-backoff = 3s
akka.contrib.cluster.sharding.shard-failure-backoff = 3s akka.contrib.cluster.sharding.shard-failure-backoff = 3s

View file

@ -44,6 +44,7 @@ object ClusterShardingSpec extends MultiNodeConfig {
native = off native = off
dir = "target/journal-ClusterShardingSpec" dir = "target/journal-ClusterShardingSpec"
} }
akka.persistence.snapshot-store.plugin = "akka.persistence.snapshot-store.local"
akka.persistence.snapshot-store.local.dir = "target/snapshots-ClusterShardingSpec" akka.persistence.snapshot-store.local.dir = "target/snapshots-ClusterShardingSpec"
akka.contrib.cluster.sharding { akka.contrib.cluster.sharding {
role = backend role = backend

View file

@ -48,6 +48,22 @@ Akka persistence is a separate jar file. Make sure that you have the following d
<version>@version@</version> <version>@version@</version>
</dependency> </dependency>
Akka persistence extension comes with few built-in persistence plugins, including
in-memory heap based journal, local file-system based snapshot-store and LevelDB based journal.
LevelDB based plugins will require the following additional dependency declaration::
<dependency>
<groupId>org.iq80.leveldb</groupId>
<artifactId>leveldb</artifactId>
<version>0.7</version>
</dependency>
<dependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-all</artifactId>
<version>1.7</version>
</dependency>
Architecture Architecture
============ ============
@ -64,18 +80,19 @@ Architecture
case of sender and receiver JVM crashes. case of sender and receiver JVM crashes.
* *Journal*: A journal stores the sequence of messages sent to a persistent actor. An application can control which messages * *Journal*: A journal stores the sequence of messages sent to a persistent actor. An application can control which messages
are journaled and which are received by the persistent actor without being journaled. The storage backend of a journal is are journaled and which are received by the persistent actor without being journaled. The storage backend of a journal is pluggable.
pluggable. The default journal storage plugin writes to the local filesystem, replicated journals are available as Persistence extension comes with a "leveldb" journal plugin, which writes to the local filesystem,
`Community plugins`_. and replicated journals are available as `Community plugins`_.
* *Snapshot store*: A snapshot store persists snapshots of a persistent actor's or a view's internal state. Snapshots are * *Snapshot store*: A snapshot store persists snapshots of a persistent actor's or a view's internal state. Snapshots are
used for optimizing recovery times. The storage backend of a snapshot store is pluggable. The default snapshot used for optimizing recovery times. The storage backend of a snapshot store is pluggable.
storage plugin writes to the local filesystem. Persistence extension comes with a "local" snapshot storage plugin, which writes to the local filesystem,
and replicated snapshot stores are available as `Community plugins`_.
* *Event sourcing*. Based on the building blocks described above, Akka persistence provides abstractions for the * *Event sourcing*. Based on the building blocks described above, Akka persistence provides abstractions for the
development of event sourced applications (see section :ref:`event-sourcing-java-lambda`) development of event sourced applications (see section :ref:`event-sourcing-java-lambda`)
.. _Community plugins: https://gist.github.com/krasserm/8612920#file-akka-persistence-plugins-md .. _Community plugins: http://akka.io/community/
.. _event-sourcing-java-lambda: .. _event-sourcing-java-lambda:
@ -474,11 +491,25 @@ configuration key. The method can be overridden by implementation classes to ret
Storage plugins Storage plugins
=============== ===============
Storage backends for journals and snapshot stores are pluggable in Akka persistence. The default journal plugin Storage backends for journals and snapshot stores are pluggable in the Akka persistence extension.
writes messages to LevelDB (see :ref:`local-leveldb-journal-java-lambda`). The default snapshot store plugin writes
snapshots as individual files to the local filesystem (see :ref:`local-snapshot-store-java-lambda`). Applications can Directory of persistence journal and snapshot store plugins is available at the Akka Community Projects page, see `Community plugins`_
provide their own plugins by implementing a plugin API and activate them by configuration. Plugin development
requires the following imports: Plugins can be selected either by "default", for all persistent actors and views,
or "individually", when persistent actor or view defines it's own set of plugins.
When persistent actor or view does NOT override ``journalPluginId`` and ``snapshotPluginId`` methods,
persistense extension will use "default" journal and snapshot-store plugins configured in the ``reference.conf``::
akka.persistence.journal.plugin = ""
akka.persistence.snapshot-store.plugin = ""
However, these entires are provided as empty "", and require explicit user configuration via override in the user ``application.conf``.
For an example of journal plugin which writes messages to LevelDB see :ref:`local-leveldb-journal-java-lambda`.
For an example of snapshot store plugin which writes snapshots as individual files to the local filesystem see :ref:`local-snapshot-store-java-lambda`.
Applications can provide their own plugins by implementing a plugin API and activate them by configuration.
Plugin development requires the following imports:
.. includecode:: ../../../akka-samples/akka-sample-persistence-java-lambda/src/main/java/doc/LambdaPersistencePluginDocTest.java#plugin-imports .. includecode:: ../../../akka-samples/akka-sample-persistence-java-lambda/src/main/java/doc/LambdaPersistencePluginDocTest.java#plugin-imports
@ -530,7 +561,7 @@ Pre-packaged plugins
Local LevelDB journal Local LevelDB journal
--------------------- ---------------------
The default journal plugin is ``akka.persistence.journal.leveldb`` which writes messages to a local LevelDB LevelDB journal plugin config entry is ``akka.persistence.journal.leveldb`` and it writes messages to a local LevelDB
instance. The default location of the LevelDB files is a directory named ``journal`` in the current working instance. The default location of the LevelDB files is a directory named ``journal`` in the current working
directory. This location can be changed by configuration where the specified path can be relative or absolute: directory. This location can be changed by configuration where the specified path can be relative or absolute:
@ -579,7 +610,7 @@ i.e. only the first injection is used.
Local snapshot store Local snapshot store
-------------------- --------------------
The default snapshot store plugin is ``akka.persistence.snapshot-store.local``. It writes snapshot files to Local snapshot store plugin config entry is ``akka.persistence.snapshot-store.local`` and it writes snapshot files to
the local filesystem. The default storage location is a directory named ``snapshots`` in the current working the local filesystem. The default storage location is a directory named ``snapshots`` in the current working
directory. This can be changed by configuration where the specified path can be relative or absolute: directory. This can be changed by configuration where the specified path can be relative or absolute:

View file

@ -4,7 +4,6 @@
Persistence Persistence
########### ###########
Akka persistence enables stateful actors to persist their internal state so that it can be recovered when an actor Akka persistence enables stateful actors to persist their internal state so that it can be recovered when an actor
is started, restarted after a JVM crash or by a supervisor, or migrated in a cluster. The key concept behind Akka is started, restarted after a JVM crash or by a supervisor, or migrated in a cluster. The key concept behind Akka
persistence is that only changes to an actor's internal state are persisted but never its current state directly persistence is that only changes to an actor's internal state are persisted but never its current state directly
@ -53,6 +52,22 @@ Akka persistence is a separate jar file. Make sure that you have the following d
<version>@version@</version> <version>@version@</version>
</dependency> </dependency>
Akka persistence extension comes with few built-in persistence plugins, including
in-memory heap based journal, local file-system based snapshot-store and LevelDB based journal.
LevelDB based plugins will require the following additional dependency declaration::
<dependency>
<groupId>org.iq80.leveldb</groupId>
<artifactId>leveldb</artifactId>
<version>0.7</version>
</dependency>
<dependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-all</artifactId>
<version>1.7</version>
</dependency>
Architecture Architecture
============ ============
@ -69,13 +84,14 @@ Architecture
case of sender and receiver JVM crashes. case of sender and receiver JVM crashes.
* *Journal*: A journal stores the sequence of messages sent to a persistent actor. An application can control which messages * *Journal*: A journal stores the sequence of messages sent to a persistent actor. An application can control which messages
are journaled and which are received by the persistent actor without being journaled. The storage backend of a journal is are journaled and which are received by the persistent actor without being journaled. The storage backend of a journal is pluggable.
pluggable. The default journal storage plugin writes to the local filesystem, replicated journals are available as Persistence extension comes with a "leveldb" journal plugin, which writes to the local filesystem,
`Community plugins`_. and replicated journals are available as `Community plugins`_.
* *Snapshot store*: A snapshot store persists snapshots of a persistent actor's or a view's internal state. Snapshots are * *Snapshot store*: A snapshot store persists snapshots of a persistent actor's or a view's internal state. Snapshots are
used for optimizing recovery times. The storage backend of a snapshot store is pluggable. The default snapshot used for optimizing recovery times. The storage backend of a snapshot store is pluggable.
storage plugin writes to the local filesystem. Persistence extension comes with a "local" snapshot storage plugin, which writes to the local filesystem,
and replicated snapshot stores are available as `Community plugins`_.
.. _Community plugins: http://akka.io/community/ .. _Community plugins: http://akka.io/community/
@ -486,11 +502,25 @@ configuration key. The method can be overridden by implementation classes to ret
Storage plugins Storage plugins
=============== ===============
Storage backends for journals and snapshot stores are pluggable in Akka persistence. The default journal plugin Storage backends for journals and snapshot stores are pluggable in the Akka persistence extension.
writes messages to LevelDB (see :ref:`local-leveldb-journal-java`). The default snapshot store plugin writes snapshots
as individual files to the local filesystem (see :ref:`local-snapshot-store-java`). Applications can provide their own Directory of persistence journal and snapshot store plugins is available at the Akka Community Projects page, see `Community plugins`_
plugins by implementing a plugin API and activate them by configuration. Plugin development requires the following
imports: Plugins can be selected either by "default", for all persistent actors and views,
or "individually", when persistent actor or view defines it's own set of plugins.
When persistent actor or view does NOT override ``journalPluginId`` and ``snapshotPluginId`` methods,
persistense extension will use "default" journal and snapshot-store plugins configured in the ``reference.conf``::
akka.persistence.journal.plugin = ""
akka.persistence.snapshot-store.plugin = ""
However, these entires are provided as empty "", and require explicit user configuration via override in the user ``application.conf``.
For an example of journal plugin which writes messages to LevelDB see :ref:`local-leveldb-journal-java`.
For an example of snapshot store plugin which writes snapshots as individual files to the local filesystem see :ref:`local-snapshot-store-java`.
Applications can provide their own plugins by implementing a plugin API and activate them by configuration.
Plugin development requires the following imports:
.. includecode:: code/docs/persistence/PersistencePluginDocTest.java#plugin-imports .. includecode:: code/docs/persistence/PersistencePluginDocTest.java#plugin-imports
@ -576,7 +606,7 @@ Pre-packaged plugins
Local LevelDB journal Local LevelDB journal
--------------------- ---------------------
The default journal plugin is ``akka.persistence.journal.leveldb`` which writes messages to a local LevelDB LevelDB journal plugin config entry is ``akka.persistence.journal.leveldb`` and it writes messages to a local LevelDB
instance. The default location of the LevelDB files is a directory named ``journal`` in the current working instance. The default location of the LevelDB files is a directory named ``journal`` in the current working
directory. This location can be changed by configuration where the specified path can be relative or absolute: directory. This location can be changed by configuration where the specified path can be relative or absolute:
@ -625,7 +655,7 @@ i.e. only the first injection is used.
Local snapshot store Local snapshot store
-------------------- --------------------
The default snapshot store plugin is ``akka.persistence.snapshot-store.local``. It writes snapshot files to Local snapshot store plugin config entry is ``akka.persistence.snapshot-store.local`` and it writes snapshot files to
the local filesystem. The default storage location is a directory named ``snapshots`` in the current working the local filesystem. The default storage location is a directory named ``snapshots`` in the current working
directory. This can be changed by configuration where the specified path can be relative or absolute: directory. This can be changed by configuration where the specified path can be relative or absolute:

View file

@ -178,3 +178,21 @@ persistent actor on the sending side.
Read more about at-least-once delivery in the :ref:`documentation for Scala <at-least-once-delivery>` and Read more about at-least-once delivery in the :ref:`documentation for Scala <at-least-once-delivery>` and
:ref:`documentation for Java <at-least-once-delivery-java>`. :ref:`documentation for Java <at-least-once-delivery-java>`.
Default persistence plugins
===========================
Previously default ``akka.persistence.journal.plugin`` was set to the LevelDB journal ``akka.persistence.journal.leveldb``
and default ``akka.persistence.snapshot-store.plugin`` was set to the local file-system snapshot ``akka.persistence.snapshot-store.local``.
Now default journal and default snapshot-store plugins are set to empty "" in the persistence extension ``reference.conf``,
and require explicit user configuration via override in the user ``application.conf``.
This change was needed to decouple persistence extension from the LevelDB dependency, and to support multiple plugin configurations.
Please see persistence extension ``reference.conf`` for details.
Converted LevelDB to an optional dependency
===========================================
Persistence extension uses LevelDB based plugins for own development and keeps related code in the published jar.
However previously LevelDB was a ``compile`` scope dependency, and now it is an ``optional;provided`` dependency.
To continue using LevelDB based persistence plugins it is now required for related user projects
to include an additional explicit dependency declaration for the LevelDB artifacts.
This change allows production akka deployments to avoid need for the LevelDB provisioning.
Please see persistence extension ``reference.conf`` for details.

View file

@ -45,6 +45,14 @@ Akka persistence is a separate jar file. Make sure that you have the following d
"com.typesafe.akka" %% "akka-persistence-experimental" % "@version@" @crossString@ "com.typesafe.akka" %% "akka-persistence-experimental" % "@version@" @crossString@
Akka persistence extension comes with few built-in persistence plugins, including
in-memory heap based journal, local file-system based snapshot-store and LevelDB based journal.
LevelDB based plugins will require the following additional dependency declaration::
"org.iq80.leveldb" % "leveldb" % "0.7"
"org.fusesource.leveldbjni" % "leveldbjni-all" % "1.7"
Architecture Architecture
============ ============
@ -61,13 +69,14 @@ Architecture
case of sender and receiver JVM crashes. case of sender and receiver JVM crashes.
* *Journal*: A journal stores the sequence of messages sent to a persistent actor. An application can control which messages * *Journal*: A journal stores the sequence of messages sent to a persistent actor. An application can control which messages
are journaled and which are received by the persistent actor without being journaled. The storage backend of a journal is are journaled and which are received by the persistent actor without being journaled. The storage backend of a journal is pluggable.
pluggable. The default journal storage plugin writes to the local filesystem, replicated journals are available as Persistence extension comes with a "leveldb" journal plugin, which writes to the local filesystem,
`Community plugins`_. and replicated journals are available as `Community plugins`_.
* *Snapshot store*: A snapshot store persists snapshots of a persistent actor's or a view's internal state. Snapshots are * *Snapshot store*: A snapshot store persists snapshots of a persistent actor's or a view's internal state. Snapshots are
used for optimizing recovery times. The storage backend of a snapshot store is pluggable. The default snapshot used for optimizing recovery times. The storage backend of a snapshot store is pluggable.
storage plugin writes to the local filesystem. Persistence extension comes with a "local" snapshot storage plugin, which writes to the local filesystem,
and replicated snapshot stores are available as `Community plugins`_.
.. _Community plugins: http://akka.io/community/ .. _Community plugins: http://akka.io/community/
@ -486,11 +495,25 @@ configuration key. The method can be overridden by implementation classes to ret
Storage plugins Storage plugins
=============== ===============
Storage backends for journals and snapshot stores are pluggable in Akka persistence. The default journal plugin Storage backends for journals and snapshot stores are pluggable in the Akka persistence extension.
writes messages to LevelDB (see :ref:`local-leveldb-journal`). The default snapshot store plugin writes snapshots
as individual files to the local filesystem (see :ref:`local-snapshot-store`). Applications can provide their own Directory of persistence journal and snapshot store plugins is available at the Akka Community Projects page, see `Community plugins`_
plugins by implementing a plugin API and activate them by configuration. Plugin development requires the following
imports: Plugins can be selected either by "default", for all persistent actors and views,
or "individually", when persistent actor or view defines it's own set of plugins.
When persistent actor or view does NOT override ``journalPluginId`` and ``snapshotPluginId`` methods,
persistense extension will use "default" journal and snapshot-store plugins configured in the ``reference.conf``::
akka.persistence.journal.plugin = ""
akka.persistence.snapshot-store.plugin = ""
However, these entires are provided as empty "", and require explicit user configuration via override in the user ``application.conf``.
For an example of journal plugin which writes messages to LevelDB see :ref:`local-leveldb-journal`.
For an example of snapshot store plugin which writes snapshots as individual files to the local filesystem see :ref:`local-snapshot-store`.
Applications can provide their own plugins by implementing a plugin API and activate them by configuration.
Plugin development requires the following imports:
.. includecode:: code/docs/persistence/PersistencePluginDocSpec.scala#plugin-imports .. includecode:: code/docs/persistence/PersistencePluginDocSpec.scala#plugin-imports
@ -575,7 +598,7 @@ Pre-packaged plugins
Local LevelDB journal Local LevelDB journal
--------------------- ---------------------
The default journal plugin is ``akka.persistence.journal.leveldb`` which writes messages to a local LevelDB LevelDB journal plugin config entry is ``akka.persistence.journal.leveldb`` and it writes messages to a local LevelDB
instance. The default location of the LevelDB files is a directory named ``journal`` in the current working instance. The default location of the LevelDB files is a directory named ``journal`` in the current working
directory. This location can be changed by configuration where the specified path can be relative or absolute: directory. This location can be changed by configuration where the specified path can be relative or absolute:
@ -625,7 +648,7 @@ i.e. only the first injection is used.
Local snapshot store Local snapshot store
-------------------- --------------------
The default snapshot store plugin is ``akka.persistence.snapshot-store.local``. It writes snapshot files to Local snapshot store plugin config entry is ``akka.persistence.snapshot-store.local`` and it writes snapshot files to
the local filesystem. The default storage location is a directory named ``snapshots`` in the current working the local filesystem. The default storage location is a directory named ``snapshots`` in the current working
directory. This can be changed by configuration where the specified path can be relative or absolute: directory. This can be changed by configuration where the specified path can be relative or absolute:

View file

@ -20,7 +20,7 @@ akka.persistence {
journal { journal {
# Absolute path to the journal plugin configuration entry used by persistent actor or view by default. # Absolute path to the journal plugin configuration entry used by persistent actor or view by default.
# Persistent actor or view can override `journalPluginId` method in order to rely on a different journal plugin. # Persistent actor or view can override `journalPluginId` method in order to rely on a different journal plugin.
plugin = "akka.persistence.journal.inmem" plugin = ""
# Maximum size of a persistent message batch written to the journal. # Maximum size of a persistent message batch written to the journal.
max-message-batch-size = 200 max-message-batch-size = 200
# Maximum size of a deletion batch written to the journal. # Maximum size of a deletion batch written to the journal.
@ -30,7 +30,7 @@ akka.persistence {
snapshot-store { snapshot-store {
# Absolute path to the snapshot plugin configuration entry used by persistent actor or view by default. # Absolute path to the snapshot plugin configuration entry used by persistent actor or view by default.
# Persistent actor or view can override `snapshotPluginId` method in order to rely on a different snapshot plugin. # Persistent actor or view can override `snapshotPluginId` method in order to rely on a different snapshot plugin.
plugin = "akka.persistence.snapshot-store.local" plugin = ""
} }
# Default persistent view settings. # Default persistent view settings.
view { view {
@ -119,7 +119,7 @@ akka.persistence.snapshot-store.local {
} }
# LevelDB journal plugin. # LevelDB journal plugin.
# TODO move to separate module: https://github.com/akka/akka/issues/15884 # Note: this plugin requires explicit LevelDB dependency, see below.
akka.persistence.journal.leveldb { akka.persistence.journal.leveldb {
# Class name of the plugin. # Class name of the plugin.
class = "akka.persistence.journal.leveldb.LeveldbJournal" class = "akka.persistence.journal.leveldb.LeveldbJournal"
@ -138,7 +138,7 @@ akka.persistence.journal.leveldb {
} }
# Shared LevelDB journal plugin (for testing only). # Shared LevelDB journal plugin (for testing only).
# TODO move to separate module: https://github.com/akka/akka/issues/15884 # Note: this plugin requires explicit LevelDB dependency, see below.
akka.persistence.journal.leveldb-shared { akka.persistence.journal.leveldb-shared {
# Class name of the plugin. # Class name of the plugin.
class = "akka.persistence.journal.leveldb.SharedLeveldbJournal" class = "akka.persistence.journal.leveldb.SharedLeveldbJournal"
@ -161,3 +161,21 @@ akka.persistence.journal.leveldb-shared {
native = on native = on
} }
} }
# LevelDB persistence requires the following dependency declarations:
#
# SBT:
# "org.iq80.leveldb" % "leveldb" % "0.7"
# "org.fusesource.leveldbjni" % "leveldbjni-all" % "1.7"
#
# Maven:
# <dependency>
# <groupId>org.iq80.leveldb</groupId>
# <artifactId>leveldb</artifactId>
# <version>0.7</version>
# </dependency>
# <dependency>
# <groupId>org.fusesource.leveldbjni</groupId>
# <artifactId>leveldbjni-all</artifactId>
# <version>1.7</version>
# </dependency>

View file

@ -126,10 +126,18 @@ class Persistence(val system: ExtendedActorSystem) extends Extension {
private val config = system.settings.config.getConfig("akka.persistence") private val config = system.settings.config.getConfig("akka.persistence")
// Lazy, so user is not forced to configure defaults when she is not using them. // Lazy, so user is not forced to configure defaults when she is not using them.
private lazy val defaultJournalPluginId = config.getString("journal.plugin") private lazy val defaultJournalPluginId = {
val configPath = config.getString("journal.plugin")
require(!isEmpty(configPath), "default journal plugin is not configured, see 'reference.conf'")
configPath
}
// Lazy, so user is not forced to configure defaults when she is not using them. // Lazy, so user is not forced to configure defaults when she is not using them.
private lazy val defaultSnapshotPluginId = config.getString("snapshot-store.plugin") private lazy val defaultSnapshotPluginId = {
val configPath = config.getString("snapshot-store.plugin")
require(!isEmpty(configPath), "default snapshot-store plugin is not configured, see 'reference.conf'")
configPath
}
val settings = new PersistenceSettings(config) val settings = new PersistenceSettings(config)
@ -139,8 +147,8 @@ class Persistence(val system: ExtendedActorSystem) extends Extension {
private def snapshotDispatchSelector(klaz: Class[_]): String = private def snapshotDispatchSelector(klaz: Class[_]): String =
DefaultPluginDispatcherId DefaultPluginDispatcherId
/** Check for default identity. */ /** Check for default or missing identity. */
private def isDefault(text: String) = text == null || text.length == 0 private def isEmpty(text: String) = text == null || text.length == 0
/** Discovered persistence journal plugins. */ /** Discovered persistence journal plugins. */
private val journalPluginExtensionId = new AtomicReference[Map[String, ExtensionId[PluginHolder]]](Map.empty) private val journalPluginExtensionId = new AtomicReference[Map[String, ExtensionId[PluginHolder]]](Map.empty)
@ -155,7 +163,7 @@ class Persistence(val system: ExtendedActorSystem) extends Extension {
* Configuration entry must contain few required fields, such as `class`. See `src/main/resources/reference.conf`. * Configuration entry must contain few required fields, such as `class`. See `src/main/resources/reference.conf`.
*/ */
@tailrec final def journalFor(journalPluginId: String): ActorRef = { @tailrec final def journalFor(journalPluginId: String): ActorRef = {
val configPath = if (isDefault(journalPluginId)) defaultJournalPluginId else journalPluginId val configPath = if (isEmpty(journalPluginId)) defaultJournalPluginId else journalPluginId
val extensionIdMap = journalPluginExtensionId.get val extensionIdMap = journalPluginExtensionId.get
extensionIdMap.get(configPath) match { extensionIdMap.get(configPath) match {
case Some(extensionId) case Some(extensionId)
@ -177,7 +185,7 @@ class Persistence(val system: ExtendedActorSystem) extends Extension {
* Configuration entry must contain few required fields, such as `class`. See `src/main/resources/reference.conf`. * Configuration entry must contain few required fields, such as `class`. See `src/main/resources/reference.conf`.
*/ */
@tailrec final def snapshotStoreFor(snapshotPluginId: String): ActorRef = { @tailrec final def snapshotStoreFor(snapshotPluginId: String): ActorRef = {
val configPath = if (isDefault(snapshotPluginId)) defaultSnapshotPluginId else snapshotPluginId val configPath = if (isEmpty(snapshotPluginId)) defaultSnapshotPluginId else snapshotPluginId
val extensionIdMap = snapshotPluginExtensionId.get val extensionIdMap = snapshotPluginExtensionId.get
extensionIdMap.get(configPath) match { extensionIdMap.get(configPath) match {
case Some(extensionId) case Some(extensionId)
@ -193,6 +201,8 @@ class Persistence(val system: ExtendedActorSystem) extends Extension {
} }
private def createPlugin(configPath: String)(dispatcherSelector: Class[_] String) = { private def createPlugin(configPath: String)(dispatcherSelector: Class[_] String) = {
require(!isEmpty(configPath) && system.settings.config.hasPath(configPath),
s"'reference.conf' is missing persistence plugin config path: '${configPath}'")
val pluginActorName = configPath val pluginActorName = configPath
val pluginConfig = system.settings.config.getConfig(configPath) val pluginConfig = system.settings.config.getConfig(configPath)
val pluginClassName = pluginConfig.getString("class") val pluginClassName = pluginConfig.getString("class")

View file

@ -26,6 +26,7 @@ object AtLeastOnceDeliveryFailureSpec {
akka.persistence.journal.chaos.replay-failure-rate = 0.25 akka.persistence.journal.chaos.replay-failure-rate = 0.25
akka.persistence.journal.chaos.read-highest-failure-rate = 0.1 akka.persistence.journal.chaos.read-highest-failure-rate = 0.1
akka.persistence.journal.chaos.class = akka.persistence.journal.chaos.ChaosJournal akka.persistence.journal.chaos.class = akka.persistence.journal.chaos.ChaosJournal
akka.persistence.snapshot-store.plugin = "akka.persistence.snapshot-store.local"
akka.persistence.snapshot-store.local.dir = "target/snapshots-at-least-once-delivery-failure-spec/" akka.persistence.snapshot-store.local.dir = "target/snapshots-at-least-once-delivery-failure-spec/"
""") """)

View file

@ -55,6 +55,7 @@ object PersistenceSpec {
akka.persistence.publish-plugin-commands = on akka.persistence.publish-plugin-commands = on
akka.persistence.journal.plugin = "akka.persistence.journal.${plugin}" akka.persistence.journal.plugin = "akka.persistence.journal.${plugin}"
akka.persistence.journal.leveldb.dir = "target/journal-${test}" akka.persistence.journal.leveldb.dir = "target/journal-${test}"
akka.persistence.snapshot-store.plugin = "akka.persistence.snapshot-store.local"
akka.persistence.snapshot-store.local.dir = "target/snapshots-${test}/" akka.persistence.snapshot-store.local.dir = "target/snapshots-${test}/"
akka.test.single-expect-default = 10s akka.test.single-expect-default = 10s
""")) """))

View file

@ -23,7 +23,10 @@ object SharedLeveldbJournalSpec {
plugin = "akka.persistence.journal.leveldb-shared" plugin = "akka.persistence.journal.leveldb-shared"
leveldb-shared.store.dir = target/journal-SharedLeveldbJournalSpec leveldb-shared.store.dir = target/journal-SharedLeveldbJournalSpec
} }
snapshot-store.local.dir = target/snapshots-SharedLeveldbJournalSpec snapshot-store {
plugin = "akka.persistence.snapshot-store.local"
local.dir = target/snapshots-SharedLeveldbJournalSpec
}
} }
remote { remote {
enabled-transports = ["akka.remote.netty.tcp"] enabled-transports = ["akka.remote.netty.tcp"]

View file

@ -92,7 +92,7 @@ object AkkaBuild extends Build {
lazy val benchJmh = Project( lazy val benchJmh = Project(
id = "akka-bench-jmh", id = "akka-bench-jmh",
base = file("akka-bench-jmh"), base = file("akka-bench-jmh"),
dependencies = Seq(actor, persistence, testkit).map(_ % "compile;compile->test") dependencies = Seq(actor, persistence, testkit).map(_ % "compile;compile->test;provided->test")
).disablePlugins(ValidatePullRequest) ).disablePlugins(ValidatePullRequest)
lazy val remote = Project( lazy val remote = Project(
@ -146,7 +146,7 @@ object AkkaBuild extends Build {
lazy val persistenceTck = Project( lazy val persistenceTck = Project(
id = "akka-persistence-experimental-tck", id = "akka-persistence-experimental-tck",
base = file("akka-persistence-tck"), base = file("akka-persistence-tck"),
dependencies = Seq(persistence % "compile;test->test", testkit % "compile;test->test") dependencies = Seq(persistence % "compile;provided->provided;test->test", testkit % "compile;test->test")
) )
lazy val kernel = Project( lazy val kernel = Project(
@ -172,14 +172,14 @@ object AkkaBuild extends Build {
base = file("akka-docs"), base = file("akka-docs"),
dependencies = Seq(actor, testkit % "test->test", dependencies = Seq(actor, testkit % "test->test",
remote % "compile;test->test", cluster, clusterMetrics, slf4j, agent, camel, osgi, remote % "compile;test->test", cluster, clusterMetrics, slf4j, agent, camel, osgi,
persistence % "compile;test->test", persistenceTck, persistence % "compile;provided->provided;test->test", persistenceTck,
typed % "compile;test->test") typed % "compile;test->test")
) )
lazy val contrib = Project( lazy val contrib = Project(
id = "akka-contrib", id = "akka-contrib",
base = file("akka-contrib"), base = file("akka-contrib"),
dependencies = Seq(remote, remoteTests % "test->test", cluster, persistence) dependencies = Seq(remote, remoteTests % "test->test", cluster, persistence % "compile;test->provided")
) configs (MultiJvm) ) configs (MultiJvm)
lazy val samples = Project( lazy val samples = Project(

View file

@ -32,8 +32,8 @@ object Dependencies {
val uncommonsMath = "org.uncommons.maths" % "uncommons-maths" % "1.2.2a" exclude("jfree", "jcommon") exclude("jfree", "jfreechart") // ApacheV2 val uncommonsMath = "org.uncommons.maths" % "uncommons-maths" % "1.2.2a" exclude("jfree", "jcommon") exclude("jfree", "jfreechart") // ApacheV2
val osgiCore = "org.osgi" % "org.osgi.core" % "4.3.1" // ApacheV2 val osgiCore = "org.osgi" % "org.osgi.core" % "4.3.1" // ApacheV2
val osgiCompendium= "org.osgi" % "org.osgi.compendium" % "4.3.1" // ApacheV2 val osgiCompendium= "org.osgi" % "org.osgi.compendium" % "4.3.1" // ApacheV2
val levelDB = "org.iq80.leveldb" % "leveldb" % "0.7" // ApacheV2
val levelDBNative = "org.fusesource.leveldbjni" % "leveldbjni-all" % "1.7" // New BSD // TODO remove with metrics from akka-cluster
val sigar = "org.fusesource" % "sigar" % "1.6.4" // ApacheV2 val sigar = "org.fusesource" % "sigar" % "1.6.4" // ApacheV2
object Test { object Test {
@ -67,6 +67,9 @@ object Dependencies {
object Provided { object Provided {
// TODO remove from "test" config // TODO remove from "test" config
val sigarLoader = "io.kamon" % "sigar-loader" % "1.6.5-rev001" % "optional;provided;test" // ApacheV2 val sigarLoader = "io.kamon" % "sigar-loader" % "1.6.5-rev001" % "optional;provided;test" // ApacheV2
val levelDB = "org.iq80.leveldb" % "leveldb" % "0.7" % "optional;provided" // ApacheV2
val levelDBNative = "org.fusesource.leveldbjni" % "leveldbjni-all" % "1.7" % "optional;provided" // New BSD
} }
} }
@ -91,7 +94,7 @@ object Dependencies {
val agent = Seq(scalaStm, Test.scalatest, Test.junit) val agent = Seq(scalaStm, Test.scalatest, Test.junit)
val persistence = deps(levelDB, levelDBNative, protobuf, Test.scalatest, Test.junit, Test.commonsIo, Test.scalaXml) val persistence = deps(protobuf, Provided.levelDB, Provided.levelDBNative, Test.scalatest, Test.junit, Test.commonsIo, Test.scalaXml)
val persistenceTck = Seq(Test.scalatest.copy(configurations = Some("compile")), Test.junit.copy(configurations = Some("compile"))) val persistenceTck = Seq(Test.scalatest.copy(configurations = Some("compile")), Test.junit.copy(configurations = Some("compile")))