From 2e97ed2b22977d2a69804f99caa242fae778313b Mon Sep 17 00:00:00 2001 From: Martin Krasser Date: Fri, 11 Mar 2016 10:53:42 +0100 Subject: [PATCH] Multi-module project - closes #169 --- .travis.yml | 8 +- .travis/test-core.sh | 3 + .travis/test-crdt.sh | 3 + .travis/test-it.sh | 7 - .travis/test-leveldb.sh | 3 + .travis/test-multi.sh | 9 - .travis/test.sh | 3 - README.md | 1 + build.sbt | 217 +----------- .../EventsourcedActorCausalitySpec.scala | 14 +- .../EventsourcedActorIntegrationSpec.scala | 28 +- .../EventsourcedActorThroughputSpec.scala | 9 +- ...EventsourcedProcessorIntegrationSpec.scala | 22 +- .../eventuate/IntegrationTestException.scala | 10 +- .../eventuate/LocationSpec.scala | 50 ++- .../PersistOnEventIntegrationSpec.scala | 9 +- .../eventuate/ReplicationCycleSpec.scala | 9 +- .../ReplicationIntegrationSpec.scala | 14 +- .../eventuate/log/EventLogSpec.scala | 321 +----------------- .../DurableEventSerializerSpec.scala | 10 +- .../ReplicationFilterSerializerSpec.scala | 11 +- .../ReplicationProtocolSerializerSpec.scala | 8 +- .../serializer/SerializationContext.scala | 4 +- .../serializer/SnapshotSerializerSpec.scala | 10 +- .../FilesystemSnapshotStoreSpec.scala | 6 +- .../eventuate/utilities/RestarterActor.scala | 4 +- .../eventuate/utilities/package.scala | 5 +- .../eventuate/ProcessBuilder.java | 4 +- .../src}/main/protobuf/CommonFormats.proto | 0 .../main/protobuf/DurableEventFormats.proto | 0 .../protobuf/ReplicationFilterFormats.proto | 0 .../protobuf/ReplicationProtocolFormats.proto | 0 .../src}/main/protobuf/SnapshotFormats.proto | 0 .../src}/main/resources/reference.conf | 86 ----- .../main/scala/akka/actor/MessageStash.scala | 4 +- .../eventuate/AbstractEventsourcedActor.scala | 4 +- .../AbstractEventsourcedProcessor.scala | 4 +- ...bstractEventsourcedStatefulProcessor.scala | 4 +- .../eventuate/AbstractEventsourcedView.scala | 4 +- .../AbstractEventsourcedWriter.scala | 4 +- .../eventuate/ApplicationVersion.scala | 4 +- .../eventuate/BehaviorContext.scala | 6 +- .../eventuate/ConditionalRequest.scala | 4 +- .../eventuate/ConfirmedDelivery.scala | 4 +- .../eventuate/DurableEvent.scala | 4 +- .../eventuate/EventsourcedActor.scala | 4 +- .../eventuate/EventsourcedClock.scala | 4 +- .../eventuate/EventsourcedProcessor.scala | 4 +- .../eventuate/EventsourcedView.scala | 4 +- .../eventuate/EventsourcedWriter.scala | 4 +- .../eventuate/EventsourcingProtocol.scala | 4 +- .../eventuate/PersistOnEvent.scala | 4 +- .../rbmhtechnology/eventuate/Recovery.scala | 4 +- .../eventuate/ReplicationConnection.scala | 4 +- .../eventuate/ReplicationEndpoint.scala | 4 +- .../eventuate/ReplicationFilter.scala | 4 +- .../eventuate/ReplicationProtocol.scala | 4 +- .../eventuate/ResultHandler.scala | 4 +- .../com/rbmhtechnology/eventuate/Retry.scala | 4 +- .../rbmhtechnology/eventuate/Snapshot.scala | 4 +- .../rbmhtechnology/eventuate/StashError.scala | 4 +- .../eventuate/UnavailableException.scala | 4 +- .../eventuate/VectorClock.scala | 4 +- .../rbmhtechnology/eventuate/Versioned.scala | 4 +- .../eventuate/VersionedAggregate.scala | 4 +- .../eventuate/log/BatchingLayer.scala | 4 +- .../eventuate/log/CircuitBreaker.scala | 4 +- .../eventuate/log/EventLog.scala | 4 +- .../eventuate/log/NotificationChannel.scala | 4 +- .../eventuate/log/SubscriberRegistry.scala | 4 +- .../serializer/CommonSerializer.scala | 4 +- .../serializer/DurableEventSerializer.scala | 4 +- .../ReplicationFilterSerializer.scala | 4 +- .../ReplicationProtocolSerializer.scala | 4 +- .../serializer/SnapshotSerializer.scala | 4 +- .../eventuate/snapshot/SnapshotStore.scala | 4 +- .../filesystem/FilesystemSnapshotStore.scala | 4 +- .../FilesystemSnapshotStoreSettings.scala | 4 +- .../eventuate/BasicCausalitySpec.scala | 30 +- .../eventuate/BasicPersistOnEventSpec.scala | 26 +- .../eventuate/BasicReplicationSpec.scala | 38 +-- .../BasicReplicationThroughputSpec.scala | 38 +-- .../eventuate/FailureDetectionSpec.scala | 30 +- .../eventuate/FilteredReplicationSpec.scala | 24 +- .../MultiNodeReplicationConfig.scala | 18 +- .../MultiNodeReplicationEndpoint.scala | 4 +- .../eventuate/MultiNodeWordSpec.scala | 4 +- .../AbstractEventsourcedActorSpec.java | 4 +- .../AbstractEventsourcedProcessorSpec.java | 4 +- .../AbstractEventsourcedViewSpec.java | 4 +- .../AbstractEventsourcedWriterSpec.java | 4 +- .../rbmhtechnology/eventuate/BaseSpec.java | 4 +- .../src/test/resources/reference.conf | 2 + .../eventuate/ApplicationVersionSpec.scala | 4 +- .../eventuate/BehaviorContextSpec.scala | 4 +- .../eventuate/ConcurrentVersionsSpec.scala | 4 +- .../eventuate/ConditionalRequestsSpec.scala | 4 +- .../eventuate/EventsourcedActorSpec.scala | 18 +- .../eventuate/EventsourcedProcessorSpec.scala | 10 +- .../eventuate/EventsourcedViewSpec.scala | 14 +- .../eventuate/EventsourcedWriterSpec.scala | 8 +- .../eventuate/FailureDetectorSpec.scala | 4 +- .../eventuate/PersistOnEventSpec.scala | 10 +- .../eventuate/ReplicationFilterSpec.scala | 4 +- .../eventuate/TestException.scala | 10 +- .../eventuate/VectorClockSpec.scala | 4 +- .../eventuate/VectorTimeSpec.scala | 4 +- .../eventuate/log/CircuitBreakerSpec.scala | 4 +- .../log/NotificationChannelSpec.scala | 4 +- eventuate-crdt/build.sbt | 2 + .../src/it/resources/application.conf | 5 + .../eventuate/crdt/CRDTChaosSpecLeveldb.scala | 60 ++-- .../crdt/CRDTRecoverySpecLeveldb.scala | 9 +- .../eventuate/crdt}/CRDTSerializerSpec.scala | 21 +- .../crdt/CRDTServiceSpecLeveldb.scala | 4 +- .../src}/main/protobuf/CRDTFormats.proto | 2 +- .../src/main/resources/reference.conf | 11 + .../eventuate/crdt/CRDTFormat.scala | 4 +- .../eventuate/crdt}/CRDTSerializer.scala | 12 +- .../eventuate/crdt/CRDTService.scala | 4 +- .../eventuate/crdt/Counter.scala | 4 +- .../eventuate/crdt/LWWRegister.scala | 4 +- .../eventuate/crdt/MVRegister.scala | 4 +- .../rbmhtechnology/eventuate/crdt/ORSet.scala | 4 +- .../eventuate/crdt/ReplicatedORSetSpec.scala | 25 +- .../eventuate/crdt/CRDTSpec.scala | 4 +- eventuate-examples/bin/.example-classpath | 5 + {example => eventuate-examples/bin}/ordermgnt | 6 +- .../bin}/ordermgnt-location | 6 +- .../example/japi/ordermgnt/Order.java | 4 +- .../example/japi/ordermgnt/OrderActor.java | 4 +- .../example/japi/ordermgnt/OrderExample.java | 4 +- .../example/japi/ordermgnt/OrderId.java | 4 +- .../example/japi/ordermgnt/OrderManager.java | 4 +- .../japi/ordermgnt/OrderSerializer.java | 4 +- .../example/japi/ordermgnt/OrderView.java | 4 +- .../src/main}/resources/log4j.properties | 0 .../main}/resources/ordermgnt/location-A.conf | 0 .../main}/resources/ordermgnt/location-B.conf | 0 .../main}/resources/ordermgnt/location-C.conf | 0 .../main}/resources/ordermgnt/location-D.conf | 0 .../main}/resources/ordermgnt/location-E.conf | 0 .../main}/resources/ordermgnt/location-F.conf | 0 .../example/ordermgnt/Order.scala | 4 +- .../example/ordermgnt/OrderActor.scala | 4 +- .../example/ordermgnt/OrderExample.scala | 4 +- .../example/ordermgnt/OrderManager.scala | 4 +- .../example/ordermgnt/OrderView.scala | 4 +- .../example/ordermgnt/package.scala | 4 +- .../example/querydb/Emitter.scala | 4 +- .../example/querydb/Writer.scala | 33 +- .../example/querydb/WriterApp.scala | 4 +- .../src}/it/resources/application.conf | 6 +- .../src}/it/resources/log4j.properties | 0 .../eventuate/LocationSpecCassandra.scala | 22 +- .../eventuate/LocationSpecsCassandra.scala | 52 +++ ...cuitBreakerIntregrationSpecCassandra.scala | 12 +- .../EventLogPartitioningSpecCassandra.scala | 10 +- .../eventuate/log/EventLogSpecCassandra.scala | 223 ++++++++++++ .../src/main/resources/reference.conf | 80 +++++ .../eventuate/log/cassandra/Cassandra.scala | 4 +- .../cassandra/CassandraDeletedToStore.scala | 4 +- .../log/cassandra/CassandraEventLog.scala | 4 +- .../cassandra/CassandraEventLogSettings.scala | 4 +- .../cassandra/CassandraEventLogStore.scala | 4 +- .../log/cassandra/CassandraIndex.scala | 4 +- .../log/cassandra/CassandraIndexStore.scala | 4 +- .../CassandraReplicationProgressStore.scala | 4 +- .../log/cassandra/CassandraStatements.scala | 4 +- .../eventuate/log/cassandra/package.scala | 4 +- .../src}/multi-jvm/resources/log4j.properties | 0 .../eventuate/MultiNodeConfigCassandra.scala | 18 +- .../eventuate/MultiNodeSpecsCassandra.scala | 67 ++++ .../eventuate/MultiNodeSupportCassandra.scala | 30 +- .../src/it/resources/application.conf | 5 + .../eventuate/DeleteEventsSpecLeveldb.scala | 20 +- .../eventuate/LocationSpecLeveldb.scala | 21 +- .../eventuate/LocationSpecsLeveldb.scala | 52 +++ .../eventuate/RecoverySpecLeveldb.scala | 10 +- .../eventuate/log/EventLogSpecLeveldb.scala | 150 ++++++++ .../src/main/resources/reference.conf | 22 ++ .../log/leveldb/LeveldbDeletionActor.scala | 6 +- .../LeveldbDeletionMetadataStore.scala | 6 +- .../log/leveldb/LeveldbEventLog.scala | 4 +- .../LeveldbNumericIdentifierStore.scala | 4 +- .../LeveldbReplicationProgressStore.scala | 4 +- .../eventuate/MultiNodeConfigLeveldb.scala | 14 +- .../eventuate/MultiNodeSpecsLeveldb.scala | 48 +++ .../eventuate/MultiNodeSupportLeveldb.scala | 50 +++ example/dbreplica | 19 -- example/dbreplica-location | 28 -- project/Formatting.scala | 37 -- project/ProjectDependencies.scala | 41 +++ project/ProjectSettings.scala | 199 +++++++++++ project/build.properties | 2 +- project/plugins.sbt | 4 +- .../eventuate/LocationConfig.scala | 46 --- src/sphinx/architecture.rst | 2 +- src/sphinx/code/EventLogDoc.scala | 4 +- src/sphinx/code/EventRoutingDoc.scala | 4 +- src/sphinx/code/EventSourcingDoc.scala | 6 +- src/sphinx/code/ReliableDeliveryDoc.scala | 4 +- src/sphinx/code/UserGuideDoc.scala | 4 +- src/sphinx/current-limitations.rst | 2 +- src/sphinx/download.rst | 87 ++++- src/sphinx/example-application.rst | 18 +- src/sphinx/getting-started.rst | 2 +- src/sphinx/project.rst | 2 +- src/sphinx/reference/configuration.rst | 20 +- src/sphinx/reference/event-sourcing.rst | 10 +- src/sphinx/user-guide.rst | 2 +- .../example/japi/dbreplica/DBReplica.java | 139 -------- .../example/japi/dbreplica/cdc/AssetCdc.java | 36 -- .../japi/dbreplica/cdc/AssetCdcActor.java | 176 ---------- .../japi/dbreplica/cdc/AssetCdcInbound.java | 152 --------- .../japi/dbreplica/cdc/AssetCdcOutbound.java | 113 ------ .../japi/dbreplica/cdc/AssetCdcSettings.java | 40 --- .../example/japi/dbreplica/cli/Command.java | 64 ---- .../japi/dbreplica/cli/DBReplicaCLI.java | 105 ------ .../example/japi/dbreplica/domain/Asset.java | 70 ---- .../domain/AssetDoesNotExistException.java | 24 -- .../japi/dbreplica/event/AssetEvent.java | 80 ----- .../repository/AssetClockRepository.java | 71 ---- .../repository/AssetEventRepository.java | 79 ----- .../dbreplica/repository/AssetRepository.java | 58 ---- .../repository/ProgressRepository.java | 84 ----- .../dbreplica/repository/StorageBackend.java | 92 ----- .../japi/dbreplica/service/AssetFinder.java | 29 -- .../japi/dbreplica/service/AssetListener.java | 30 -- .../dbreplica/service/AssetListeners.java | 32 -- .../dbreplica/service/AssetListenersImpl.java | 42 --- .../dbreplica/service/AssetServiceImpl.java | 57 ---- .../japi/dbreplica/util/CollectionUtil.java | 41 --- .../japi/dbreplica/util/RepositoryUtil.java | 30 -- .../japi/dbreplica/util/ScalaObjects.java | 122 ------- src/test/resources/dbreplica/create.sql | 24 -- src/test/resources/dbreplica/location-A.conf | 29 -- src/test/resources/dbreplica/location-B.conf | 29 -- src/test/resources/dbreplica/location-C.conf | 29 -- .../example/dbreplica/DBReplica.scala | 139 -------- .../example/dbreplica/cdc/AssetCdc.scala | 132 ------- .../dbreplica/cdc/AssetCdcInbound.scala | 115 ------- .../dbreplica/cdc/AssetCdcOutbound.scala | 102 ------ .../example/dbreplica/cdc/package.scala | 28 -- .../example/dbreplica/event/AssetEvent.scala | 33 -- .../repository/AssetClockRepository.scala | 63 ---- .../repository/AssetEventRepository.scala | 87 ----- .../repository/AssetRepository.scala | 48 --- .../repository/ProgressRepository.scala | 63 ---- .../dbreplica/repository/StorageBackend.scala | 53 --- .../dbreplica/service/AssetListener.scala | 27 -- .../dbreplica/service/AssetListeners.scala | 37 -- .../dbreplica/service/AssetService.scala | 60 ---- 253 files changed, 1729 insertions(+), 4353 deletions(-) create mode 100755 .travis/test-core.sh create mode 100755 .travis/test-crdt.sh delete mode 100755 .travis/test-it.sh create mode 100755 .travis/test-leveldb.sh delete mode 100755 .travis/test-multi.sh delete mode 100755 .travis/test.sh rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorCausalitySpec.scala (89%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorIntegrationSpec.scala (94%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorThroughputSpec.scala (87%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/EventsourcedProcessorIntegrationSpec.scala (92%) rename src/test/scala/com/rbmhtechnology/example/dbreplica/domain/Asset.scala => eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/IntegrationTestException.scala (56%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/LocationSpec.scala (72%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/PersistOnEventIntegrationSpec.scala (77%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/ReplicationCycleSpec.scala (87%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/ReplicationIntegrationSpec.scala (95%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/log/EventLogSpec.scala (71%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/serializer/DurableEventSerializerSpec.scala (92%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/serializer/ReplicationFilterSerializerSpec.scala (95%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/serializer/ReplicationProtocolSerializerSpec.scala (96%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/serializer/SerializationContext.scala (91%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/serializer/SnapshotSerializerSpec.scala (94%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStoreSpec.scala (95%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/utilities/RestarterActor.scala (90%) rename {src => eventuate-core/src}/it/scala/com/rbmhtechnology/eventuate/utilities/package.scala (94%) rename {src => eventuate-core/src}/main/java/com/rbmhtechnology/eventuate/ProcessBuilder.java (95%) rename {src => eventuate-core/src}/main/protobuf/CommonFormats.proto (100%) rename {src => eventuate-core/src}/main/protobuf/DurableEventFormats.proto (100%) rename {src => eventuate-core/src}/main/protobuf/ReplicationFilterFormats.proto (100%) rename {src => eventuate-core/src}/main/protobuf/ReplicationProtocolFormats.proto (100%) rename {src => eventuate-core/src}/main/protobuf/SnapshotFormats.proto (100%) rename {src => eventuate-core/src}/main/resources/reference.conf (63%) rename {src => eventuate-core/src}/main/scala/akka/actor/MessageStash.scala (91%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedActor.scala (96%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedProcessor.scala (96%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedStatefulProcessor.scala (86%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedView.scala (98%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedWriter.scala (95%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/ApplicationVersion.scala (89%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/BehaviorContext.scala (93%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/ConditionalRequest.scala (95%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/ConfirmedDelivery.scala (95%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/DurableEvent.scala (97%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/EventsourcedActor.scala (98%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/EventsourcedClock.scala (95%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/EventsourcedProcessor.scala (98%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/EventsourcedView.scala (98%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/EventsourcedWriter.scala (98%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/EventsourcingProtocol.scala (96%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/PersistOnEvent.scala (97%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/Recovery.scala (98%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/ReplicationConnection.scala (94%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/ReplicationEndpoint.scala (99%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/ReplicationFilter.scala (94%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/ReplicationProtocol.scala (97%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/ResultHandler.scala (95%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/Retry.scala (85%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/Snapshot.scala (94%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/StashError.scala (81%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/UnavailableException.scala (81%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/VectorClock.scala (97%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/Versioned.scala (98%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/VersionedAggregate.scala (97%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/log/BatchingLayer.scala (96%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/log/CircuitBreaker.scala (95%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/log/EventLog.scala (99%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/log/NotificationChannel.scala (92%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/log/SubscriberRegistry.scala (95%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/serializer/CommonSerializer.scala (96%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/serializer/DurableEventSerializer.scala (96%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/serializer/ReplicationFilterSerializer.scala (95%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/serializer/ReplicationProtocolSerializer.scala (98%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/serializer/SnapshotSerializer.scala (98%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/snapshot/SnapshotStore.scala (88%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStore.scala (96%) rename {src => eventuate-core/src}/main/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStoreSettings.scala (89%) rename {src => eventuate-core/src}/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicCausalitySpec.scala (76%) rename {src => eventuate-core/src}/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicPersistOnEventSpec.scala (70%) rename {src => eventuate-core/src}/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicReplicationSpec.scala (65%) rename {src => eventuate-core/src}/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicReplicationThroughputSpec.scala (67%) rename {src => eventuate-core/src}/multi-jvm/scala/com/rbmhtechnology/eventuate/FailureDetectionSpec.scala (69%) rename {src => eventuate-core/src}/multi-jvm/scala/com/rbmhtechnology/eventuate/FilteredReplicationSpec.scala (69%) rename {src => eventuate-core/src}/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeReplicationConfig.scala (63%) rename {src => eventuate-core/src}/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeReplicationEndpoint.scala (91%) rename {src => eventuate-core/src}/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeWordSpec.scala (84%) rename {src => eventuate-core/src}/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedActorSpec.java (96%) rename {src => eventuate-core/src}/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedProcessorSpec.java (97%) rename {src => eventuate-core/src}/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedViewSpec.java (98%) rename {src => eventuate-core/src}/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedWriterSpec.java (97%) rename {src => eventuate-core/src}/test/java/com/rbmhtechnology/eventuate/BaseSpec.java (96%) create mode 100644 eventuate-core/src/test/resources/reference.conf rename {src => eventuate-core/src}/test/scala/com/rbmhtechnology/eventuate/ApplicationVersionSpec.scala (89%) rename {src => eventuate-core/src}/test/scala/com/rbmhtechnology/eventuate/BehaviorContextSpec.scala (92%) rename {src => eventuate-core/src}/test/scala/com/rbmhtechnology/eventuate/ConcurrentVersionsSpec.scala (97%) rename {src => eventuate-core/src}/test/scala/com/rbmhtechnology/eventuate/ConditionalRequestsSpec.scala (96%) rename {src => eventuate-core/src}/test/scala/com/rbmhtechnology/eventuate/EventsourcedActorSpec.scala (98%) rename {src => eventuate-core/src}/test/scala/com/rbmhtechnology/eventuate/EventsourcedProcessorSpec.scala (96%) rename {src => eventuate-core/src}/test/scala/com/rbmhtechnology/eventuate/EventsourcedViewSpec.scala (98%) rename {src => eventuate-core/src}/test/scala/com/rbmhtechnology/eventuate/EventsourcedWriterSpec.scala (97%) rename {src => eventuate-core/src}/test/scala/com/rbmhtechnology/eventuate/FailureDetectorSpec.scala (92%) rename {src => eventuate-core/src}/test/scala/com/rbmhtechnology/eventuate/PersistOnEventSpec.scala (97%) rename {src => eventuate-core/src}/test/scala/com/rbmhtechnology/eventuate/ReplicationFilterSpec.scala (91%) rename src/test/scala/com/rbmhtechnology/eventuate/package.scala => eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/TestException.scala (67%) rename {src => eventuate-core/src}/test/scala/com/rbmhtechnology/eventuate/VectorClockSpec.scala (92%) rename {src => eventuate-core/src}/test/scala/com/rbmhtechnology/eventuate/VectorTimeSpec.scala (94%) rename {src => eventuate-core/src}/test/scala/com/rbmhtechnology/eventuate/log/CircuitBreakerSpec.scala (95%) rename {src => eventuate-core/src}/test/scala/com/rbmhtechnology/eventuate/log/NotificationChannelSpec.scala (96%) create mode 100644 eventuate-crdt/build.sbt create mode 100644 eventuate-crdt/src/it/resources/application.conf rename src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTChaosSpec.scala => eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTChaosSpecLeveldb.scala (80%) rename src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTRecoverySpec.scala => eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTRecoverySpecLeveldb.scala (83%) rename {src/it/scala/com/rbmhtechnology/eventuate/serializer => eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt}/CRDTSerializerSpec.scala (82%) rename src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTServiceSpec.scala => eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTServiceSpecLeveldb.scala (96%) rename {src => eventuate-crdt/src}/main/protobuf/CRDTFormats.proto (93%) create mode 100644 eventuate-crdt/src/main/resources/reference.conf rename {src => eventuate-crdt/src}/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTFormat.scala (80%) rename {src/main/scala/com/rbmhtechnology/eventuate/serializer => eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt}/CRDTSerializer.scala (92%) rename {src => eventuate-crdt/src}/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTService.scala (97%) rename {src => eventuate-crdt/src}/main/scala/com/rbmhtechnology/eventuate/crdt/Counter.scala (93%) rename {src => eventuate-crdt/src}/main/scala/com/rbmhtechnology/eventuate/crdt/LWWRegister.scala (96%) rename {src => eventuate-crdt/src}/main/scala/com/rbmhtechnology/eventuate/crdt/MVRegister.scala (95%) rename {src => eventuate-crdt/src}/main/scala/com/rbmhtechnology/eventuate/crdt/ORSet.scala (96%) rename {src => eventuate-crdt/src}/multi-jvm/scala/com/rbmhtechnology/eventuate/crdt/ReplicatedORSetSpec.scala (83%) rename {src => eventuate-crdt/src}/test/scala/com/rbmhtechnology/eventuate/crdt/CRDTSpec.scala (96%) create mode 100755 eventuate-examples/bin/.example-classpath rename {example => eventuate-examples/bin}/ordermgnt (61%) rename {example => eventuate-examples/bin}/ordermgnt-location (78%) rename {src/test => eventuate-examples/src/main}/java/com/rbmhtechnology/example/japi/ordermgnt/Order.java (91%) rename {src/test => eventuate-examples/src/main}/java/com/rbmhtechnology/example/japi/ordermgnt/OrderActor.java (98%) rename {src/test => eventuate-examples/src/main}/java/com/rbmhtechnology/example/japi/ordermgnt/OrderExample.java (97%) rename {src/test => eventuate-examples/src/main}/java/com/rbmhtechnology/example/japi/ordermgnt/OrderId.java (82%) rename {src/test => eventuate-examples/src/main}/java/com/rbmhtechnology/example/japi/ordermgnt/OrderManager.java (96%) rename {src/test => eventuate-examples/src/main}/java/com/rbmhtechnology/example/japi/ordermgnt/OrderSerializer.java (92%) rename {src/test => eventuate-examples/src/main}/java/com/rbmhtechnology/example/japi/ordermgnt/OrderView.java (93%) rename {src/test => eventuate-examples/src/main}/resources/log4j.properties (100%) rename {src/test => eventuate-examples/src/main}/resources/ordermgnt/location-A.conf (100%) rename {src/test => eventuate-examples/src/main}/resources/ordermgnt/location-B.conf (100%) rename {src/test => eventuate-examples/src/main}/resources/ordermgnt/location-C.conf (100%) rename {src/test => eventuate-examples/src/main}/resources/ordermgnt/location-D.conf (100%) rename {src/test => eventuate-examples/src/main}/resources/ordermgnt/location-E.conf (100%) rename {src/test => eventuate-examples/src/main}/resources/ordermgnt/location-F.conf (100%) rename {src/test => eventuate-examples/src/main}/scala/com/rbmhtechnology/example/ordermgnt/Order.scala (86%) rename {src/test => eventuate-examples/src/main}/scala/com/rbmhtechnology/example/ordermgnt/OrderActor.scala (97%) rename {src/test => eventuate-examples/src/main}/scala/com/rbmhtechnology/example/ordermgnt/OrderExample.scala (96%) rename {src/test => eventuate-examples/src/main}/scala/com/rbmhtechnology/example/ordermgnt/OrderManager.scala (94%) rename {src/test => eventuate-examples/src/main}/scala/com/rbmhtechnology/example/ordermgnt/OrderView.scala (90%) rename {src/test => eventuate-examples/src/main}/scala/com/rbmhtechnology/example/ordermgnt/package.scala (85%) rename {src/test => eventuate-examples/src/main}/scala/com/rbmhtechnology/example/querydb/Emitter.scala (92%) rename {src/test => eventuate-examples/src/main}/scala/com/rbmhtechnology/example/querydb/Writer.scala (79%) rename {src/test => eventuate-examples/src/main}/scala/com/rbmhtechnology/example/querydb/WriterApp.scala (95%) rename {src => eventuate-log-cassandra/src}/it/resources/application.conf (67%) rename {src => eventuate-log-cassandra/src}/it/resources/log4j.properties (100%) rename {src => eventuate-log-cassandra/src}/it/scala/com/rbmhtechnology/eventuate/LocationSpecCassandra.scala (89%) create mode 100644 eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecsCassandra.scala rename src/it/scala/com/rbmhtechnology/eventuate/log/CircuitBreakerIntregrationSpec.scala => eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/log/CircuitBreakerIntregrationSpecCassandra.scala (97%) rename src/it/scala/com/rbmhtechnology/eventuate/log/EventLogPartitioningSpec.scala => eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogPartitioningSpecCassandra.scala (94%) create mode 100644 eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogSpecCassandra.scala create mode 100644 eventuate-log-cassandra/src/main/resources/reference.conf rename {src => eventuate-log-cassandra/src}/main/scala/com/rbmhtechnology/eventuate/log/cassandra/Cassandra.scala (98%) rename {src => eventuate-log-cassandra/src}/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraDeletedToStore.scala (88%) rename {src => eventuate-log-cassandra/src}/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLog.scala (98%) rename {src => eventuate-log-cassandra/src}/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLogSettings.scala (96%) rename {src => eventuate-log-cassandra/src}/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLogStore.scala (96%) rename {src => eventuate-log-cassandra/src}/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraIndex.scala (97%) rename {src => eventuate-log-cassandra/src}/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraIndexStore.scala (96%) rename {src => eventuate-log-cassandra/src}/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraReplicationProgressStore.scala (91%) rename {src => eventuate-log-cassandra/src}/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraStatements.scala (96%) rename {src => eventuate-log-cassandra/src}/main/scala/com/rbmhtechnology/eventuate/log/cassandra/package.scala (87%) rename {src => eventuate-log-cassandra/src}/multi-jvm/resources/log4j.properties (100%) rename src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdcSettings.scala => eventuate-log-cassandra/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeConfigCassandra.scala (51%) create mode 100644 eventuate-log-cassandra/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSpecsCassandra.scala rename src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSupport.scala => eventuate-log-cassandra/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSupportCassandra.scala (62%) create mode 100644 eventuate-log-leveldb/src/it/resources/application.conf rename src/it/scala/com/rbmhtechnology/eventuate/DeleteEventsSpec.scala => eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/DeleteEventsSpecLeveldb.scala (91%) rename {src => eventuate-log-leveldb/src}/it/scala/com/rbmhtechnology/eventuate/LocationSpecLeveldb.scala (77%) create mode 100644 eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecsLeveldb.scala rename src/it/scala/com/rbmhtechnology/eventuate/RecoverySpec.scala => eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/RecoverySpecLeveldb.scala (98%) create mode 100644 eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogSpecLeveldb.scala create mode 100644 eventuate-log-leveldb/src/main/resources/reference.conf rename {src => eventuate-log-leveldb/src}/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbDeletionActor.scala (93%) rename {src => eventuate-log-leveldb/src}/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbDeletionMetadataStore.scala (87%) rename {src => eventuate-log-leveldb/src}/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbEventLog.scala (98%) rename {src => eventuate-log-leveldb/src}/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbNumericIdentifierStore.scala (92%) rename {src => eventuate-log-leveldb/src}/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbReplicationProgressStore.scala (93%) rename src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetService.java => eventuate-log-leveldb/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeConfigLeveldb.scala (55%) create mode 100644 eventuate-log-leveldb/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSpecsLeveldb.scala create mode 100644 eventuate-log-leveldb/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSupportLeveldb.scala delete mode 100755 example/dbreplica delete mode 100755 example/dbreplica-location delete mode 100644 project/Formatting.scala create mode 100644 project/ProjectDependencies.scala create mode 100644 project/ProjectSettings.scala delete mode 100644 src/it/scala/com/rbmhtechnology/eventuate/LocationConfig.scala delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/DBReplica.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdc.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcActor.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcInbound.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcOutbound.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcSettings.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/cli/Command.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/cli/DBReplicaCLI.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/domain/Asset.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/domain/AssetDoesNotExistException.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/event/AssetEvent.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/AssetClockRepository.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/AssetEventRepository.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/AssetRepository.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/ProgressRepository.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/StorageBackend.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetFinder.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetListener.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetListeners.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetListenersImpl.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetServiceImpl.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/util/CollectionUtil.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/util/RepositoryUtil.java delete mode 100644 src/test/java/com/rbmhtechnology/example/japi/dbreplica/util/ScalaObjects.java delete mode 100644 src/test/resources/dbreplica/create.sql delete mode 100644 src/test/resources/dbreplica/location-A.conf delete mode 100644 src/test/resources/dbreplica/location-B.conf delete mode 100644 src/test/resources/dbreplica/location-C.conf delete mode 100644 src/test/scala/com/rbmhtechnology/example/dbreplica/DBReplica.scala delete mode 100644 src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdc.scala delete mode 100644 src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdcInbound.scala delete mode 100644 src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdcOutbound.scala delete mode 100644 src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/package.scala delete mode 100644 src/test/scala/com/rbmhtechnology/example/dbreplica/event/AssetEvent.scala delete mode 100644 src/test/scala/com/rbmhtechnology/example/dbreplica/repository/AssetClockRepository.scala delete mode 100644 src/test/scala/com/rbmhtechnology/example/dbreplica/repository/AssetEventRepository.scala delete mode 100644 src/test/scala/com/rbmhtechnology/example/dbreplica/repository/AssetRepository.scala delete mode 100644 src/test/scala/com/rbmhtechnology/example/dbreplica/repository/ProgressRepository.scala delete mode 100644 src/test/scala/com/rbmhtechnology/example/dbreplica/repository/StorageBackend.scala delete mode 100644 src/test/scala/com/rbmhtechnology/example/dbreplica/service/AssetListener.scala delete mode 100644 src/test/scala/com/rbmhtechnology/example/dbreplica/service/AssetListeners.scala delete mode 100644 src/test/scala/com/rbmhtechnology/example/dbreplica/service/AssetService.scala diff --git a/.travis.yml b/.travis.yml index 655ea326..f94be819 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,14 +14,14 @@ before_script: - pip install --user sphinx - pip install --user sphinx_rtd_theme script: - - .travis/test.sh ++$TRAVIS_SCALA_VERSION - - .travis/test-it.sh ++$TRAVIS_SCALA_VERSION - - .travis/test-multi.sh ++$TRAVIS_SCALA_VERSION + - .travis/test-core.sh ++$TRAVIS_SCALA_VERSION + - .travis/test-leveldb.sh ++$TRAVIS_SCALA_VERSION + - .travis/test-crdt.sh ++$TRAVIS_SCALA_VERSION - find $HOME/.sbt -name "*.lock" | xargs rm - find $HOME/.ivy2 -name "ivydata-*.properties" | xargs rm after_success: - if [ "${TRAVIS_PULL_REQUEST}" = "false" ] && [ "${TRAVIS_BRANCH}" = "master" ]; then sbt ++$TRAVIS_SCALA_VERSION publish ghpagesPushSite; fi scala: - - 2.11.4 + - 2.11.7 jdk: - oraclejdk8 diff --git a/.travis/test-core.sh b/.travis/test-core.sh new file mode 100755 index 00000000..63a66025 --- /dev/null +++ b/.travis/test-core.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +sbt $1 "core/test" \ No newline at end of file diff --git a/.travis/test-crdt.sh b/.travis/test-crdt.sh new file mode 100755 index 00000000..e0647a6a --- /dev/null +++ b/.travis/test-crdt.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +sbt $1 "crdt/test" \ No newline at end of file diff --git a/.travis/test-it.sh b/.travis/test-it.sh deleted file mode 100755 index d2085685..00000000 --- a/.travis/test-it.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -sbt $1 "it:testOnly \ - com.rbmhtechnology.eventuate.crdt.* \ - com.rbmhtechnology.eventuate.serializer.* \ - com.rbmhtechnology.eventuate.snapshot.filesystem.* - *Leveldb" \ No newline at end of file diff --git a/.travis/test-leveldb.sh b/.travis/test-leveldb.sh new file mode 100755 index 00000000..9aadaf81 --- /dev/null +++ b/.travis/test-leveldb.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +sbt $1 "logLeveldb/test" diff --git a/.travis/test-multi.sh b/.travis/test-multi.sh deleted file mode 100755 index 60578b01..00000000 --- a/.travis/test-multi.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -sbt $1 "multi-jvm:testOnly \ - com.rbmhtechnology.eventuate.BasicCausalitySpecLeveldb \ - com.rbmhtechnology.eventuate.BasicReplicationSpecLeveldb \ - com.rbmhtechnology.eventuate.BasicReplicationThroughputSpecLeveldb \ - com.rbmhtechnology.eventuate.FailureDetectionSpecLeveldb \ - com.rbmhtechnology.eventuate.FilteredReplicationSpecLeveldb \ - com.rbmhtechnology.eventuate.crdt.ReplicatedORSetSpecLeveldb" diff --git a/.travis/test.sh b/.travis/test.sh deleted file mode 100755 index 9c8ab418..00000000 --- a/.travis/test.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -sbt $1 "test:testOnly" \ No newline at end of file diff --git a/README.md b/README.md index 2856df4a..48baabf1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/RBMHTechnology/eventuate?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Build Status](https://travis-ci.org/RBMHTechnology/eventuate.svg?branch=master)](https://travis-ci.org/RBMHTechnology/eventuate) [![Stories in Ready](https://badge.waffle.io/rbmhtechnology/eventuate.svg?label=ready&title=Ready)](http://waffle.io/rbmhtechnology/eventuate) diff --git a/build.sbt b/build.sbt index 5b0d034e..81c27b34 100644 --- a/build.sbt +++ b/build.sbt @@ -1,216 +1 @@ -import Keys.{compile => comp, _} - -val akkaVersion = "2.4.1" - -val protobufVersion = "2.5.0" - -organization := "com.rbmhtechnology" - -name := "eventuate" - -version := "0.6-SNAPSHOT" - -scalaVersion := "2.11.7" - -scalacOptions in (Compile, doc) := List("-skip-packages", "akka") - -scalacOptions ++= Seq("-feature", "-unchecked", "-deprecation", "-Xlint") - -fork in Test := true - -parallelExecution in Test := false - -connectInput in run := true - -resolvers += "krasserm at bintray" at "http://dl.bintray.com/krasserm/maven" - -libraryDependencies ++= Seq( - "com.datastax.cassandra" % "cassandra-driver-core" % "2.1.5", - "com.google.guava" % "guava" % "16.0", - "com.google.protobuf" % "protobuf-java" % protobufVersion, - "com.javaslang" % "javaslang" % "2.0.0-RC3" % "test,it", - "com.novocode" % "junit-interface" % "0.11" % "test->default", - "com.typesafe.akka" %% "akka-remote" % akkaVersion, - "com.typesafe.akka" %% "akka-testkit" % akkaVersion % "test,it", - "com.typesafe.akka" %% "akka-multi-node-testkit" % akkaVersion % "test", - "commons-io" % "commons-io" % "2.4", - "org.cassandraunit" % "cassandra-unit" % "2.0.2.2" % "test,it" excludeAll ExclusionRule(organization = "ch.qos.logback"), - "org.fusesource.leveldbjni" % "leveldbjni-all" % "1.8", - "org.scalatest" %% "scalatest" % "2.1.4" % "test,it", - "org.scalaz" %% "scalaz-core" % "7.1.0", - "org.scala-lang.modules" % "scala-java8-compat_2.11" % "0.7.0" -) - -// ---------------------------------------------------------------------- -// Database replication POC (example) -// ---------------------------------------------------------------------- - -val springVersion = "4.2.4.RELEASE" - -libraryDependencies ++= Seq( - "org.aspectj" % "aspectjrt" % "1.8.8", - "org.aspectj" % "aspectjweaver" % "1.8.8", - "org.springframework" % "spring-context" % springVersion, - "org.springframework" % "spring-jdbc" % springVersion, - "org.springframework" % "spring-tx" % springVersion, - "org.hsqldb" % "hsqldb" % "2.3.3" -) - -// ---------------------------------------------------------------------- -// Documentation -// ---------------------------------------------------------------------- - -site.settings - -site.sphinxSupport() - -site.includeScaladoc() - -ghpages.settings - -git.remoteRepo := "git@github.com:RBMHTechnology/eventuate.git" - -unmanagedSourceDirectories in Test += baseDirectory.value / "src" / "sphinx"/ "code" - -// ---------------------------------------------------------------------- -// Publishing -// ---------------------------------------------------------------------- - -credentials += Credentials( - "Artifactory Realm", - "oss.jfrog.org", - sys.env.getOrElse("OSS_JFROG_USER", ""), - sys.env.getOrElse("OSS_JFROG_PASS", "") -) - -publishTo := { - val jfrog = "https://oss.jfrog.org/artifactory/" - if (isSnapshot.value) - Some("OJO Snapshots" at jfrog + "oss-snapshot-local") - else - Some("OJO Releases" at jfrog + "oss-release-local") -} - -publishMavenStyle := true - -// ---------------------------------------------------------------------- -// Protobuf compilation -// ---------------------------------------------------------------------- - -protobufSettings - -version in protobufConfig := "2.5.0" -runProtoc in protobufConfig := (args => - com.github.os72.protocjar.Protoc.runProtoc("-v250" +: args.toArray) -) - -// ---------------------------------------------------------------------- -// Integration and Multi-JVM testing -// ---------------------------------------------------------------------- - -import com.typesafe.sbt.SbtMultiJvm -import com.typesafe.sbt.SbtMultiJvm.MultiJvmKeys.MultiJvm - -lazy val IntegrTest = config("it") extend(Test) - -evictionWarningOptions in update := EvictionWarningOptions.default - .withWarnTransitiveEvictions(false) - .withWarnDirectEvictions(false) - .withWarnScalaVersionEviction(false) - -lazy val root = (project in file(".")) - .configs(IntegrTest) - .settings(itSettings: _*) - .configs(MultiJvm) - .settings(multiJvmSettings: _*) - -lazy val itSettings = Defaults.itSettings ++ Seq( - comp in IntegrTest <<= (comp in IntegrTest) triggeredBy (comp in Test), - test in IntegrTest <<= (test in IntegrTest) triggeredBy (test in Test), - parallelExecution in IntegrTest := false, - fork in IntegrTest := true -) - -lazy val multiJvmSettings = SbtMultiJvm.multiJvmSettings ++ Seq( - comp in MultiJvm <<= (comp in MultiJvm) triggeredBy (comp in Test), - parallelExecution in Test := false, - executeTests in Test <<= - ((executeTests in Test), (executeTests in MultiJvm)) map { - case ((testResults), (multiJvmResults)) => - val overall = - if (testResults.overall.id < multiJvmResults.overall.id) multiJvmResults.overall - else testResults.overall - Tests.Output(overall, - testResults.events ++ multiJvmResults.events, - testResults.summaries ++ multiJvmResults.summaries) - } -) - -// ---------------------------------------------------------------------- -// Example classpath generation -// ---------------------------------------------------------------------- - -lazy val exampleClasspath = taskKey[Unit]("generate example classpath script") - -exampleClasspath <<= exampleClasspath.dependsOn(comp in Test) - -exampleClasspath := { - import java.nio.file.{Paths, Files, StandardOpenOption} - val cpaths = (fullClasspath in Test value) map (_.data) mkString(":") - val output = - s"""|#!/bin/sh - | - |# this file is automatically generated by the sbt 'exampleClasspath' command - | - |export EXAMPLE_CLASSPATH="$cpaths" - |""".stripMargin - - val fileName = "example/.example-classpath" - val file = Paths.get(fileName) - - Files.write(file, output.getBytes, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING) - file.toFile.setExecutable(true) -} - -// ---------------------------------------------------------------------- -// Source code formatting -// ---------------------------------------------------------------------- - -com.rbmhtechnology.eventuate.Formatting.formatSettings - -// ---------------------------------------------------------------------- -// File headers -// ---------------------------------------------------------------------- - -val header = (HeaderPattern.cStyleBlockComment, - """|/* - | * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - | * - | * Licensed 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. - | */ - | - |""".stripMargin) - -headers := Map( - "scala" -> header, - "java" -> header) - -inConfig(IntegrTest)(SbtHeader.toBeScopedSettings) -inConfig(MultiJvm)(SbtHeader.toBeScopedSettings) - -val createHeaderDep = compileInputs.in(comp) <<= compileInputs.in(comp).dependsOn(createHeaders.in(comp)) - -inConfig(Compile)(createHeaderDep) -inConfig(Test)(createHeaderDep) -inConfig(IntegrTest)(createHeaderDep) -inConfig(MultiJvm)(createHeaderDep) \ No newline at end of file +import sbt._ import sbt.Keys._ import sbtunidoc.Plugin.UnidocKeys._ import MultiJvmKeys._ import ProjectSettings._ import ProjectDependencies._ version in ThisBuild := "0.7-SNAPSHOT" organization in ThisBuild := "com.rbmhtechnology" scalaVersion in ThisBuild := "2.11.7" lazy val root = (project in file(".")) .aggregate(core, crdt, logCassandra, logLeveldb, examples) .dependsOn(core, logCassandra, logLeveldb) .settings(name := "eventuate") .settings(commonSettings: _*) .settings(documentationSettings: _*) .settings(unidocProjectFilter in (ScalaUnidoc, unidoc) := inAnyProject -- inProjects(examples)) .settings(libraryDependencies ++= Seq(AkkaRemote)) .enablePlugins(HeaderPlugin, AutomateHeaderPlugin) lazy val core = (project in file("eventuate-core")) .settings(name := "eventuate-core") .settings(commonSettings: _*) .settings(protocSettings: _*) .settings(integrationTestSettings: _*) .settings(libraryDependencies ++= Seq(AkkaRemote, CommonsIo, Java8Compat, Scalaz)) .settings(libraryDependencies ++= Seq(AkkaTestkit % "test,it", AkkaTestkitMultiNode % "test", Javaslang % "test", JunitInterface % "test", Scalatest % "test,it")) .configs(IntegrationTest, MultiJvm) .enablePlugins(HeaderPlugin, AutomateHeaderPlugin) lazy val logCassandra = (project in file("eventuate-log-cassandra")) .dependsOn(core % "compile->compile;it->it;multi-jvm->multi-jvm") .settings(name := "eventuate-log-cassandra") .settings(commonSettings: _*) .settings(integrationTestSettings: _*) .settings(libraryDependencies ++= Seq(AkkaRemote, CassandraDriver)) .settings(libraryDependencies ++= Seq(AkkaTestkit % "test,it", AkkaTestkitMultiNode % "test", Scalatest % "test,it")) .settings(libraryDependencies ++= Seq(CassandraUnit % "test,it" excludeAll ExclusionRule(organization = "ch.qos.logback"))) .settings(jvmOptions in MultiJvm += "-Dmultinode.server-port=4712") .configs(IntegrationTest, MultiJvm) .enablePlugins(HeaderPlugin, AutomateHeaderPlugin) lazy val logLeveldb = (project in file("eventuate-log-leveldb")) .dependsOn(core % "compile->compile;it->it;multi-jvm->multi-jvm") .settings(name := "eventuate-log-leveldb") .settings(commonSettings: _*) .settings(integrationTestSettings: _*) .settings(libraryDependencies ++= Seq(AkkaRemote, Leveldb)) .settings(libraryDependencies ++= Seq(AkkaTestkit % "test,it", AkkaTestkitMultiNode % "test", Scalatest % "test,it")) .settings(jvmOptions in MultiJvm += "-Dmultinode.server-port=4713") .configs(IntegrationTest, MultiJvm) .enablePlugins(HeaderPlugin, AutomateHeaderPlugin) lazy val crdt = (project in file("eventuate-crdt")) .dependsOn(core % "compile->compile;it->it;multi-jvm->multi-jvm") .dependsOn(logLeveldb % "test;it->it;multi-jvm->multi-jvm") .settings(name := "eventuate-crdt") .settings(commonSettings: _*) .settings(protocSettings: _*) .settings(integrationTestSettings: _*) .settings(libraryDependencies ++= Seq(AkkaRemote)) .settings(libraryDependencies ++= Seq(AkkaTestkit % "test,it", AkkaTestkitMultiNode % "test", Scalatest % "test,it")) .settings(jvmOptions in MultiJvm += "-Dmultinode.server-port=4714") .configs(IntegrationTest, MultiJvm) .enablePlugins(HeaderPlugin, AutomateHeaderPlugin) lazy val examples = (project in file("eventuate-examples")) .dependsOn(core, logLeveldb) .settings(name := "eventuate-examples") .settings(commonSettings: _*) .settings(exampleSettings: _*) .settings(libraryDependencies ++= Seq(AkkaRemote, CassandraDriver, Javaslang)) .enablePlugins(HeaderPlugin, AutomateHeaderPlugin) \ No newline at end of file diff --git a/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorCausalitySpec.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorCausalitySpec.scala similarity index 89% rename from src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorCausalitySpec.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorCausalitySpec.scala index 8beaf809..812b213f 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorCausalitySpec.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorCausalitySpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -40,7 +40,7 @@ object EventsourcedActorCausalitySpec { } } -abstract class EventsourcedActorCausalitySpec extends WordSpec with Matchers with MultiLocationSpec { +trait EventsourcedActorCausalitySpec extends WordSpec with Matchers with MultiLocationSpec { import ReplicationIntegrationSpec.replicationConnection import EventsourcedActorCausalitySpec._ @@ -149,11 +149,3 @@ abstract class EventsourcedActorCausalitySpec extends WordSpec with Matchers wit } } } - -class EventsourcedActorCausalitySpecLeveldb extends EventsourcedActorCausalitySpec with MultiLocationSpecLeveldb { - override val logFactory: String => Props = id => SingleLocationSpecLeveldb.TestEventLog.props(id, batching = true) -} - -class EventsourcedActorCausalitySpecCassandra extends EventsourcedActorCausalitySpec with MultiLocationSpecCassandra { - override val logFactory: String => Props = id => SingleLocationSpecCassandra.TestEventLog.props(id, batching = true) -} diff --git a/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorIntegrationSpec.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorIntegrationSpec.scala similarity index 94% rename from src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorIntegrationSpec.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorIntegrationSpec.scala index 342da101..e8da036c 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorIntegrationSpec.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorIntegrationSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -16,13 +16,13 @@ package com.rbmhtechnology.eventuate -import scala.util._ - import akka.actor._ import akka.testkit._ import org.scalatest._ +import scala.util._ + object EventsourcedActorIntegrationSpec { case class Cmd(payloads: String*) case class State(state: Vector[String]) @@ -47,7 +47,7 @@ object EventsourcedActorIntegrationSpec { class BatchActor(val id: String, val eventLog: ActorRef, probe: ActorRef) extends EventsourcedActor { override def onCommand = { case "boom" => - throw boom + throw IntegrationTestException case Cmd(ps @ _*) => ps.foreach { s => persist(s) { @@ -82,7 +82,7 @@ object EventsourcedActorIntegrationSpec { class ConfirmedDeliveryActor(val id: String, val eventLog: ActorRef, probe: ActorRef) extends EventsourcedActor with ConfirmedDelivery { override def onCommand = { - case "boom" => throw boom + case "boom" => throw IntegrationTestException case "end" => probe ! "end" case "cmd-1" => persist("evt-1")(_ => probe ! "out-1") case "cmd-2" => persist("evt-2")(r => ()) @@ -159,7 +159,7 @@ object EventsourcedActorIntegrationSpec { override def onCommand = { case "boom" => - throw boom + throw IntegrationTestException case "snap" => save(State(state)) { case Success(m) => sender() ! m.sequenceNr case Failure(e) => throw e @@ -188,7 +188,7 @@ object EventsourcedActorIntegrationSpec { override def onCommand = { case "boom" => - throw boom + throw IntegrationTestException case "snap" => save(State(state)) { case Success(m) => sender() ! m.sequenceNr case Failure(e) => throw e @@ -215,7 +215,7 @@ object EventsourcedActorIntegrationSpec { override def onCommand = { case "boom" => - throw boom + throw IntegrationTestException case "state" => probe ! state case s: String => @@ -231,7 +231,7 @@ object EventsourcedActorIntegrationSpec { } } -abstract class EventsourcedActorIntegrationSpec extends TestKit(ActorSystem("test")) with WordSpecLike with Matchers with SingleLocationSpec { +trait EventsourcedActorIntegrationSpec extends TestKitBase with WordSpecLike with Matchers with SingleLocationSpec { import EventsourcedActorIntegrationSpec._ var probe: TestProbe = _ @@ -423,11 +423,3 @@ abstract class EventsourcedActorIntegrationSpec extends TestKit(ActorSystem("tes } } } - -class EventsourcedActorIntegrationSpecLeveldb extends EventsourcedActorIntegrationSpec with SingleLocationSpecLeveldb { - override def batching = false -} - -class EventsourcedActorIntegrationSpecCassandra extends EventsourcedActorIntegrationSpec with SingleLocationSpecCassandra { - override def batching = false -} \ No newline at end of file diff --git a/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorThroughputSpec.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorThroughputSpec.scala similarity index 87% rename from src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorThroughputSpec.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorThroughputSpec.scala index c0eec212..80caaa2b 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorThroughputSpec.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedActorThroughputSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -85,7 +85,7 @@ object EventsourcedActorThroughputSpec { } } -abstract class EventsourcedActorThroughputSpec extends TestKit(ActorSystem("test")) with WordSpecLike with Matchers with SingleLocationSpec { +trait EventsourcedActorThroughputSpec extends TestKitBase with WordSpecLike with Matchers with SingleLocationSpec { import EventsourcedActorThroughputSpec._ var probe: TestProbe = _ @@ -149,6 +149,3 @@ abstract class EventsourcedActorThroughputSpec extends TestKit(ActorSystem("test } } } - -class EventsourcedActorThroughputSpecLeveldb extends EventsourcedActorThroughputSpec with SingleLocationSpecLeveldb -class EventsourcedActorThroughputSpecCassandra extends EventsourcedActorThroughputSpec with SingleLocationSpecCassandra diff --git a/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedProcessorIntegrationSpec.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedProcessorIntegrationSpec.scala similarity index 92% rename from src/it/scala/com/rbmhtechnology/eventuate/EventsourcedProcessorIntegrationSpec.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedProcessorIntegrationSpec.scala index 21a58735..5c120ee6 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedProcessorIntegrationSpec.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/EventsourcedProcessorIntegrationSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -39,7 +39,7 @@ object EventsourcedProcessorIntegrationSpec { class StatelessSampleProcessor(val id: String, val eventLog: ActorRef, val targetEventLog: ActorRef, eventProbe: ActorRef, progressProbe: ActorRef) extends EventsourcedProcessor { override def onCommand = { - case "boom" => throw boom + case "boom" => throw IntegrationTestException case "snap" => save("") { case Success(_) => eventProbe ! "snapped" case Failure(_) => @@ -66,7 +66,7 @@ object EventsourcedProcessorIntegrationSpec { extends StatelessSampleProcessor(id, eventLog, targetEventLog, eventProbe, progressProbe) with StatefulProcessor } -abstract class EventsourcedProcessorIntegrationSpec extends TestKit(ActorSystem("test")) with WordSpecLike with Matchers with SingleLocationSpec { +trait EventsourcedProcessorIntegrationSpec extends TestKitBase with WordSpecLike with Matchers with SingleLocationSpec { import EventsourcedProcessorIntegrationSpec._ def logProps(logId: String): Props @@ -254,17 +254,3 @@ abstract class EventsourcedProcessorIntegrationSpec extends TestKit(ActorSystem( } } } - -class EventsourcedProcessorIntegrationSpecLeveldb extends EventsourcedProcessorIntegrationSpec with SingleLocationSpecLeveldb { - override def beforeEach(): Unit = { - super.beforeEach() - init() - } -} - -class EventsourcedProcessorIntegrationSpecCassandra extends EventsourcedProcessorIntegrationSpec with SingleLocationSpecCassandra { - override def beforeEach(): Unit = { - super.beforeEach() - init() - } -} \ No newline at end of file diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/domain/Asset.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/IntegrationTestException.scala similarity index 56% rename from src/test/scala/com/rbmhtechnology/example/dbreplica/domain/Asset.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/IntegrationTestException.scala index 20dc9ba6..8ca9572b 100644 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/domain/Asset.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/IntegrationTestException.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -14,8 +14,8 @@ * limitations under the License. */ -package com.rbmhtechnology.example.dbreplica.domain +package com.rbmhtechnology.eventuate -case class Asset(id: String, subject: String, content: String) +import scala.util.control.NoStackTrace -class AssetDoesNotExistException(assetId: String) extends RuntimeException(s"asset with id ${assetId} does not exist") \ No newline at end of file +object IntegrationTestException extends Exception("boom") with NoStackTrace diff --git a/src/it/scala/com/rbmhtechnology/eventuate/LocationSpec.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/LocationSpec.scala similarity index 72% rename from src/it/scala/com/rbmhtechnology/eventuate/LocationSpec.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/LocationSpec.scala index 32f81a47..2af4c434 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/LocationSpec.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/LocationSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -19,7 +19,7 @@ package com.rbmhtechnology.eventuate import java.io.File import akka.actor._ -import akka.testkit.{TestProbe, TestKit} +import akka.testkit._ import com.rbmhtechnology.eventuate.ReplicationEndpoint._ import com.rbmhtechnology.eventuate.log._ @@ -55,16 +55,16 @@ object SingleLocationSpec { override def currentSystemTime: Long = 0L abstract override def read(fromSequenceNr: Long, toSequenceNr: Long, max: Int): Future[BatchReadResult] = - if (fromSequenceNr == ErrorSequenceNr) Future.failed(boom) else super.read(fromSequenceNr, toSequenceNr, max) + if (fromSequenceNr == ErrorSequenceNr) Future.failed(IntegrationTestException) else super.read(fromSequenceNr, toSequenceNr, max) abstract override def read(fromSequenceNr: Long, toSequenceNr: Long, max: Int, aggregateId: String): Future[BatchReadResult] = - if (fromSequenceNr == ErrorSequenceNr) Future.failed(boom) else super.read(fromSequenceNr, toSequenceNr, max, aggregateId) + if (fromSequenceNr == ErrorSequenceNr) Future.failed(IntegrationTestException) else super.read(fromSequenceNr, toSequenceNr, max, aggregateId) abstract override def replicationRead(fromSequenceNr: Long, toSequenceNr: Long, max: Int, filter: (DurableEvent) => Boolean): Future[BatchReadResult] = - if (fromSequenceNr == ErrorSequenceNr) Future.failed(boom) else super.replicationRead(fromSequenceNr, toSequenceNr, max, filter) + if (fromSequenceNr == ErrorSequenceNr) Future.failed(IntegrationTestException) else super.replicationRead(fromSequenceNr, toSequenceNr, max, filter) abstract override def write(events: Seq[DurableEvent], partition: Long, clock: EventLogClock): Unit = - if (events.map(_.payload).contains("boom")) throw boom else super.write(events, partition, clock) + if (events.map(_.payload).contains("boom")) throw IntegrationTestException else super.write(events, partition, clock) override private[eventuate] def adjustFromSequenceNr(seqNr: Long) = seqNr match { case ErrorSequenceNr => seqNr @@ -77,6 +77,8 @@ object SingleLocationSpec { trait SingleLocationSpec extends LocationCleanup with BeforeAndAfterEach { private var _logCtr: Int = 0 + implicit val system: ActorSystem + override def beforeEach(): Unit = { super.beforeEach() _logCtr += 1 @@ -102,27 +104,49 @@ trait SingleLocationSpec extends LocationCleanup with BeforeAndAfterEach { _logCtr.toString def log: ActorRef +} - def system: ActorSystem +object MultiLocationConfig { + def create(port: Int = 0, customConfig: Config = ConfigFactory.empty()): Config = { + val defaultConfig = ConfigFactory.parseString( + s""" + |akka.actor.provider = "akka.remote.RemoteActorRefProvider" + |akka.remote.enabled-transports = ["akka.remote.netty.tcp"] + |akka.remote.netty.tcp.hostname = "127.0.0.1" + |akka.remote.netty.tcp.port = ${port} + |akka.remote.retry-gate-closed-for = 300ms + |akka.test.single-expect-default = 20s + |akka.loglevel = "ERROR" + | + |eventuate.log.write-batch-size = 3 + |eventuate.log.replication.retry-delay = 1s + |eventuate.log.replication.failure-detection-limit = 3s + |eventuate.snapshot.filesystem.dir = target/test-snapshot + """.stripMargin) + + customConfig.withFallback(defaultConfig) + } } trait MultiLocationSpec extends LocationCleanup with BeforeAndAfterEach { private var locations: List[Location] = Nil private var ctr: Int = 0 - override def config = - LocationConfig.create(port = 0) - override def beforeEach(): Unit = ctr += 1 override def afterEach(): Unit = locations.foreach(location => Await.result(location.terminate(), 10.seconds)) + override def config = + MultiLocationConfig.create(port = 0, providerConfig) + + def providerConfig: Config + def logFactory: String => Props def location(name: String, customPort: Int = 0, customConfig: Config = ConfigFactory.empty()): Location = { - val location = new Location(locationId(name), logFactory, customPort, customConfig) + val location = new Location(locationId(name), logFactory, customPort, customConfig.withFallback(providerConfig)) registerLocation(location) location } @@ -140,7 +164,7 @@ class Location(val id: String, logFactory: String => Props, customPort: Int, cus import Location._ val system: ActorSystem = - ActorSystem(ReplicationConnection.DefaultRemoteSystemName, LocationConfig.create(customPort, customConfig)) + ActorSystem(ReplicationConnection.DefaultRemoteSystemName, MultiLocationConfig.create(customPort, customConfig)) val port: Int = if (customPort != 0) customPort else system.asInstanceOf[ExtendedActorSystem].provider.getDefaultAddress.port.get diff --git a/src/it/scala/com/rbmhtechnology/eventuate/PersistOnEventIntegrationSpec.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/PersistOnEventIntegrationSpec.scala similarity index 77% rename from src/it/scala/com/rbmhtechnology/eventuate/PersistOnEventIntegrationSpec.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/PersistOnEventIntegrationSpec.scala index d91fa1be..5ae573d8 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/PersistOnEventIntegrationSpec.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/PersistOnEventIntegrationSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -47,7 +47,7 @@ object PersistOnEventIntegrationSpec { } } -abstract class PersistOnEventIntegrationSpec extends TestKit(ActorSystem("test")) with WordSpecLike with Matchers with SingleLocationSpec { +trait PersistOnEventIntegrationSpec extends TestKitBase with WordSpecLike with Matchers with SingleLocationSpec { import PersistOnEventIntegrationSpec._ var probe: TestProbe = _ @@ -68,6 +68,3 @@ abstract class PersistOnEventIntegrationSpec extends TestKit(ActorSystem("test") } } } - -class PersistOnEventIntegrationSpecLeveldb extends PersistOnEventIntegrationSpec with SingleLocationSpecLeveldb -class PersistOnEventIntegrationSpecCassandra extends PersistOnEventIntegrationSpec with SingleLocationSpecCassandra \ No newline at end of file diff --git a/src/it/scala/com/rbmhtechnology/eventuate/ReplicationCycleSpec.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/ReplicationCycleSpec.scala similarity index 87% rename from src/it/scala/com/rbmhtechnology/eventuate/ReplicationCycleSpec.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/ReplicationCycleSpec.scala index ca687f34..c23260b1 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/ReplicationCycleSpec.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/ReplicationCycleSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -22,7 +22,7 @@ import org.scalatest._ import scala.concurrent.Future -abstract class ReplicationCycleSpec extends WordSpec with Matchers with MultiLocationSpec { +trait ReplicationCycleSpec extends WordSpec with Matchers with MultiLocationSpec { import ReplicationIntegrationSpec._ var locationA: Location = _ @@ -84,6 +84,3 @@ abstract class ReplicationCycleSpec extends WordSpec with Matchers with MultiLoc } } } - -class ReplicationCycleSpecLeveldb extends ReplicationCycleSpec with MultiLocationSpecLeveldb -class ReplicationCycleSpecCassandra extends ReplicationCycleSpec with MultiLocationSpecCassandra diff --git a/src/it/scala/com/rbmhtechnology/eventuate/ReplicationIntegrationSpec.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/ReplicationIntegrationSpec.scala similarity index 95% rename from src/it/scala/com/rbmhtechnology/eventuate/ReplicationIntegrationSpec.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/ReplicationIntegrationSpec.scala index cce63e3a..2479b70a 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/ReplicationIntegrationSpec.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/ReplicationIntegrationSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -55,7 +55,7 @@ object ReplicationIntegrationSpec { ReplicationConnection("127.0.0.1", port, filters) } -abstract class ReplicationIntegrationSpec extends WordSpec with Matchers with MultiLocationSpec { +trait ReplicationIntegrationSpec extends WordSpec with Matchers with MultiLocationSpec { import ReplicationIntegrationSpec._ def customPort: Int @@ -286,11 +286,3 @@ abstract class ReplicationIntegrationSpec extends WordSpec with Matchers with Mu locationA.probe } } - -class ReplicationIntegrationSpecLeveldb extends ReplicationIntegrationSpec with MultiLocationSpecLeveldb { - def customPort = 2553 -} - -class ReplicationIntegrationSpecCassandra extends ReplicationIntegrationSpec with MultiLocationSpecCassandra { - def customPort = 2554 -} diff --git a/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogSpec.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogSpec.scala similarity index 71% rename from src/it/scala/com/rbmhtechnology/eventuate/log/EventLogSpec.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogSpec.scala index 64ff0d9b..377773c0 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogSpec.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -27,17 +27,10 @@ import com.rbmhtechnology.eventuate.EventsourcingProtocol._ import com.rbmhtechnology.eventuate.ReplicationFilter.NoFilter import com.rbmhtechnology.eventuate.ReplicationProtocol._ import com.rbmhtechnology.eventuate.SingleLocationSpec._ -import com.rbmhtechnology.eventuate.SingleLocationSpecCassandra._ -import com.rbmhtechnology.eventuate.log.EventLogSpecLeveldb.immediateEventLogClockSnapshotConfig -import com.rbmhtechnology.eventuate.log.cassandra._ -import com.rbmhtechnology.eventuate.utilities.RestarterActor.restartActor import com.rbmhtechnology.eventuate.utilities._ - import com.typesafe.config._ import org.scalatest._ -import org.scalatest.time._ -import org.scalatest.concurrent.Eventually import scala.collection.immutable.Seq @@ -50,15 +43,8 @@ object EventLogSpec { val config: Config = ConfigFactory.parseString( """ |akka.loglevel = "ERROR" - |akka.test.single-expect-default = 10s + |akka.test.single-expect-default = 20s | - |eventuate.log.leveldb.dir = target/test-log - |eventuate.log.leveldb.index-update-limit = 6 - |eventuate.log.leveldb.deletion-batch-size = 2 - |eventuate.log.leveldb.deletion-retry-delay = 1ms - |eventuate.log.cassandra.default-port = 9142 - |eventuate.log.cassandra.index-update-limit = 3 - |eventuate.log.cassandra.init-retry-delay = 1s |eventuate.snapshot.filesystem.dir = target/test-snapshot """.stripMargin) @@ -86,8 +72,6 @@ object EventLogSpec { trait EventLogSpecSupport extends WordSpecLike with Matchers with SingleLocationSpec { import EventLogSpec._ - implicit val system: ActorSystem - var _replyToProbe: TestProbe = _ var _replicatorProbe: TestProbe = _ var _notificationProbe: TestProbe = _ @@ -177,7 +161,7 @@ trait EventLogSpecSupport extends WordSpecLike with Matchers with SingleLocation } } -abstract class EventLogSpec extends TestKit(ActorSystem("test", EventLogSpec.config)) with EventLogSpecSupport { +trait EventLogSpec extends TestKitBase with EventLogSpecSupport { import EventLogSpec._ val dl = system.deadLetters @@ -271,7 +255,7 @@ abstract class EventLogSpec extends TestKit(ActorSystem("test", EventLogSpec.con DurableEvent("okay", emitterIdA)) log ! Write(events, system.deadLetters, replyToProbe.ref, 0, 0) - replyToProbe.expectMsg(WriteFailure(events, boom, 0, 0)) + replyToProbe.expectMsg(WriteFailure(events, IntegrationTestException, 0, 0)) } "write replicated events" in { generateReplicatedEvents() @@ -366,7 +350,7 @@ abstract class EventLogSpec extends TestKit(ActorSystem("test", EventLogSpec.con DurableEvent("okay", emitterIdB, None, Set(), 0L, timestamp(0, 8), remoteLogId, remoteLogId, 8)) log.tell(ReplicationWrite(events, remoteLogId, 8, VectorTime()), replicatorProbe.ref) - replicatorProbe.expectMsg(ReplicationWriteFailure(boom)) + replicatorProbe.expectMsg(ReplicationWriteFailure(IntegrationTestException)) } "reply with a failure message if replication fails and not update the replication progress map" in { log.tell(GetReplicationProgresses, replyToProbe.ref) @@ -376,7 +360,7 @@ abstract class EventLogSpec extends TestKit(ActorSystem("test", EventLogSpec.con DurableEvent("okay", emitterIdB, None, Set(), 0L, timestamp(0, 8), remoteLogId, remoteLogId, 8)) log.tell(ReplicationWrite(events, remoteLogId, 8, VectorTime()), replicatorProbe.ref) - replicatorProbe.expectMsg(ReplicationWriteFailure(boom)) + replicatorProbe.expectMsg(ReplicationWriteFailure(IntegrationTestException)) log.tell(GetReplicationProgresses, replyToProbe.ref) replyToProbe.expectMsg(GetReplicationProgressesSuccess(Map())) } @@ -438,7 +422,7 @@ abstract class EventLogSpec extends TestKit(ActorSystem("test", EventLogSpec.con } "reply with a failure message if replay fails" in { log.tell(Replay(ErrorSequenceNr, None, 0), replyToProbe.ref) - replyToProbe.expectMsg(ReplayFailure(boom, 0)) + replyToProbe.expectMsg(ReplayFailure(IntegrationTestException, 0)) } "replication-read local events" in { generateEmittedEvents() @@ -484,7 +468,7 @@ abstract class EventLogSpec extends TestKit(ActorSystem("test", EventLogSpec.con } "reply with a failure message if replication-read fails" in { log.tell(ReplicationRead(ErrorSequenceNr, Int.MaxValue, NoFilter, UndefinedLogId, dl, VectorTime()), replyToProbe.ref) - replyToProbe.expectMsg(ReplicationReadFailure(boom.getMessage, UndefinedLogId)) + replyToProbe.expectMsg(ReplicationReadFailure(IntegrationTestException.getMessage, UndefinedLogId)) } "recover the current sequence number on (re)start" in { generateEmittedEvents() @@ -597,290 +581,3 @@ abstract class EventLogSpec extends TestKit(ActorSystem("test", EventLogSpec.con } } } - - -object EventLogSpecLeveldb { - val immediateEventLogClockSnapshotConfig = - ConfigFactory.parseString("eventuate.log.leveldb.state-snapshot-limit = 1") -} - -class EventLogSpecLeveldb extends EventLogSpec with SingleLocationSpecLeveldb { - - "A LeveldbEventLog" must { - "not delete events required for restoring the EventLogClock" in { - generateEmittedEvents() - val currentEventLogClock = (log ? GetEventLogClock).mapTo[GetEventLogClockSuccess].await - (log ? Delete(generatedEmittedEvents.last.localSequenceNr)).await - val restartedLog = restartActor(log) - val restoredEventLogClock = (restartedLog ? GetEventLogClock).mapTo[GetEventLogClockSuccess].await - restoredEventLogClock should be(currentEventLogClock) - } - } -} - -class EventLogWithImmediateEventLogClockSnapshotSpecLeveldb - extends TestKit(ActorSystem("test", immediateEventLogClockSnapshotConfig.withFallback(EventLogSpec.config))) - with EventLogSpecSupport with SingleLocationSpecLeveldb with Eventually { - - import EventLogSpec._ - - override implicit def patienceConfig = PatienceConfig(Span(10, Seconds), Span(100, Millis)) - - val dl = system.deadLetters - implicit val implicitTimeout = Timeout(timeoutDuration) - - "A LeveldbEventLog" must { - "actually delete events from the log and an index" in { - generateEmittedEvents(customDestinationAggregateIds = Set("a")) - generateEmittedEvents() - (log ? Delete(generatedEmittedEvents(4).localSequenceNr)).await - eventually { - val probe = TestProbe() - log.tell(Replay(IgnoreDeletedSequenceNr, None, 0), probe.ref) - probe.expectMsg(ReplaySuccess(generatedEmittedEvents.slice(5, 6), generatedEmittedEvents(5).localSequenceNr, 0)) - } - eventually { - val probe = TestProbe() - log.tell(Replay(IgnoreDeletedSequenceNr, None, Some("a"), 0), probe.ref) - probe.expectMsg(ReplaySuccess(Nil, 0L, 0)) - } - } - "actually delete events from the log and an index when overlapping conditional delete and replication requests are sent" in { - generateEmittedEvents(customDestinationAggregateIds = Set("a"), num = 50) - generateEmittedEvents(num = 50) - generatedEmittedEvents.foreach { event => - (log ? Delete(event.localSequenceNr, Set(remoteLogId))).await - log ! ReplicationRead((event.localSequenceNr - 10) max 0, Int.MaxValue, NoFilter, remoteLogId, dl, VectorTime()) - } - log ! ReplicationRead(generatedEmittedEvents.last.localSequenceNr + 1, Int.MaxValue, NoFilter, remoteLogId, dl, VectorTime()) - eventually { - val probe = TestProbe() - log.tell(Replay(IgnoreDeletedSequenceNr, None, 0), probe.ref) - probe.expectMsg(ReplaySuccess(Nil, 0L, 0)) - } - eventually { - val probe = TestProbe() - log.tell(Replay(IgnoreDeletedSequenceNr, None, Some("a"), 0), probe.ref) - probe.expectMsg(ReplaySuccess(Nil, 0L, 0)) - } - } - "not replication-read unconditionally deleted (replicated or local) events" in { - generateEmittedEvents() - generateReplicatedEvents() - (log ? Delete(generatedReplicatedEvents(1).localSequenceNr)).await - eventually { - val probe = TestProbe() - log.tell(ReplicationRead(1, Int.MaxValue, NoFilter, UndefinedLogId, dl, VectorTime()), probe.ref) - probe.expectMsg(ReplicationReadSuccess(List(generatedReplicatedEvents.last), 6, UndefinedLogId, VectorTime(logId -> 3L, remoteLogId -> 9L))) - } - } - "continue with unfinished conditional deletion of replicated events after restart" in { - generateEmittedEvents() - (log ? Delete(generatedEmittedEvents.last.localSequenceNr, Set(remoteLogId))).await - val restartedLog = restartActor(log) - restartedLog ! ReplicationRead(generatedEmittedEvents.last.localSequenceNr + 1, Int.MaxValue, NoFilter, remoteLogId, dl, VectorTime()) - eventually { - val probe = TestProbe() - restartedLog.tell(Replay(IgnoreDeletedSequenceNr, None, 0), probe.ref) - probe.expectMsg(ReplaySuccess(Nil, 0L, 0)) - } - } - "delete events after successful replication if conditionally deleted" in { - generateEmittedEvents() - (log ? Delete(generatedEmittedEvents(1).localSequenceNr, Set(remoteLogId))).await - log.tell(ReplicationRead(1, Int.MaxValue, NoFilter, remoteLogId, dl, VectorTime()), replyToProbe.ref) - replyToProbe.expectMsg(ReplicationReadSuccess(generatedEmittedEvents, 3, remoteLogId, VectorTime(logId -> 3L))) - // indicate that remoteLogId has successfully replicated all events - log.tell(ReplicationRead(generatedEmittedEvents.last.localSequenceNr + 1, Int.MaxValue, NoFilter, remoteLogId, dl, VectorTime()), ActorRef.noSender) - - eventually { - val probe = TestProbe() - log.tell(ReplicationRead(1, Int.MaxValue, NoFilter, "otherLog", dl, VectorTime()), probe.ref) - probe.expectMsg(ReplicationReadSuccess(List(generatedEmittedEvents.last), 3, "otherLog", VectorTime(logId -> 3L))) - } - } - } -} - -class EventLogSpecCassandra extends EventLogSpec with SingleLocationSpecCassandra { - import EventLogSpec._ - import CassandraIndex._ - - var probe: TestProbe = _ - - override def beforeEach(): Unit = { - super.beforeEach() - - probe = TestProbe() - indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 0L), 0)) - } - - def expectReplay(aggregateId: Option[String], payloads: String *): Unit = - expectReplay(1L, aggregateId, payloads: _*) - - def expectReplay(fromSequenceNr: Long, aggregateId: Option[String], payloads: String *): Unit = { - log.tell(Replay(fromSequenceNr, None, aggregateId, 0), replyToProbe.ref) - val act = replyToProbe.expectMsgClass(classOf[ReplaySuccess]).events.map(_.payload) - val exp = payloads.toVector - act should be(exp) - } - - "A Cassandra event log" must { - "serve small replication reads efficiently" in { - val num = 1000 - - val events = 1 to num map { i => - event(s"e-$i", timestamp(i, 0), emitterIdA) - } - - writeEmittedEvents(events) - - 1 to num foreach { i => - log.tell(ReplicationRead(i, 1, NoFilter, "test-target-log-id", dl, VectorTime()), probe.ref) - probe.expectMsgClass(classOf[ReplicationReadSuccess]) - } - } - } - - "A Cassandra event log and its index" must { - "run an index update on initialization" in { - writeEmittedEvents(List(event("a"), event("b"))) - log ! "boom" - indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 2L, versionVector = timestamp(2L)), 1)) - } - "retry an index update on initialization if sequence number read fails" in { - val failureLog = createLog(TestFailureSpec(failOnClockRead = true), indexProbe.ref) - indexProbe.expectMsg(ReadClockFailure(boom)) - indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 0L, versionVector = VectorTime()), 0)) - } - "retry an index update on initialization if index update fails" in { - val failureLog = createLog(TestFailureSpec(failBeforeIndexIncrementWrite = true), indexProbe.ref) - indexProbe.expectMsg(UpdateIndexFailure(boom)) - indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 0L, versionVector = VectorTime()), 0)) - writeEmittedEvents(List(event("a"), event("b")), failureLog) - failureLog ! "boom" - indexProbe.expectMsg(UpdateIndexFailure(boom)) - indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 2L, versionVector = timestamp(2L)), 1)) - } - "run an index update after reaching the update limit with a single event batch" in { - writeEmittedEvents(List(event("a"), event("b"), event("c"), event("d"))) - indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 4L, versionVector = timestamp(4L)), 2)) - } - "run an index update after reaching the update limit with a several event batches" in { - writeEmittedEvents(List(event("a"), event("b"))) - writeEmittedEvents(List(event("c"), event("d"))) - indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 4L, versionVector = timestamp(4L)), 2)) - } - "run an index update on initialization and after reaching the update limit" in { - writeEmittedEvents(List(event("a"), event("b"))) - log ! "boom" - indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 2L, versionVector = timestamp(2L)), 1)) - writeEmittedEvents(List(event("d"), event("e"), event("f"))) - indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 5L, versionVector = timestamp(5L)), 1)) - } - "return the initial value for a replication progress" in { - log.tell(GetReplicationProgress(remoteLogId), probe.ref) - probe.expectMsg(GetReplicationProgressSuccess(remoteLogId, 0L, VectorTime())) - } - "return the updated value for a replication progress" in { - writeReplicatedEvents(List(event("a").remote, event("b").remote), 4L) - log.tell(GetReplicationProgress(remoteLogId), probe.ref) - probe.expectMsg(GetReplicationProgressSuccess(remoteLogId, 4L, VectorTime())) - } - "add events with emitter aggregate id to index" in { - writeEmittedEvents(List( - event("a", None), - event("b", Some("a1")), - event("c", None), - event("d", Some("a1")), - event("e", None), - event("f", Some("a1")))) - - expectReplay(None, "a", "b", "c", "d", "e", "f") - expectReplay(Some("a1"), "b", "d", "f") - } - "add events with custom routing destinations to index" in { - writeEmittedEvents(List( - event("a", None), - event("b", None, Set("a1")), - event("c", None), - event("d", None, Set("a1")), - event("e", None), - event("f", None, Set("a1", "a2")))) - - expectReplay(None, "a", "b", "c", "d", "e", "f") - expectReplay(Some("a1"), "b", "d", "f") - expectReplay(Some("a2"), "f") - } - "add events with emitter aggregate id and custom routing destinations to index" in { - writeEmittedEvents(List( - event("a", None), - event("b", Some("a1"), Set("a2")), - event("c", None), - event("d", Some("a1"), Set("a2")), - event("e", None), - event("f", Some("a1"), Set("a3")))) - - expectReplay(None, "a", "b", "c", "d", "e", "f") - expectReplay(Some("a1"), "b", "d", "f") - expectReplay(Some("a2"), "b", "d") - expectReplay(Some("a3"), "f") - } - "replay aggregate events from log" in { - writeEmittedEvents(List( - event("a", Some("a1")), - event("b", Some("a1")))) - - expectReplay(Some("a1"), "a", "b") - } - "replay aggregate events from index and log" in { - writeEmittedEvents(List( - event("a", Some("a1")), - event("b", Some("a1")), - event("c", Some("a1")))) - - indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 3L, versionVector = timestamp(3L)), 1)) - - writeEmittedEvents(List( - event("d", Some("a1")))) - - expectReplay(Some("a1"), "a", "b", "c", "d") - } - "replay aggregate events from index and log with a lower sequence number bound" in { - writeEmittedEvents(List( - event("a", Some("a1")), - event("b", Some("a1")), - event("c", Some("a1")))) - - indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 3L, versionVector = timestamp(3L)), 1)) - - writeEmittedEvents(List( - event("d", Some("a1")))) - - expectReplay(3L, Some("a1"), "c", "d") - } - "replay aggregate events from index and log in batches" in { - writeEmittedEvents(List( - event("a", Some("a1")), - event("b", Some("a1")), - event("c", Some("a1")))) - - indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 3L, versionVector = timestamp(3L)), 1)) - - writeEmittedEvents(List( - event("d", Some("a1")))) - - log.tell(Replay(1L, 2, None, Some("a1"), 0), replyToProbe.ref) - replyToProbe.expectMsgClass(classOf[ReplaySuccess]).events.map(_.payload) should be (Seq("a", "b")) - log.tell(Replay(3L, 2, None, Some("a1"), 0), replyToProbe.ref) - replyToProbe.expectMsgClass(classOf[ReplaySuccess]).events.map(_.payload) should be (Seq("c", "d")) - } - "replication-read deleted (replicated or local) events" in { - generateEmittedEvents() - generateReplicatedEvents() - (log ? Delete(generatedReplicatedEvents(1).localSequenceNr)).await - log.tell(ReplicationRead(1, Int.MaxValue, NoFilter, UndefinedLogId, dl, VectorTime()), replyToProbe.ref) - replyToProbe.expectMsg(ReplicationReadSuccess(generatedEmittedEvents ++ generatedReplicatedEvents, 6, UndefinedLogId, VectorTime(logId -> 3L, remoteLogId -> 9L))) - } - } -} diff --git a/src/it/scala/com/rbmhtechnology/eventuate/serializer/DurableEventSerializerSpec.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/serializer/DurableEventSerializerSpec.scala similarity index 92% rename from src/it/scala/com/rbmhtechnology/eventuate/serializer/DurableEventSerializerSpec.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/serializer/DurableEventSerializerSpec.scala index d85cdf6d..dc991b73 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/serializer/DurableEventSerializerSpec.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/serializer/DurableEventSerializerSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -101,9 +101,9 @@ class DurableEventSerializerSpec extends WordSpec with Matchers with BeforeAndAf import DurableEventSerializerSpec._ val context = new SerializationContext( - LocationConfig.create(), - LocationConfig.create(customConfig = serializerConfig), - LocationConfig.create(customConfig = serializerWithStringManifestConfig)) + MultiLocationConfig.create(), + MultiLocationConfig.create(customConfig = serializerConfig), + MultiLocationConfig.create(customConfig = serializerWithStringManifestConfig)) override def afterAll(): Unit = context.shutdown() diff --git a/src/it/scala/com/rbmhtechnology/eventuate/serializer/ReplicationFilterSerializerSpec.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/serializer/ReplicationFilterSerializerSpec.scala similarity index 95% rename from src/it/scala/com/rbmhtechnology/eventuate/serializer/ReplicationFilterSerializerSpec.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/serializer/ReplicationFilterSerializerSpec.scala index df895531..b407209e 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/serializer/ReplicationFilterSerializerSpec.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/serializer/ReplicationFilterSerializerSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -21,7 +21,6 @@ import akka.serialization.Serializer import akka.serialization.SerializerWithStringManifest import akka.testkit.TestProbe - import com.rbmhtechnology.eventuate._ import com.rbmhtechnology.eventuate.ReplicationFilter._ import com.rbmhtechnology.eventuate.serializer.SerializationContext.ReceiverActor @@ -122,9 +121,9 @@ class ReplicationFilterSerializerSpec extends WordSpec with Matchers with Before import ReplicationFilterSerializerSpec._ val context = new SerializationContext( - LocationConfig.create(), - LocationConfig.create(customConfig = serializerConfig), - LocationConfig.create(customConfig = serializerWithStringManifestConfig)) + MultiLocationConfig.create(), + MultiLocationConfig.create(customConfig = serializerConfig), + MultiLocationConfig.create(customConfig = serializerWithStringManifestConfig)) override def afterAll(): Unit = context.shutdown() diff --git a/src/it/scala/com/rbmhtechnology/eventuate/serializer/ReplicationProtocolSerializerSpec.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/serializer/ReplicationProtocolSerializerSpec.scala similarity index 96% rename from src/it/scala/com/rbmhtechnology/eventuate/serializer/ReplicationProtocolSerializerSpec.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/serializer/ReplicationProtocolSerializerSpec.scala index 80575ad9..351ce61c 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/serializer/ReplicationProtocolSerializerSpec.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/serializer/ReplicationProtocolSerializerSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -58,8 +58,8 @@ class ReplicationProtocolSerializerSpec extends WordSpec with Matchers with Befo import ReplicationProtocolSerializerSpec._ val context = new SerializationContext( - LocationConfig.create(), - LocationConfig.create()) + MultiLocationConfig.create(), + MultiLocationConfig.create()) override def afterAll(): Unit = context.shutdown() diff --git a/src/it/scala/com/rbmhtechnology/eventuate/serializer/SerializationContext.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/serializer/SerializationContext.scala similarity index 91% rename from src/it/scala/com/rbmhtechnology/eventuate/serializer/SerializationContext.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/serializer/SerializationContext.scala index 6892f518..ae9bfe8b 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/serializer/SerializationContext.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/serializer/SerializationContext.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/it/scala/com/rbmhtechnology/eventuate/serializer/SnapshotSerializerSpec.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/serializer/SnapshotSerializerSpec.scala similarity index 94% rename from src/it/scala/com/rbmhtechnology/eventuate/serializer/SnapshotSerializerSpec.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/serializer/SnapshotSerializerSpec.scala index 776ce9e1..f64937b8 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/serializer/SnapshotSerializerSpec.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/serializer/SnapshotSerializerSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -63,9 +63,9 @@ class SnapshotSerializerSpec extends WordSpec with Matchers with BeforeAndAfterA import SnapshotSerializerSpec._ val context = new SerializationContext( - LocationConfig.create(), - LocationConfig.create(customConfig = serializerConfig), - LocationConfig.create(customConfig = serializerWithStringManifestConfig)) + MultiLocationConfig.create(), + MultiLocationConfig.create(customConfig = serializerConfig), + MultiLocationConfig.create(customConfig = serializerWithStringManifestConfig)) override def afterAll(): Unit = context.shutdown() diff --git a/src/it/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStoreSpec.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStoreSpec.scala similarity index 95% rename from src/it/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStoreSpec.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStoreSpec.scala index 5de8dae1..07b30304 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStoreSpec.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStoreSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -33,7 +33,7 @@ object FilesystemSnapshotStoreSpec { val config: Config = ConfigFactory.parseString( """ |akka.loglevel = "ERROR" - |akka.test.single-expect-default = 10s + |akka.test.single-expect-default = 20s | |eventuate.snapshot.filesystem.dir = target/test-snapshot |eventuate.snapshot.filesystem.snapshots-per-emitter-max = 3 diff --git a/src/it/scala/com/rbmhtechnology/eventuate/utilities/RestarterActor.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/utilities/RestarterActor.scala similarity index 90% rename from src/it/scala/com/rbmhtechnology/eventuate/utilities/RestarterActor.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/utilities/RestarterActor.scala index b099328c..31428330 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/utilities/RestarterActor.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/utilities/RestarterActor.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/it/scala/com/rbmhtechnology/eventuate/utilities/package.scala b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/utilities/package.scala similarity index 94% rename from src/it/scala/com/rbmhtechnology/eventuate/utilities/package.scala rename to eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/utilities/package.scala index ac4da27c..3b6bae5c 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/utilities/package.scala +++ b/eventuate-core/src/it/scala/com/rbmhtechnology/eventuate/utilities/package.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -29,7 +29,6 @@ import scala.concurrent._ import scala.concurrent.duration._ package object utilities { - val timeoutDuration = 10.seconds implicit class AwaitHelper[T](awaitable: Awaitable[T]) { diff --git a/src/main/java/com/rbmhtechnology/eventuate/ProcessBuilder.java b/eventuate-core/src/main/java/com/rbmhtechnology/eventuate/ProcessBuilder.java similarity index 95% rename from src/main/java/com/rbmhtechnology/eventuate/ProcessBuilder.java rename to eventuate-core/src/main/java/com/rbmhtechnology/eventuate/ProcessBuilder.java index 0ed6da02..25fe690a 100644 --- a/src/main/java/com/rbmhtechnology/eventuate/ProcessBuilder.java +++ b/eventuate-core/src/main/java/com/rbmhtechnology/eventuate/ProcessBuilder.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/protobuf/CommonFormats.proto b/eventuate-core/src/main/protobuf/CommonFormats.proto similarity index 100% rename from src/main/protobuf/CommonFormats.proto rename to eventuate-core/src/main/protobuf/CommonFormats.proto diff --git a/src/main/protobuf/DurableEventFormats.proto b/eventuate-core/src/main/protobuf/DurableEventFormats.proto similarity index 100% rename from src/main/protobuf/DurableEventFormats.proto rename to eventuate-core/src/main/protobuf/DurableEventFormats.proto diff --git a/src/main/protobuf/ReplicationFilterFormats.proto b/eventuate-core/src/main/protobuf/ReplicationFilterFormats.proto similarity index 100% rename from src/main/protobuf/ReplicationFilterFormats.proto rename to eventuate-core/src/main/protobuf/ReplicationFilterFormats.proto diff --git a/src/main/protobuf/ReplicationProtocolFormats.proto b/eventuate-core/src/main/protobuf/ReplicationProtocolFormats.proto similarity index 100% rename from src/main/protobuf/ReplicationProtocolFormats.proto rename to eventuate-core/src/main/protobuf/ReplicationProtocolFormats.proto diff --git a/src/main/protobuf/SnapshotFormats.proto b/eventuate-core/src/main/protobuf/SnapshotFormats.proto similarity index 100% rename from src/main/protobuf/SnapshotFormats.proto rename to eventuate-core/src/main/protobuf/SnapshotFormats.proto diff --git a/src/main/resources/reference.conf b/eventuate-core/src/main/resources/reference.conf similarity index 63% rename from src/main/resources/reference.conf rename to eventuate-core/src/main/resources/reference.conf index a96295d4..f6130457 100644 --- a/src/main/resources/reference.conf +++ b/eventuate-core/src/main/resources/reference.conf @@ -5,7 +5,6 @@ akka { eventuate-replication-filter = "com.rbmhtechnology.eventuate.serializer.ReplicationFilterSerializer" eventuate-replication-protocol = "com.rbmhtechnology.eventuate.serializer.ReplicationProtocolSerializer" eventuate-snapshot = "com.rbmhtechnology.eventuate.serializer.SnapshotSerializer" - eventuate-crdt = "com.rbmhtechnology.eventuate.serializer.CRDTSerializer" } serialization-bindings { @@ -15,7 +14,6 @@ akka { "com.rbmhtechnology.eventuate.ConcurrentVersionsTree" = eventuate-snapshot "com.rbmhtechnology.eventuate.Snapshot" = eventuate-snapshot "com.rbmhtechnology.eventuate.log.EventLogClock" = eventuate-snapshot - "com.rbmhtechnology.eventuate.crdt.CRDTFormat" = eventuate-crdt } } } @@ -89,90 +87,6 @@ eventuate { snapshot-deletion-timeout = 30s } - log.leveldb { - # Root directory for storing the log directories of individual event logs. - dir = target - - # Use fsync on write. - fsync = on - - # Minimum number of new events that must have been written before another - # snapshot of the log's internal state (sequence number and merged vector - # time) is written. - state-snapshot-limit = 128 - - # Maximum number of events that are physically deleted in a single batch - # operation. - deletion-batch-size = 100 - - # Delay between two tries to physically delete all requested events while - # keeping those that are not yet replicated. - deletion-retry-delay = 1m - } - - log.cassandra { - # Comma-separated list of contact points in the cluster (comma-separated - # hostname or hostname:port list). - contact-points = ["127.0.0.1"] - - # Default port of contact points in the cluster. Ports defined in - # contact-points override this setting. - default-port = 9042 - - # Default Cassandra username - username = "cassandra" - - # Default Cassandra password - password = "cassandra" - - # Name of the keyspace created/used by Eventuate. - keyspace = "eventuate" - - # Whether or not to auto-create the keyspace. - keyspace-autocreate = true - - # Prefix of all tables created/used by Eventuate. - table-prefix = "log" - - # Replication factor to use when creating the keyspace. - replication-factor = 1 - - # Maximum number of times a failed write should be retried until the event - # log actor gives up and stops itself. The delay between write retries can - # be configured with eventuate.log.write-timeout. - write-retry-max = 65536 - - # Write consistency level - write-consistency = "QUORUM" - - # Read consistency level - read-consistency = "QUORUM" - - # Maximum number of events stored per event log partition. Must be greater - # than eventuate.log.write-batch-size. - partition-size = 131072 - - # Minimum number of new events that must have been written before another - # index update is triggered. - index-update-limit = 64 - - # Maximum number event log initialization retries. Initialization includes - # recovery of the current sequence number and version vector as well as - # indexing of not yet indexed log entries. - init-retry-max = 3 - - # Delay between event log initialization retries. Initialization includes - # recovery of the current sequence number and version vector as well as - # indexing of not yet indexed log entries. - init-retry-delay = 5s - - # Maximum number of initial connection retries to a Cassandra cluster. - connect-retry-max = 3 - - # Delay between initial connection retries to a Cassandra cluster. - connect-retry-delay = 5s - } - log.dispatchers { write-dispatcher { executor = "thread-pool-executor" diff --git a/src/main/scala/akka/actor/MessageStash.scala b/eventuate-core/src/main/scala/akka/actor/MessageStash.scala similarity index 91% rename from src/main/scala/akka/actor/MessageStash.scala rename to eventuate-core/src/main/scala/akka/actor/MessageStash.scala index f1f5e9c7..6b29e988 100644 --- a/src/main/scala/akka/actor/MessageStash.scala +++ b/eventuate-core/src/main/scala/akka/actor/MessageStash.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedActor.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedActor.scala similarity index 96% rename from src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedActor.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedActor.scala index 65527871..101ca8d1 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedActor.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedActor.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedProcessor.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedProcessor.scala similarity index 96% rename from src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedProcessor.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedProcessor.scala index 2a1b08f4..4c2b32c9 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedProcessor.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedProcessor.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedStatefulProcessor.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedStatefulProcessor.scala similarity index 86% rename from src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedStatefulProcessor.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedStatefulProcessor.scala index 49d7eae1..b7614ec7 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedStatefulProcessor.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedStatefulProcessor.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedView.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedView.scala similarity index 98% rename from src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedView.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedView.scala index 65288fb1..b6be4ffd 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedView.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedView.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedWriter.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedWriter.scala similarity index 95% rename from src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedWriter.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedWriter.scala index 31f07497..729047ea 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedWriter.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/AbstractEventsourcedWriter.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/ApplicationVersion.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ApplicationVersion.scala similarity index 89% rename from src/main/scala/com/rbmhtechnology/eventuate/ApplicationVersion.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ApplicationVersion.scala index 28a73707..3325d0f5 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/ApplicationVersion.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ApplicationVersion.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/BehaviorContext.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/BehaviorContext.scala similarity index 93% rename from src/main/scala/com/rbmhtechnology/eventuate/BehaviorContext.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/BehaviorContext.scala index 36af5d89..4cc764d3 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/BehaviorContext.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/BehaviorContext.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -79,4 +79,4 @@ private class StaticBehaviorContext(val initial: Receive) extends BehaviorContex override def unbecome(): Unit = () -} \ No newline at end of file +} diff --git a/src/main/scala/com/rbmhtechnology/eventuate/ConditionalRequest.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ConditionalRequest.scala similarity index 95% rename from src/main/scala/com/rbmhtechnology/eventuate/ConditionalRequest.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ConditionalRequest.scala index 64a004bf..d217e5ce 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/ConditionalRequest.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ConditionalRequest.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/ConfirmedDelivery.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ConfirmedDelivery.scala similarity index 95% rename from src/main/scala/com/rbmhtechnology/eventuate/ConfirmedDelivery.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ConfirmedDelivery.scala index f49379e2..2432170e 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/ConfirmedDelivery.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ConfirmedDelivery.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/DurableEvent.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/DurableEvent.scala similarity index 97% rename from src/main/scala/com/rbmhtechnology/eventuate/DurableEvent.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/DurableEvent.scala index 7f316914..53e9170f 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/DurableEvent.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/DurableEvent.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedActor.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedActor.scala similarity index 98% rename from src/main/scala/com/rbmhtechnology/eventuate/EventsourcedActor.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedActor.scala index a3979cec..cb8fe8a0 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedActor.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedActor.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedClock.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedClock.scala similarity index 95% rename from src/main/scala/com/rbmhtechnology/eventuate/EventsourcedClock.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedClock.scala index 170b9266..7b696f74 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedClock.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedClock.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedProcessor.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedProcessor.scala similarity index 98% rename from src/main/scala/com/rbmhtechnology/eventuate/EventsourcedProcessor.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedProcessor.scala index ada6e31a..43d76f9f 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedProcessor.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedProcessor.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedView.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedView.scala similarity index 98% rename from src/main/scala/com/rbmhtechnology/eventuate/EventsourcedView.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedView.scala index ed69f3aa..a8665351 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedView.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedView.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedWriter.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedWriter.scala similarity index 98% rename from src/main/scala/com/rbmhtechnology/eventuate/EventsourcedWriter.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedWriter.scala index 59777bce..ae08da29 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedWriter.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedWriter.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/EventsourcingProtocol.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcingProtocol.scala similarity index 96% rename from src/main/scala/com/rbmhtechnology/eventuate/EventsourcingProtocol.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcingProtocol.scala index 67e8e212..6f251132 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/EventsourcingProtocol.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcingProtocol.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/PersistOnEvent.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/PersistOnEvent.scala similarity index 97% rename from src/main/scala/com/rbmhtechnology/eventuate/PersistOnEvent.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/PersistOnEvent.scala index 74b5a0de..7fdacdf4 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/PersistOnEvent.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/PersistOnEvent.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/Recovery.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/Recovery.scala similarity index 98% rename from src/main/scala/com/rbmhtechnology/eventuate/Recovery.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/Recovery.scala index b9eb8aad..50992c1f 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/Recovery.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/Recovery.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/ReplicationConnection.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ReplicationConnection.scala similarity index 94% rename from src/main/scala/com/rbmhtechnology/eventuate/ReplicationConnection.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ReplicationConnection.scala index fa5f62c5..fa87a715 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/ReplicationConnection.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ReplicationConnection.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/ReplicationEndpoint.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ReplicationEndpoint.scala similarity index 99% rename from src/main/scala/com/rbmhtechnology/eventuate/ReplicationEndpoint.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ReplicationEndpoint.scala index 14db1807..00677f33 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/ReplicationEndpoint.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ReplicationEndpoint.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/ReplicationFilter.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ReplicationFilter.scala similarity index 94% rename from src/main/scala/com/rbmhtechnology/eventuate/ReplicationFilter.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ReplicationFilter.scala index 8f5124f4..c7a43050 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/ReplicationFilter.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ReplicationFilter.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/ReplicationProtocol.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ReplicationProtocol.scala similarity index 97% rename from src/main/scala/com/rbmhtechnology/eventuate/ReplicationProtocol.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ReplicationProtocol.scala index 537fd352..a3d0ac47 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/ReplicationProtocol.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ReplicationProtocol.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/ResultHandler.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ResultHandler.scala similarity index 95% rename from src/main/scala/com/rbmhtechnology/eventuate/ResultHandler.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ResultHandler.scala index 6fa5aee1..bc3291fd 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/ResultHandler.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/ResultHandler.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/Retry.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/Retry.scala similarity index 85% rename from src/main/scala/com/rbmhtechnology/eventuate/Retry.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/Retry.scala index 757266b1..8f0ce2f8 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/Retry.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/Retry.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/Snapshot.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/Snapshot.scala similarity index 94% rename from src/main/scala/com/rbmhtechnology/eventuate/Snapshot.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/Snapshot.scala index 520f0e41..a911f784 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/Snapshot.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/Snapshot.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/StashError.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/StashError.scala similarity index 81% rename from src/main/scala/com/rbmhtechnology/eventuate/StashError.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/StashError.scala index fe6b669c..da47779a 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/StashError.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/StashError.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/UnavailableException.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/UnavailableException.scala similarity index 81% rename from src/main/scala/com/rbmhtechnology/eventuate/UnavailableException.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/UnavailableException.scala index 3b6a8fb4..93989278 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/UnavailableException.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/UnavailableException.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/VectorClock.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/VectorClock.scala similarity index 97% rename from src/main/scala/com/rbmhtechnology/eventuate/VectorClock.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/VectorClock.scala index cadf1dff..0b907041 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/VectorClock.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/VectorClock.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/Versioned.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/Versioned.scala similarity index 98% rename from src/main/scala/com/rbmhtechnology/eventuate/Versioned.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/Versioned.scala index ce6639c5..2b573e3d 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/Versioned.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/Versioned.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/VersionedAggregate.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/VersionedAggregate.scala similarity index 97% rename from src/main/scala/com/rbmhtechnology/eventuate/VersionedAggregate.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/VersionedAggregate.scala index 81fbea54..f07b42b6 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/VersionedAggregate.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/VersionedAggregate.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/BatchingLayer.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/log/BatchingLayer.scala similarity index 96% rename from src/main/scala/com/rbmhtechnology/eventuate/log/BatchingLayer.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/log/BatchingLayer.scala index 9d2c021e..817fcf24 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/BatchingLayer.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/log/BatchingLayer.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/CircuitBreaker.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/log/CircuitBreaker.scala similarity index 95% rename from src/main/scala/com/rbmhtechnology/eventuate/log/CircuitBreaker.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/log/CircuitBreaker.scala index 3772ad39..c941b03b 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/CircuitBreaker.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/log/CircuitBreaker.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/EventLog.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/log/EventLog.scala similarity index 99% rename from src/main/scala/com/rbmhtechnology/eventuate/log/EventLog.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/log/EventLog.scala index 24069d67..e93307e4 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/EventLog.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/log/EventLog.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/NotificationChannel.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/log/NotificationChannel.scala similarity index 92% rename from src/main/scala/com/rbmhtechnology/eventuate/log/NotificationChannel.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/log/NotificationChannel.scala index 9ba5b165..9c7f664e 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/NotificationChannel.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/log/NotificationChannel.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/SubscriberRegistry.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/log/SubscriberRegistry.scala similarity index 95% rename from src/main/scala/com/rbmhtechnology/eventuate/log/SubscriberRegistry.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/log/SubscriberRegistry.scala index fab944e5..32b810c6 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/SubscriberRegistry.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/log/SubscriberRegistry.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/serializer/CommonSerializer.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/serializer/CommonSerializer.scala similarity index 96% rename from src/main/scala/com/rbmhtechnology/eventuate/serializer/CommonSerializer.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/serializer/CommonSerializer.scala index 7eba3cb8..c91044d1 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/serializer/CommonSerializer.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/serializer/CommonSerializer.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/serializer/DurableEventSerializer.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/serializer/DurableEventSerializer.scala similarity index 96% rename from src/main/scala/com/rbmhtechnology/eventuate/serializer/DurableEventSerializer.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/serializer/DurableEventSerializer.scala index 29490d2a..97b6ea51 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/serializer/DurableEventSerializer.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/serializer/DurableEventSerializer.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/serializer/ReplicationFilterSerializer.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/serializer/ReplicationFilterSerializer.scala similarity index 95% rename from src/main/scala/com/rbmhtechnology/eventuate/serializer/ReplicationFilterSerializer.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/serializer/ReplicationFilterSerializer.scala index a0e35e7b..b3bbcef7 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/serializer/ReplicationFilterSerializer.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/serializer/ReplicationFilterSerializer.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/serializer/ReplicationProtocolSerializer.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/serializer/ReplicationProtocolSerializer.scala similarity index 98% rename from src/main/scala/com/rbmhtechnology/eventuate/serializer/ReplicationProtocolSerializer.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/serializer/ReplicationProtocolSerializer.scala index d06f7aad..d71437a2 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/serializer/ReplicationProtocolSerializer.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/serializer/ReplicationProtocolSerializer.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/serializer/SnapshotSerializer.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/serializer/SnapshotSerializer.scala similarity index 98% rename from src/main/scala/com/rbmhtechnology/eventuate/serializer/SnapshotSerializer.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/serializer/SnapshotSerializer.scala index af13d979..0b651c22 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/serializer/SnapshotSerializer.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/serializer/SnapshotSerializer.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/snapshot/SnapshotStore.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/snapshot/SnapshotStore.scala similarity index 88% rename from src/main/scala/com/rbmhtechnology/eventuate/snapshot/SnapshotStore.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/snapshot/SnapshotStore.scala index 3193e865..7d41700c 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/snapshot/SnapshotStore.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/snapshot/SnapshotStore.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStore.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStore.scala similarity index 96% rename from src/main/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStore.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStore.scala index 6aeb39aa..2e1b0b1e 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStore.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStore.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStoreSettings.scala b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStoreSettings.scala similarity index 89% rename from src/main/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStoreSettings.scala rename to eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStoreSettings.scala index bf1bfc0e..3015d264 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStoreSettings.scala +++ b/eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/snapshot/filesystem/FilesystemSnapshotStoreSettings.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicCausalitySpec.scala b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicCausalitySpec.scala similarity index 76% rename from src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicCausalitySpec.scala rename to eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicCausalitySpec.scala index 32053825..7eb6f9f7 100644 --- a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicCausalitySpec.scala +++ b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicCausalitySpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -22,30 +22,20 @@ import akka.remote.transport.ThrottlerTransportAdapter.Direction import akka.testkit.TestProbe import com.rbmhtechnology.eventuate.ReplicationProtocol.ReplicationEndpointInfo +import com.typesafe.config._ import scala.util._ -class BasicCausalitySpecLeveldb extends BasicCausalitySpec with MultiNodeSupportLeveldb -class BasicCausalitySpecLeveldbMultiJvmNode1 extends BasicCausalitySpecLeveldb -class BasicCausalitySpecLeveldbMultiJvmNode2 extends BasicCausalitySpecLeveldb - -class BasicCausalitySpecCassandra extends BasicCausalitySpec with MultiNodeSupportCassandra { - override def logName = "bc" -} -class BasicCausalitySpecCassandraMultiJvmNode1 extends BasicCausalitySpecCassandra -class BasicCausalitySpecCassandraMultiJvmNode2 extends BasicCausalitySpecCassandra - -object BasicCausalityConfig extends MultiNodeConfig { +class BasicCausalityConfig(providerConfig: Config) extends MultiNodeReplicationConfig { val nodeA = role("nodeA") val nodeB = role("nodeB") testTransport(on = true) - commonConfig(MultiNodeReplicationConfig.create( - """ - |eventuate.log.replication.remote-read-timeout = 2s - """.stripMargin)) + setConfig(ConfigFactory.parseString("eventuate.log.replication.remote-read-timeout = 2s").withFallback(providerConfig)) +} +object BasicCausalitySpec { class ReplicatedActor(val id: String, val eventLog: ActorRef, probe: ActorRef) extends EventsourcedActor { def onCommand = { case s: String => persist(s) { @@ -58,11 +48,11 @@ object BasicCausalityConfig extends MultiNodeConfig { case s: String => probe ! ((s, lastVectorTimestamp, currentVectorTime)) } } - } -abstract class BasicCausalitySpec extends MultiNodeSpec(BasicCausalityConfig) with MultiNodeWordSpec with MultiNodeReplicationEndpoint { - import BasicCausalityConfig._ +abstract class BasicCausalitySpec(config: BasicCausalityConfig) extends MultiNodeSpec(config) with MultiNodeWordSpec with MultiNodeReplicationEndpoint { + import BasicCausalitySpec._ + import config._ val logIdA = ReplicationEndpointInfo.logId(nodeA.name, logName) val logIdB = ReplicationEndpointInfo.logId(nodeB.name, logName) diff --git a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicPersistOnEventSpec.scala b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicPersistOnEventSpec.scala similarity index 70% rename from src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicPersistOnEventSpec.scala rename to eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicPersistOnEventSpec.scala index dd3f7e26..d3ff24dc 100644 --- a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicPersistOnEventSpec.scala +++ b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicPersistOnEventSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -22,25 +22,18 @@ import akka.remote.transport.ThrottlerTransportAdapter.Direction import akka.testkit.TestProbe import com.rbmhtechnology.eventuate.EventsourcedView.Handler +import com.typesafe.config._ -class BasicPersistOnEventSpecLeveldb extends BasicPersistOnEventSpec with MultiNodeSupportLeveldb -class BasicPersistOnEventSpecLeveldbMultiJvmNode1 extends BasicPersistOnEventSpecLeveldb -class BasicPersistOnEventSpecLeveldbMultiJvmNode2 extends BasicPersistOnEventSpecLeveldb - -class BasicPersistOnEventSpecCassandra extends BasicPersistOnEventSpec with MultiNodeSupportCassandra { - override def logName = "bpe" -} -class BasicPersistOnEventSpecCassandraMultiJvmNode1 extends BasicPersistOnEventSpecCassandra -class BasicPersistOnEventSpecCassandraMultiJvmNode2 extends BasicPersistOnEventSpecCassandra - -object BasicPersistOnEventConfig extends MultiNodeConfig { +class BasicPersistOnEventConfig(providerConfig: Config) extends MultiNodeReplicationConfig { val nodeA = role("nodeA") val nodeB = role("nodeB") testTransport(on = true) - commonConfig(MultiNodeReplicationConfig.create("eventuate.log.replication.remote-read-timeout = 2s")) + setConfig(ConfigFactory.parseString("eventuate.log.replication.remote-read-timeout = 2s").withFallback(providerConfig)) +} +object BasicPersistOnEventSpec { case class Ping(num: Int) case class Pong(num: Int) @@ -66,8 +59,9 @@ object BasicPersistOnEventConfig extends MultiNodeConfig { } } -abstract class BasicPersistOnEventSpec extends MultiNodeSpec(BasicPersistOnEventConfig) with MultiNodeWordSpec with MultiNodeReplicationEndpoint { - import BasicPersistOnEventConfig._ +abstract class BasicPersistOnEventSpec(config: BasicPersistOnEventConfig) extends MultiNodeSpec(config) with MultiNodeWordSpec with MultiNodeReplicationEndpoint { + import BasicPersistOnEventSpec._ + import config._ muteDeadLetters(classOf[AnyRef])(system) diff --git a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicReplicationSpec.scala b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicReplicationSpec.scala similarity index 65% rename from src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicReplicationSpec.scala rename to eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicReplicationSpec.scala index df46415f..c5ba20da 100644 --- a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicReplicationSpec.scala +++ b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicReplicationSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -20,27 +20,17 @@ import akka.actor._ import akka.remote.testkit._ import akka.testkit.TestProbe +import com.typesafe.config.Config + import scala.collection.immutable.Seq import scala.util._ -class BasicReplicationSpecLeveldb extends BasicReplicationSpec with MultiNodeSupportLeveldb -class BasicReplicationSpecLeveldbMultiJvmNode1 extends BasicReplicationSpecLeveldb -class BasicReplicationSpecLeveldbMultiJvmNode2 extends BasicReplicationSpecLeveldb -class BasicReplicationSpecLeveldbMultiJvmNode3 extends BasicReplicationSpecLeveldb - -class BasicReplicationSpecCassandra extends BasicReplicationSpec with MultiNodeSupportCassandra { - override def logName = "br" -} -class BasicReplicationSpecCassandraMultiJvmNode1 extends BasicReplicationSpecCassandra -class BasicReplicationSpecCassandraMultiJvmNode2 extends BasicReplicationSpecCassandra -class BasicReplicationSpecCassandraMultiJvmNode3 extends BasicReplicationSpecCassandra - -object BasicReplicationConfig extends MultiNodeConfig { +class BasicReplicationConfig(providerConfig: Config) extends MultiNodeReplicationConfig { val nodeA = role("nodeA") val nodeB = role("nodeB") val nodeC = role("nodeC") - commonConfig(MultiNodeReplicationConfig.create()) + setConfig(providerConfig) } object BasicReplicationSpec { @@ -58,9 +48,9 @@ object BasicReplicationSpec { } } -abstract class BasicReplicationSpec extends MultiNodeSpec(BasicReplicationConfig) with MultiNodeWordSpec with MultiNodeReplicationEndpoint { - import BasicReplicationConfig._ +abstract class BasicReplicationSpec(config: BasicReplicationConfig) extends MultiNodeSpec(config) with MultiNodeWordSpec with MultiNodeReplicationEndpoint { import BasicReplicationSpec._ + import config._ def initialParticipants: Int = roles.size @@ -80,8 +70,8 @@ abstract class BasicReplicationSpec extends MultiNodeSpec(BasicReplicationConfig val endpoint = createEndpoint(nodeA.name, Set(node(nodeB).address.toReplicationConnection)) val actor = system.actorOf(Props(new ReplicatedActor("pa", endpoint.log, probe.ref))) - actor ! ("A1") - actor ! ("A2") + actor ! "A1" + actor ! "A2" } runOn(nodeB) { @@ -90,16 +80,16 @@ abstract class BasicReplicationSpec extends MultiNodeSpec(BasicReplicationConfig node(nodeC).address.toReplicationConnection)) val actor = system.actorOf(Props(new ReplicatedActor("pb", endpoint.log, probe.ref))) - actor ! ("B1") - actor ! ("B2") + actor ! "B1" + actor ! "B2" } runOn(nodeC) { val endpoint = createEndpoint(nodeC.name, Set(node(nodeB).address.toReplicationConnection)) val actor = system.actorOf(Props(new ReplicatedActor("pc", endpoint.log, probe.ref))) - actor ! ("C1") - actor ! ("C2") + actor ! "C1" + actor ! "C2" } val actual = probe.expectMsgAllOf("A1", "A2", "B1", "B2", "C1", "C2") diff --git a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicReplicationThroughputSpec.scala b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicReplicationThroughputSpec.scala similarity index 67% rename from src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicReplicationThroughputSpec.scala rename to eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicReplicationThroughputSpec.scala index 9f22cac6..d43446b1 100644 --- a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicReplicationThroughputSpec.scala +++ b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/BasicReplicationThroughputSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -20,29 +20,13 @@ import akka.actor._ import akka.remote.testkit._ import akka.testkit.TestProbe +import com.typesafe.config._ + import scala.collection.immutable.Seq import scala.concurrent.duration._ import scala.util._ -class BasicReplicationThroughputSpecLeveldb extends BasicReplicationThroughputSpec with MultiNodeSupportLeveldb -class BasicReplicationThroughputSpecLeveldbMultiJvmNode1 extends BasicReplicationThroughputSpecLeveldb -class BasicReplicationThroughputSpecLeveldbMultiJvmNode2 extends BasicReplicationThroughputSpecLeveldb -class BasicReplicationThroughputSpecLeveldbMultiJvmNode3 extends BasicReplicationThroughputSpecLeveldb -class BasicReplicationThroughputSpecLeveldbMultiJvmNode4 extends BasicReplicationThroughputSpecLeveldb -class BasicReplicationThroughputSpecLeveldbMultiJvmNode5 extends BasicReplicationThroughputSpecLeveldb -class BasicReplicationThroughputSpecLeveldbMultiJvmNode6 extends BasicReplicationThroughputSpecLeveldb - -class BasicReplicationThroughputSpecCassandra extends BasicReplicationThroughputSpec with MultiNodeSupportCassandra { - override def logName = "brt" -} -class BasicReplicationThroughputSpecCassandraMultiJvmNode1 extends BasicReplicationThroughputSpecCassandra -class BasicReplicationThroughputSpecCassandraMultiJvmNode2 extends BasicReplicationThroughputSpecCassandra -class BasicReplicationThroughputSpecCassandraMultiJvmNode3 extends BasicReplicationThroughputSpecCassandra -class BasicReplicationThroughputSpecCassandraMultiJvmNode4 extends BasicReplicationThroughputSpecCassandra -class BasicReplicationThroughputSpecCassandraMultiJvmNode5 extends BasicReplicationThroughputSpecCassandra -class BasicReplicationThroughputSpecCassandraMultiJvmNode6 extends BasicReplicationThroughputSpecCassandra - -object BasicReplicationThroughputConfig extends MultiNodeConfig { +class BasicReplicationThroughputConfig(providerConfig: Config) extends MultiNodeReplicationConfig { val nodeA = role("nodeA") val nodeB = role("nodeB") val nodeC = role("nodeC") @@ -50,14 +34,14 @@ object BasicReplicationThroughputConfig extends MultiNodeConfig { val nodeE = role("nodeE") val nodeF = role("nodeF") - commonConfig(MultiNodeReplicationConfig.create( + val customConfig = ConfigFactory.parseString( s""" |akka.remote.netty.tcp.maximum-frame-size = 1048576b - | |eventuate.log.write-batch-size = 2000 |eventuate.log.replication.retry-delay = 10s - |eventuate.log.cassandra.index-update-limit = 200 - """.stripMargin)) + """.stripMargin) + + setConfig(customConfig.withFallback(providerConfig)) } object BasicReplicationThroughputSpec { @@ -89,9 +73,9 @@ object BasicReplicationThroughputSpec { } } -abstract class BasicReplicationThroughputSpec extends MultiNodeSpec(BasicReplicationThroughputConfig) with MultiNodeWordSpec with MultiNodeReplicationEndpoint { - import BasicReplicationThroughputConfig._ +abstract class BasicReplicationThroughputSpec(config: BasicReplicationThroughputConfig) extends MultiNodeSpec(config) with MultiNodeWordSpec with MultiNodeReplicationEndpoint { import BasicReplicationThroughputSpec._ + import config._ def initialParticipants: Int = roles.size diff --git a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/FailureDetectionSpec.scala b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/FailureDetectionSpec.scala similarity index 69% rename from src/multi-jvm/scala/com/rbmhtechnology/eventuate/FailureDetectionSpec.scala rename to eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/FailureDetectionSpec.scala index 03b06330..8e648d9c 100644 --- a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/FailureDetectionSpec.scala +++ b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/FailureDetectionSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -16,35 +16,29 @@ package com.rbmhtechnology.eventuate -import akka.remote.testkit.{MultiNodeSpec, MultiNodeConfig} +import akka.remote.testkit.MultiNodeSpec import akka.remote.transport.ThrottlerTransportAdapter.Direction import akka.testkit.TestProbe -class FailureDetectionSpecLeveldb extends FailureDetectionSpec with MultiNodeSupportLeveldb -class FailureDetectionSpecLeveldbMultiJvmNode1 extends FailureDetectionSpecLeveldb -class FailureDetectionSpecLeveldbMultiJvmNode2 extends FailureDetectionSpecLeveldb +import com.typesafe.config._ -class FailureDetectionSpecCassandra extends FailureDetectionSpec with MultiNodeSupportCassandra { - override def logName = "fd" -} -class FailureDetectionSpecCassandraMultiJvmNode1 extends FailureDetectionSpecCassandra -class FailureDetectionSpecCassandraMultiJvmNode2 extends FailureDetectionSpecCassandra - -object FailureDetectionConfig extends MultiNodeConfig { +class FailureDetectionConfig(providerConfig: Config) extends MultiNodeReplicationConfig { val nodeA = role("nodeA") val nodeB = role("nodeB") testTransport(on = true) - commonConfig(MultiNodeReplicationConfig.create(""" + val customConfig = ConfigFactory.parseString(""" |eventuate.log.replication.remote-read-timeout = 1s |eventuate.log.replication.failure-detection-limit = 3s - """.stripMargin)) + """.stripMargin) + + setConfig(customConfig.withFallback(providerConfig)) } -abstract class FailureDetectionSpec extends MultiNodeSpec(FailureDetectionConfig) with MultiNodeWordSpec with MultiNodeReplicationEndpoint { - import FailureDetectionConfig._ +abstract class FailureDetectionSpec(config: FailureDetectionConfig) extends MultiNodeSpec(config) with MultiNodeWordSpec with MultiNodeReplicationEndpoint { import ReplicationEndpoint._ + import config._ def initialParticipants: Int = roles.size @@ -91,4 +85,4 @@ abstract class FailureDetectionSpec extends MultiNodeSpec(FailureDetectionConfig enterBarrier("finish") } } -} \ No newline at end of file +} diff --git a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/FilteredReplicationSpec.scala b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/FilteredReplicationSpec.scala similarity index 69% rename from src/multi-jvm/scala/com/rbmhtechnology/eventuate/FilteredReplicationSpec.scala rename to eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/FilteredReplicationSpec.scala index cf79056d..9ff8cea2 100644 --- a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/FilteredReplicationSpec.scala +++ b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/FilteredReplicationSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -20,23 +20,15 @@ import akka.actor._ import akka.remote.testkit._ import akka.testkit.TestProbe -import scala.util._ - -class FilteredReplicationSpecLeveldb extends FilteredReplicationSpec with MultiNodeSupportLeveldb -class FilteredReplicationSpecLeveldbMultiJvmNode1 extends FilteredReplicationSpecLeveldb -class FilteredReplicationSpecLeveldbMultiJvmNode2 extends FilteredReplicationSpecLeveldb +import com.typesafe.config._ -class FilteredReplicationSpecCassandra extends FilteredReplicationSpec with MultiNodeSupportCassandra { - override def logName = "fr" -} -class FilteredReplicationSpecCassandraMultiJvmNode1 extends FilteredReplicationSpecCassandra -class FilteredReplicationSpecCassandraMultiJvmNode2 extends FilteredReplicationSpecCassandra +import scala.util._ -object FilteredReplicationConfig extends MultiNodeConfig { +class FilteredReplicationConfig(providerConfig: Config) extends MultiNodeReplicationConfig { val nodeA = role("nodeA") val nodeB = role("nodeB") - commonConfig(MultiNodeReplicationConfig.create()) + setConfig(providerConfig) } object FilteredReplicationSpec { @@ -60,9 +52,9 @@ object FilteredReplicationSpec { } } -abstract class FilteredReplicationSpec extends MultiNodeSpec(FilteredReplicationConfig) with MultiNodeWordSpec with MultiNodeReplicationEndpoint { - import FilteredReplicationConfig._ +abstract class FilteredReplicationSpec(config: FilteredReplicationConfig) extends MultiNodeSpec(config) with MultiNodeWordSpec with MultiNodeReplicationEndpoint { import FilteredReplicationSpec._ + import config._ def initialParticipants: Int = roles.size diff --git a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeReplicationConfig.scala b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeReplicationConfig.scala similarity index 63% rename from src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeReplicationConfig.scala rename to eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeReplicationConfig.scala index 779c840e..0db9ec64 100644 --- a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeReplicationConfig.scala +++ b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeReplicationConfig.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -16,13 +16,14 @@ package com.rbmhtechnology.eventuate +import akka.remote.testkit.MultiNodeConfig import com.typesafe.config._ -object MultiNodeReplicationConfig { - def create(customConfig: String = ""): Config = { +trait MultiNodeReplicationConfig extends MultiNodeConfig { + def setConfig(customConfig: Config): Unit = { val defaultConfig = ConfigFactory.parseString( s""" - |akka.test.single-expect-default = 10s + |akka.test.single-expect-default = 20s |akka.testconductor.barrier-timeout = 60s |akka.loglevel = "ERROR" | @@ -31,13 +32,8 @@ object MultiNodeReplicationConfig { |eventuate.log.replication.failure-detection-limit = 60s | |eventuate.snapshot.filesystem.dir = target/test-snapshot - | - |eventuate.log.leveldb.dir = target/test-log - |eventuate.log.cassandra.default-port = 9142 - |eventuate.log.cassandra.index-update-limit = 3 - |eventuate.log.cassandra.table-prefix = mnt """.stripMargin) - ConfigFactory.parseString(customConfig).withFallback(defaultConfig) + commonConfig(customConfig.withFallback(defaultConfig)) } } diff --git a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeReplicationEndpoint.scala b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeReplicationEndpoint.scala similarity index 91% rename from src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeReplicationEndpoint.scala rename to eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeReplicationEndpoint.scala index edfe66e9..af5b5ef9 100644 --- a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeReplicationEndpoint.scala +++ b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeReplicationEndpoint.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeWordSpec.scala b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeWordSpec.scala similarity index 84% rename from src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeWordSpec.scala rename to eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeWordSpec.scala index f08c6e92..322b4aa6 100644 --- a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeWordSpec.scala +++ b/eventuate-core/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeWordSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedActorSpec.java b/eventuate-core/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedActorSpec.java similarity index 96% rename from src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedActorSpec.java rename to eventuate-core/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedActorSpec.java index 6819e94f..2923fad6 100644 --- a/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedActorSpec.java +++ b/eventuate-core/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedActorSpec.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedProcessorSpec.java b/eventuate-core/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedProcessorSpec.java similarity index 97% rename from src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedProcessorSpec.java rename to eventuate-core/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedProcessorSpec.java index 97295607..8b15c9b1 100644 --- a/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedProcessorSpec.java +++ b/eventuate-core/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedProcessorSpec.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedViewSpec.java b/eventuate-core/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedViewSpec.java similarity index 98% rename from src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedViewSpec.java rename to eventuate-core/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedViewSpec.java index f01a43d6..9b6844b2 100644 --- a/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedViewSpec.java +++ b/eventuate-core/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedViewSpec.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedWriterSpec.java b/eventuate-core/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedWriterSpec.java similarity index 97% rename from src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedWriterSpec.java rename to eventuate-core/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedWriterSpec.java index 1e4ad3bd..d151b42d 100644 --- a/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedWriterSpec.java +++ b/eventuate-core/src/test/java/com/rbmhtechnology/eventuate/AbstractEventsourcedWriterSpec.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/java/com/rbmhtechnology/eventuate/BaseSpec.java b/eventuate-core/src/test/java/com/rbmhtechnology/eventuate/BaseSpec.java similarity index 96% rename from src/test/java/com/rbmhtechnology/eventuate/BaseSpec.java rename to eventuate-core/src/test/java/com/rbmhtechnology/eventuate/BaseSpec.java index 5edeacc7..7ced2105 100644 --- a/src/test/java/com/rbmhtechnology/eventuate/BaseSpec.java +++ b/eventuate-core/src/test/java/com/rbmhtechnology/eventuate/BaseSpec.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/eventuate-core/src/test/resources/reference.conf b/eventuate-core/src/test/resources/reference.conf new file mode 100644 index 00000000..919033a3 --- /dev/null +++ b/eventuate-core/src/test/resources/reference.conf @@ -0,0 +1,2 @@ +akka.loglevel = "ERROR" +akka.test.single-expect-default = 20s diff --git a/src/test/scala/com/rbmhtechnology/eventuate/ApplicationVersionSpec.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/ApplicationVersionSpec.scala similarity index 89% rename from src/test/scala/com/rbmhtechnology/eventuate/ApplicationVersionSpec.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/ApplicationVersionSpec.scala index 8a8324d7..875c03fd 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/ApplicationVersionSpec.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/ApplicationVersionSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/eventuate/BehaviorContextSpec.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/BehaviorContextSpec.scala similarity index 92% rename from src/test/scala/com/rbmhtechnology/eventuate/BehaviorContextSpec.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/BehaviorContextSpec.scala index 0ec7b0b1..52ef20d6 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/BehaviorContextSpec.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/BehaviorContextSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/eventuate/ConcurrentVersionsSpec.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/ConcurrentVersionsSpec.scala similarity index 97% rename from src/test/scala/com/rbmhtechnology/eventuate/ConcurrentVersionsSpec.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/ConcurrentVersionsSpec.scala index 932b167d..3ebc7360 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/ConcurrentVersionsSpec.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/ConcurrentVersionsSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/eventuate/ConditionalRequestsSpec.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/ConditionalRequestsSpec.scala similarity index 96% rename from src/test/scala/com/rbmhtechnology/eventuate/ConditionalRequestsSpec.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/ConditionalRequestsSpec.scala index 8cc57572..af3d205c 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/ConditionalRequestsSpec.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/ConditionalRequestsSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedActorSpec.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedActorSpec.scala similarity index 98% rename from src/test/scala/com/rbmhtechnology/eventuate/EventsourcedActorSpec.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedActorSpec.scala index ae1cd6b8..2043ba00 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedActorSpec.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedActorSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -50,7 +50,7 @@ object EventsourcedActorSpec { val eventLog = logProbe override def onCommand = { - case "boom" => throw boom + case "boom" => throw TestException case "status" => cmdProbe ! (("status", lastVectorTimestamp, currentVectorTime, lastSequenceNr)) case Ping(i) => cmdProbe ! Pong(i) case "test-handler-order" => @@ -69,7 +69,7 @@ object EventsourcedActorSpec { } override def onEvent = { - case "boom" => throw boom + case "boom" => throw TestException case evt if evt != "x" => evtProbe ! ((evt, lastVectorTimestamp, currentVectorTime, lastSequenceNr)) } @@ -91,7 +91,7 @@ object EventsourcedActorSpec { override def onCommand = { case "boom" => - throw boom + throw TestException case "stash-on" => stashing = true case "stash-off" => @@ -129,7 +129,7 @@ object EventsourcedActorSpec { override def onCommand = { case "boom" => - throw boom + throw TestException case "snap" => save(State(state)) { case Success(md) => cmdProbe ! md @@ -749,10 +749,10 @@ class EventsourcedActorSpec extends TestKit(ActorSystem("test", EventsourcedActo val write = logProbe.expectMsgClass(classOf[Write]) val event1 = write.events(0) val event2 = write.events(1) - logProbe.sender() ! WriteFailure(Seq(event1, event2), boom, write.correlationId, instanceId) + logProbe.sender() ! WriteFailure(Seq(event1, event2), TestException, write.correlationId, instanceId) - cmdProbe.expectMsg((boom, event1.vectorTimestamp, event1.vectorTimestamp, event1.localSequenceNr)) - cmdProbe.expectMsg((boom, event2.vectorTimestamp, event2.vectorTimestamp, event2.localSequenceNr)) + cmdProbe.expectMsg((TestException, event1.vectorTimestamp, event1.vectorTimestamp, event1.localSequenceNr)) + cmdProbe.expectMsg((TestException, event2.vectorTimestamp, event2.vectorTimestamp, event2.localSequenceNr)) } "not send empty write commands to log" in { val actor = recoveredEventsourcedActor(stateSync = true) diff --git a/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedProcessorSpec.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedProcessorSpec.scala similarity index 96% rename from src/test/scala/com/rbmhtechnology/eventuate/EventsourcedProcessorSpec.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedProcessorSpec.scala index f0fb5b31..c1a51e09 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedProcessorSpec.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedProcessorSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -128,7 +128,7 @@ class EventsourcedProcessorSpec extends TestKit(ActorSystem("test")) with WordSp def processRead(progress: Long, success: Boolean = true): Unit = { trgProbe.expectMsg(GetReplicationProgress(emitterIdB)) if (success) processResult(GetReplicationProgressSuccess(emitterIdB, progress, VectorTime())) - else processResult(GetReplicationProgressFailure(boom)) + else processResult(GetReplicationProgressFailure(TestException)) } def processWrite(progress: Long, events: Seq[DurableEvent], success: Boolean = true): Unit = { @@ -137,8 +137,8 @@ class EventsourcedProcessorSpec extends TestKit(ActorSystem("test")) with WordSp processResult(ReplicationWriteSuccess(events.size, emitterIdB, progress, VectorTime())) appProbe.expectMsg(progress) } else { - processResult(ReplicationWriteFailure(boom)) - appProbe.expectMsg(boom) + processResult(ReplicationWriteFailure(TestException)) + appProbe.expectMsg(TestException) } } diff --git a/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedViewSpec.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedViewSpec.scala similarity index 98% rename from src/test/scala/com/rbmhtechnology/eventuate/EventsourcedViewSpec.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedViewSpec.scala index d5d4599b..96c58bb0 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedViewSpec.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedViewSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -47,12 +47,12 @@ object EventsourcedViewSpec { } override def onCommand = { - case "boom" => throw boom + case "boom" => throw TestException case Ping(i) => msgProbe ! Pong(i) } override def onEvent = { - case "boom" => throw boom + case "boom" => throw TestException case evt => msgProbe ! ((evt, lastVectorTimestamp, lastSequenceNr)) } } @@ -68,7 +68,7 @@ object EventsourcedViewSpec { override def onCommand = { case "boom" => - throw boom + throw TestException case "stash-on" => stashing = true case "stash-off" => @@ -458,8 +458,8 @@ class EventsourcedViewSpec extends TestKit(ActorSystem("test")) with WordSpecLik logProbe.expectMsg(LoadSnapshot(emitterIdA, instanceId)) logProbe.sender() ! LoadSnapshotSuccess(None, instanceId) logProbe.expectMsg(Replay(1L, Some(actor), instanceId)) - actor ! ReplayFailure(boom, instanceId) - msgProbe.expectMsg(boom) + actor ! ReplayFailure(TestException, instanceId) + msgProbe.expectMsg(TestException) } "support command handler behavior changes" in { val actor = recoveredBehaviorView() diff --git a/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedWriterSpec.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedWriterSpec.scala similarity index 97% rename from src/test/scala/com/rbmhtechnology/eventuate/EventsourcedWriterSpec.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedWriterSpec.scala index c4091df7..45bf7aaf 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedWriterSpec.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/EventsourcedWriterSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -148,7 +148,7 @@ class EventsourcedWriterSpec extends TestKit(ActorSystem("test")) with WordSpecL } "restart on failed read by default" in { val actor = unrecoveredEventsourcedWriter() - processRead(Failure(boom)) + processRead(Failure(TestException)) processRead(Success("rs")) processLoad(actor, instanceId + 1) logProbe.expectMsg(Replay(1L, 2, Some(actor), instanceId + 1)) @@ -161,7 +161,7 @@ class EventsourcedWriterSpec extends TestKit(ActorSystem("test")) with WordSpecL logProbe.expectMsg(Replay(1L, 2, Some(actor), instanceId)) logProbe.sender() ! ReplaySuccess(List(event("a", 1)), 1L, instanceId) appProbe.expectMsg(("a", 1)) - processWrite(Failure(boom)) + processWrite(Failure(TestException)) processRead(Success("rs")) processLoad(actor, instanceId + 1) logProbe.expectMsg(Replay(1L, 2, Some(actor), instanceId + 1)) diff --git a/src/test/scala/com/rbmhtechnology/eventuate/FailureDetectorSpec.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/FailureDetectorSpec.scala similarity index 92% rename from src/test/scala/com/rbmhtechnology/eventuate/FailureDetectorSpec.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/FailureDetectorSpec.scala index 43ffa3be..d11ccd76 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/FailureDetectorSpec.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/FailureDetectorSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/eventuate/PersistOnEventSpec.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/PersistOnEventSpec.scala similarity index 97% rename from src/test/scala/com/rbmhtechnology/eventuate/PersistOnEventSpec.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/PersistOnEventSpec.scala index 84759b93..862c0d6a 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/PersistOnEventSpec.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/PersistOnEventSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -47,7 +47,7 @@ object PersistOnEventSpec { case Failure(e) => throw e } case "boom" => - throw boom + throw TestException } def onEvent = { @@ -77,7 +77,7 @@ object PersistOnEventSpec { // after restart, there is // a PersistOnEventRequest // duplicate in the mailbox - throw boom + throw TestException } else deliverProbe ! unconfirmedRequests } } @@ -212,7 +212,7 @@ class PersistOnEventSpec extends TestKit(ActorSystem("test")) with WordSpecLike // application crash and restart logProbe.sender() ! WriteFailure(Seq( event(write1.events(0).payload, 0L, Some(1L)), - event(write1.events(1).payload, 0L, Some(1L))), boom, write1.correlationId, instanceId) + event(write1.events(1).payload, 0L, Some(1L))), TestException, write1.correlationId, instanceId) processRecover(actor, instanceId + 1, Seq(event("a", 1L))) deliverProbe.expectMsg(Set(1L)) diff --git a/src/test/scala/com/rbmhtechnology/eventuate/ReplicationFilterSpec.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/ReplicationFilterSpec.scala similarity index 91% rename from src/test/scala/com/rbmhtechnology/eventuate/ReplicationFilterSpec.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/ReplicationFilterSpec.scala index 017e9468..87828b68 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/ReplicationFilterSpec.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/ReplicationFilterSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/eventuate/package.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/TestException.scala similarity index 67% rename from src/test/scala/com/rbmhtechnology/eventuate/package.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/TestException.scala index bebf35a0..b430ca67 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/package.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/TestException.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -14,10 +14,8 @@ * limitations under the License. */ -package com.rbmhtechnology +package com.rbmhtechnology.eventuate import scala.util.control.NoStackTrace -package object eventuate { - val boom = new Exception("boom") with NoStackTrace -} +object TestException extends Exception("boom") with NoStackTrace diff --git a/src/test/scala/com/rbmhtechnology/eventuate/VectorClockSpec.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/VectorClockSpec.scala similarity index 92% rename from src/test/scala/com/rbmhtechnology/eventuate/VectorClockSpec.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/VectorClockSpec.scala index 902e9dec..4ec06a2d 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/VectorClockSpec.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/VectorClockSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/eventuate/VectorTimeSpec.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/VectorTimeSpec.scala similarity index 94% rename from src/test/scala/com/rbmhtechnology/eventuate/VectorTimeSpec.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/VectorTimeSpec.scala index 7033e9e0..449c01f0 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/VectorTimeSpec.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/VectorTimeSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/eventuate/log/CircuitBreakerSpec.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/log/CircuitBreakerSpec.scala similarity index 95% rename from src/test/scala/com/rbmhtechnology/eventuate/log/CircuitBreakerSpec.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/log/CircuitBreakerSpec.scala index 86461ae6..3f09111d 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/log/CircuitBreakerSpec.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/log/CircuitBreakerSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/eventuate/log/NotificationChannelSpec.scala b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/log/NotificationChannelSpec.scala similarity index 96% rename from src/test/scala/com/rbmhtechnology/eventuate/log/NotificationChannelSpec.scala rename to eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/log/NotificationChannelSpec.scala index 71c3a28b..669dea4d 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/log/NotificationChannelSpec.scala +++ b/eventuate-core/src/test/scala/com/rbmhtechnology/eventuate/log/NotificationChannelSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/eventuate-crdt/build.sbt b/eventuate-crdt/build.sbt new file mode 100644 index 00000000..799bc244 --- /dev/null +++ b/eventuate-crdt/build.sbt @@ -0,0 +1,2 @@ +// make protobuf definitions of core module available in this module (needed for compilation with protoc) +includePaths in protobufConfig ++= (sourceDirectories in (LocalProject("core"), protobufConfig)).value diff --git a/eventuate-crdt/src/it/resources/application.conf b/eventuate-crdt/src/it/resources/application.conf new file mode 100644 index 00000000..7d8111fe --- /dev/null +++ b/eventuate-crdt/src/it/resources/application.conf @@ -0,0 +1,5 @@ +akka.loglevel = "ERROR" +akka.test.single-expect-default = 20s + +eventuate.log.leveldb.dir = target/test-log +eventuate.snapshot.filesystem.dir = target/test-snapshot diff --git a/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTChaosSpec.scala b/eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTChaosSpecLeveldb.scala similarity index 80% rename from src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTChaosSpec.scala rename to eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTChaosSpecLeveldb.scala index 6853db55..8ac9b1e8 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTChaosSpec.scala +++ b/eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTChaosSpecLeveldb.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -25,25 +25,29 @@ import akka.testkit.TestProbe import com.rbmhtechnology.eventuate._ import com.rbmhtechnology.eventuate.crdt.CRDTService.ValueUpdated import com.rbmhtechnology.eventuate.log._ -import com.rbmhtechnology.eventuate.log.cassandra._ import com.rbmhtechnology.eventuate.log.leveldb._ import com.typesafe.config.ConfigFactory import org.scalatest._ import scala.collection.immutable.Seq -import scala.concurrent.{ExecutionContext, Future} +import scala.concurrent.{ ExecutionContext, Future } -object CRDTChaosSpec { +object CRDTChaosSpecLeveldb { val crdtId = "1" def randomNr(): String = ThreadLocalRandom.current.nextInt(1, 10).toString } -abstract class CRDTChaosSpec extends WordSpec with Matchers with MultiLocationSpec { +class CRDTChaosSpecLeveldb extends WordSpec with Matchers with MultiLocationSpecLeveldb { import ReplicationIntegrationSpec.replicationConnection - import CRDTChaosSpec._ + import CRDTChaosSpecLeveldb._ + + class TestEventLog(id: String) extends LeveldbEventLog(id, "log-test") { + override def write(events: Seq[DurableEvent], partition: Long, clock: EventLogClock): Unit = + if (events.map(_.payload).contains(ValueUpdated(crdtId, AddOp(randomNr())))) throw IntegrationTestException else super.write(events, partition, clock) + } val customConfig = ConfigFactory.parseString( """ @@ -51,6 +55,14 @@ abstract class CRDTChaosSpec extends WordSpec with Matchers with MultiLocationSp |eventuate.log.replication.retry-delay = 100ms """.stripMargin) + override val logFactory: String => Props = + id => logProps(id) + + def logProps(logId: String, batching: Boolean = true): Props = { + val logProps = Props(new TestEventLog(logId)).withDispatcher("eventuate.log.dispatchers.write-dispatcher") + if (batching) Props(new BatchingLayer(logProps)) else logProps + } + def service(endpoint: ReplicationEndpoint): (ORSetService[String], TestProbe) = { implicit val system = endpoint.system @@ -141,37 +153,3 @@ abstract class CRDTChaosSpec extends WordSpec with Matchers with MultiLocationSp } } } - -class CRDTChaosSpecLeveldb extends CRDTChaosSpec with MultiLocationSpecLeveldb { - import CRDTChaosSpec._ - - class TestEventLog(id: String) extends LeveldbEventLog(id, "log-test") { - override def write(events: Seq[DurableEvent], partition: Long, clock: EventLogClock): Unit = - if (events.map(_.payload).contains(ValueUpdated(crdtId, AddOp(randomNr())))) throw boom else super.write(events, partition, clock) - } - - override val logFactory: String => Props = - id => logProps(id) - - def logProps(logId: String, batching: Boolean = true): Props = { - val logProps = Props(new TestEventLog(logId)).withDispatcher("eventuate.log.dispatchers.write-dispatcher") - if (batching) Props(new BatchingLayer(logProps)) else logProps - } -} - -class CRDTChaosSpecCassandra extends CRDTChaosSpec with MultiLocationSpecCassandra { - import CRDTChaosSpec._ - - class TestEventLog(id: String) extends CassandraEventLog(id) { - override def write(events: Seq[DurableEvent], partition: Long, clock: EventLogClock): Unit = - if (events.map(_.payload).contains(ValueUpdated(crdtId, AddOp(randomNr())))) throw boom else super.write(events, partition, clock) - } - - override val logFactory: String => Props = - id => logProps(id) - - def logProps(logId: String, batching: Boolean = true): Props = { - val logProps = Props(new TestEventLog(logId)).withDispatcher("eventuate.log.dispatchers.write-dispatcher") - Props(new CircuitBreaker(logProps, batching)) - } -} diff --git a/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTRecoverySpec.scala b/eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTRecoverySpecLeveldb.scala similarity index 83% rename from src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTRecoverySpec.scala rename to eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTRecoverySpecLeveldb.scala index aec7e797..b112f3a2 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTRecoverySpec.scala +++ b/eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTRecoverySpecLeveldb.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -24,7 +24,7 @@ import com.rbmhtechnology.eventuate.utilities._ import org.scalatest._ -abstract class CRDTRecoverySpec extends TestKit(ActorSystem("test")) with WordSpecLike with Matchers with SingleLocationSpec { +class CRDTRecoverySpecLeveldb extends TestKit(ActorSystem("test")) with WordSpecLike with Matchers with SingleLocationSpecLeveldb { var probe: TestProbe = _ def service(serviceId: String) = new ORSetService[Int](serviceId, log) { @@ -79,6 +79,3 @@ abstract class CRDTRecoverySpec extends TestKit(ActorSystem("test")) with WordSp } } } - -class CRDTRecoverySpecLeveldb extends CRDTRecoverySpec with SingleLocationSpecLeveldb -class CRDTRecoverySpecCassandra extends CRDTRecoverySpec with SingleLocationSpecCassandra diff --git a/src/it/scala/com/rbmhtechnology/eventuate/serializer/CRDTSerializerSpec.scala b/eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTSerializerSpec.scala similarity index 82% rename from src/it/scala/com/rbmhtechnology/eventuate/serializer/CRDTSerializerSpec.scala rename to eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTSerializerSpec.scala index 7a5075c8..0386198b 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/serializer/CRDTSerializerSpec.scala +++ b/eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTSerializerSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -14,16 +14,12 @@ * limitations under the License. */ -package com.rbmhtechnology.eventuate.serializer +package com.rbmhtechnology.eventuate.crdt import akka.serialization.SerializationExtension - import com.rbmhtechnology.eventuate._ -import com.rbmhtechnology.eventuate.crdt._ -import com.rbmhtechnology.eventuate.serializer.DurableEventSerializerSpec.ExamplePayload -import com.rbmhtechnology.eventuate.serializer.DurableEventSerializerSpec.serializerConfig -import com.rbmhtechnology.eventuate.serializer.DurableEventSerializerSpec.serializerWithStringManifestConfig - +import com.rbmhtechnology.eventuate.serializer.DurableEventSerializerSpec._ +import com.rbmhtechnology.eventuate.serializer.SerializationContext import org.scalatest._ object CRDTSerializerSpec { @@ -38,13 +34,12 @@ object CRDTSerializerSpec { } class CRDTSerializerSpec extends WordSpec with Matchers with BeforeAndAfterAll { - import DurableEventSerializerSpec.ExamplePayload import CRDTSerializerSpec._ val context = new SerializationContext( - LocationConfig.create(), - LocationConfig.create(customConfig = serializerConfig), - LocationConfig.create(customConfig = serializerWithStringManifestConfig)) + MultiLocationConfig.create(), + MultiLocationConfig.create(customConfig = serializerConfig), + MultiLocationConfig.create(customConfig = serializerWithStringManifestConfig)) override def afterAll(): Unit = context.shutdown() diff --git a/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTServiceSpec.scala b/eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTServiceSpecLeveldb.scala similarity index 96% rename from src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTServiceSpec.scala rename to eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTServiceSpecLeveldb.scala index 5d8f8220..3ff76063 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTServiceSpec.scala +++ b/eventuate-crdt/src/it/scala/com/rbmhtechnology/eventuate/crdt/CRDTServiceSpecLeveldb.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/protobuf/CRDTFormats.proto b/eventuate-crdt/src/main/protobuf/CRDTFormats.proto similarity index 93% rename from src/main/protobuf/CRDTFormats.proto rename to eventuate-crdt/src/main/protobuf/CRDTFormats.proto index 36c62b6c..abbe1218 100644 --- a/src/main/protobuf/CRDTFormats.proto +++ b/eventuate-crdt/src/main/protobuf/CRDTFormats.proto @@ -14,7 +14,7 @@ * limitations under the License. */ -option java_package = "com.rbmhtechnology.eventuate.serializer"; +option java_package = "com.rbmhtechnology.eventuate.crdt"; option optimize_for = SPEED; import "CommonFormats.proto"; diff --git a/eventuate-crdt/src/main/resources/reference.conf b/eventuate-crdt/src/main/resources/reference.conf new file mode 100644 index 00000000..8424fc17 --- /dev/null +++ b/eventuate-crdt/src/main/resources/reference.conf @@ -0,0 +1,11 @@ +akka { + actor { + serializers { + eventuate-crdt = "com.rbmhtechnology.eventuate.crdt.CRDTSerializer" + } + + serialization-bindings { + "com.rbmhtechnology.eventuate.crdt.CRDTFormat" = eventuate-crdt + } + } +} diff --git a/src/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTFormat.scala b/eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTFormat.scala similarity index 80% rename from src/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTFormat.scala rename to eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTFormat.scala index 6afb774a..280e4ae5 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTFormat.scala +++ b/eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTFormat.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/serializer/CRDTSerializer.scala b/eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTSerializer.scala similarity index 92% rename from src/main/scala/com/rbmhtechnology/eventuate/serializer/CRDTSerializer.scala rename to eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTSerializer.scala index 86aa97bc..2185b6c3 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/serializer/CRDTSerializer.scala +++ b/eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTSerializer.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.rbmhtechnology.eventuate.serializer +package com.rbmhtechnology.eventuate.crdt import akka.actor._ import akka.serialization.Serializer import com.rbmhtechnology.eventuate._ -import com.rbmhtechnology.eventuate.crdt._ -import com.rbmhtechnology.eventuate.serializer.CRDTFormats._ +import com.rbmhtechnology.eventuate.crdt.CRDTFormats._ +import com.rbmhtechnology.eventuate.serializer.CommonSerializer -import scala.collection.JavaConverters._ import scala.collection.immutable.VectorBuilder +import scala.collection.JavaConverters._ class CRDTSerializer(system: ExtendedActorSystem) extends Serializer { val commonSerializer = new CommonSerializer(system) diff --git a/src/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTService.scala b/eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTService.scala similarity index 97% rename from src/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTService.scala rename to eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTService.scala index 35321d0e..786249cc 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTService.scala +++ b/eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/CRDTService.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/crdt/Counter.scala b/eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/Counter.scala similarity index 93% rename from src/main/scala/com/rbmhtechnology/eventuate/crdt/Counter.scala rename to eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/Counter.scala index b2b5a4df..1f723dcf 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/crdt/Counter.scala +++ b/eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/Counter.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/crdt/LWWRegister.scala b/eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/LWWRegister.scala similarity index 96% rename from src/main/scala/com/rbmhtechnology/eventuate/crdt/LWWRegister.scala rename to eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/LWWRegister.scala index e7c6810d..89856753 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/crdt/LWWRegister.scala +++ b/eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/LWWRegister.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/crdt/MVRegister.scala b/eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/MVRegister.scala similarity index 95% rename from src/main/scala/com/rbmhtechnology/eventuate/crdt/MVRegister.scala rename to eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/MVRegister.scala index 8bfb125a..40dd577a 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/crdt/MVRegister.scala +++ b/eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/MVRegister.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/crdt/ORSet.scala b/eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/ORSet.scala similarity index 96% rename from src/main/scala/com/rbmhtechnology/eventuate/crdt/ORSet.scala rename to eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/ORSet.scala index 18cf05e8..ca14f4c5 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/crdt/ORSet.scala +++ b/eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/ORSet.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/crdt/ReplicatedORSetSpec.scala b/eventuate-crdt/src/multi-jvm/scala/com/rbmhtechnology/eventuate/crdt/ReplicatedORSetSpec.scala similarity index 83% rename from src/multi-jvm/scala/com/rbmhtechnology/eventuate/crdt/ReplicatedORSetSpec.scala rename to eventuate-crdt/src/multi-jvm/scala/com/rbmhtechnology/eventuate/crdt/ReplicatedORSetSpec.scala index e9c4de92..989ef73d 100644 --- a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/crdt/ReplicatedORSetSpec.scala +++ b/eventuate-crdt/src/multi-jvm/scala/com/rbmhtechnology/eventuate/crdt/ReplicatedORSetSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -22,32 +22,29 @@ import akka.remote.transport.ThrottlerTransportAdapter.Direction import akka.testkit.TestProbe import com.rbmhtechnology.eventuate._ +import com.typesafe.config.ConfigFactory class ReplicatedORSetSpecLeveldb extends ReplicatedORSetSpec with MultiNodeSupportLeveldb class ReplicatedORSetSpecLeveldbMultiJvmNode1 extends ReplicatedORSetSpecLeveldb class ReplicatedORSetSpecLeveldbMultiJvmNode2 extends ReplicatedORSetSpecLeveldb -class ReplicatedORSetSpecCassandra extends ReplicatedORSetSpec with MultiNodeSupportCassandra { - override def logName = "ros" -} -class ReplicatedORSetSpecCassandraMultiJvmNode1 extends ReplicatedORSetSpecCassandra -class ReplicatedORSetSpecCassandraMultiJvmNode2 extends ReplicatedORSetSpecCassandra - -object ReplicatedORSetConfig extends MultiNodeConfig { +object ReplicatedORSetConfig extends MultiNodeReplicationConfig { val nodeA = role("nodeA") val nodeB = role("nodeB") - testTransport(on = true) - - commonConfig(MultiNodeReplicationConfig.create( + val customConfig = ConfigFactory.parseString( """ |eventuate.log.write-batch-size = 200 |eventuate.log.replication.remote-read-timeout = 2s - """.stripMargin)) + """.stripMargin) + + testTransport(on = true) + + setConfig(customConfig.withFallback(MultiNodeConfigLeveldb.providerConfig)) } abstract class ReplicatedORSetSpec extends MultiNodeSpec(ReplicatedORSetConfig) with MultiNodeWordSpec with MultiNodeReplicationEndpoint { - import BasicReplicationConfig._ + import ReplicatedORSetConfig._ def initialParticipants: Int = roles.size diff --git a/src/test/scala/com/rbmhtechnology/eventuate/crdt/CRDTSpec.scala b/eventuate-crdt/src/test/scala/com/rbmhtechnology/eventuate/crdt/CRDTSpec.scala similarity index 96% rename from src/test/scala/com/rbmhtechnology/eventuate/crdt/CRDTSpec.scala rename to eventuate-crdt/src/test/scala/com/rbmhtechnology/eventuate/crdt/CRDTSpec.scala index a350f0e2..d73cd279 100644 --- a/src/test/scala/com/rbmhtechnology/eventuate/crdt/CRDTSpec.scala +++ b/eventuate-crdt/src/test/scala/com/rbmhtechnology/eventuate/crdt/CRDTSpec.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/eventuate-examples/bin/.example-classpath b/eventuate-examples/bin/.example-classpath new file mode 100755 index 00000000..6d3d1650 --- /dev/null +++ b/eventuate-examples/bin/.example-classpath @@ -0,0 +1,5 @@ +#!/bin/sh + +# this file is automatically generated by the sbt 'generateClasspath' command + +export EXAMPLE_CLASSPATH="/Users/martin/Development/extern/eventuate-temp/eventuate-examples/target/scala-2.11/classes:/Users/martin/Development/extern/eventuate-temp/eventuate-core/target/scala-2.11/classes:/Users/martin/Development/extern/eventuate-temp/eventuate-log-leveldb/target/scala-2.11/classes:/Users/martin/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.11.7.jar:/Users/martin/.ivy2/cache/com.google.protobuf/protobuf-java/bundles/protobuf-java-2.5.0.jar:/Users/martin/.ivy2/cache/com.typesafe.akka/akka-remote_2.11/jars/akka-remote_2.11-2.4.1.jar:/Users/martin/.ivy2/cache/com.typesafe.akka/akka-actor_2.11/jars/akka-actor_2.11-2.4.1.jar:/Users/martin/.ivy2/cache/com.typesafe/config/bundles/config-1.3.0.jar:/Users/martin/.ivy2/cache/com.typesafe.akka/akka-protobuf_2.11/jars/akka-protobuf_2.11-2.4.1.jar:/Users/martin/.ivy2/cache/io.netty/netty/bundles/netty-3.10.3.Final.jar:/Users/martin/.ivy2/cache/org.uncommons.maths/uncommons-maths/jars/uncommons-maths-1.2.2a.jar:/Users/martin/.ivy2/cache/commons-io/commons-io/jars/commons-io-2.4.jar:/Users/martin/.ivy2/cache/org.scala-lang.modules/scala-java8-compat_2.11/bundles/scala-java8-compat_2.11-0.7.0.jar:/Users/martin/.ivy2/cache/org.scalaz/scalaz-core_2.11/bundles/scalaz-core_2.11-7.1.0.jar:/Users/martin/.ivy2/cache/org.scala-lang.modules/scala-parser-combinators_2.11/bundles/scala-parser-combinators_2.11-1.0.2.jar:/Users/martin/.ivy2/cache/org.scala-lang.modules/scala-xml_2.11/bundles/scala-xml_2.11-1.0.2.jar:/Users/martin/.ivy2/cache/org.fusesource.leveldbjni/leveldbjni-all/bundles/leveldbjni-all-1.8.jar:/Users/martin/.ivy2/cache/com.datastax.cassandra/cassandra-driver-core/bundles/cassandra-driver-core-2.1.5.jar:/Users/martin/.ivy2/cache/com.google.guava/guava/bundles/guava-14.0.1.jar:/Users/martin/.ivy2/cache/com.codahale.metrics/metrics-core/bundles/metrics-core-3.0.2.jar:/Users/martin/.ivy2/cache/org.slf4j/slf4j-api/jars/slf4j-api-1.7.5.jar:/Users/martin/.ivy2/cache/com.javaslang/javaslang/jars/javaslang-2.0.0-RC3.jar" diff --git a/example/ordermgnt b/eventuate-examples/bin/ordermgnt similarity index 61% rename from example/ordermgnt rename to eventuate-examples/bin/ordermgnt index 544c49a6..1537e114 100755 --- a/example/ordermgnt +++ b/eventuate-examples/bin/ordermgnt @@ -1,17 +1,17 @@ #!/bin/sh # generate example classpath script only once -sbt exampleClasspath +sbt generateClasspath for location in A B C D E F do if command -v osascript >/dev/null 2>&1; then osascript -e "tell app \"Terminal\" - do script \"cd `pwd`; ./example/ordermgnt-location $* $location\" + do script \"cd `pwd`; ./eventuate-examples/bin/ordermgnt-location $* $location\" end tell" else if command -v xterm >/dev/null 2>&1; then - xterm -title "location $location" -e "./example/ordermgnt-location $* $location" & + xterm -title "location $location" -e "./eventuate-examples/bin/ordermgnt-location $* $location" & else echo "Neither osascript nor xterm were found"; fi diff --git a/example/ordermgnt-location b/eventuate-examples/bin/ordermgnt-location similarity index 78% rename from example/ordermgnt-location rename to eventuate-examples/bin/ordermgnt-location index 1a691485..cb2532f9 100755 --- a/example/ordermgnt-location +++ b/eventuate-examples/bin/ordermgnt-location @@ -21,10 +21,10 @@ done EXAMPLE_CONF=ordermgnt/location-$1.conf -if [[ ! -f ./example/.example-classpath ]]; then - sbt exampleClasspath || exit 1 +if [[ ! -f ./eventuate-examples/bin/.example-classpath ]]; then + sbt generateClasspath || exit 1 fi -source ./example/.example-classpath +source ./eventuate-examples/bin/.example-classpath exec java -cp "$EXAMPLE_CLASSPATH" $EXAMPLE_MAIN $EXAMPLE_CONF $EXAMPLE_MODE diff --git a/src/test/java/com/rbmhtechnology/example/japi/ordermgnt/Order.java b/eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/Order.java similarity index 91% rename from src/test/java/com/rbmhtechnology/example/japi/ordermgnt/Order.java rename to eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/Order.java index fd6ae12c..8cc4611b 100644 --- a/src/test/java/com/rbmhtechnology/example/japi/ordermgnt/Order.java +++ b/eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/Order.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderActor.java b/eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderActor.java similarity index 98% rename from src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderActor.java rename to eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderActor.java index 11b4ea86..9cb72d17 100644 --- a/src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderActor.java +++ b/eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderActor.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderExample.java b/eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderExample.java similarity index 97% rename from src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderExample.java rename to eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderExample.java index f2d84144..c99a0cf7 100644 --- a/src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderExample.java +++ b/eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderExample.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderId.java b/eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderId.java similarity index 82% rename from src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderId.java rename to eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderId.java index a677c709..058d43a3 100644 --- a/src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderId.java +++ b/eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderId.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderManager.java b/eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderManager.java similarity index 96% rename from src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderManager.java rename to eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderManager.java index f4bc1e3e..33d6102e 100644 --- a/src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderManager.java +++ b/eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderManager.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderSerializer.java b/eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderSerializer.java similarity index 92% rename from src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderSerializer.java rename to eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderSerializer.java index 7271b662..d7d1c312 100644 --- a/src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderSerializer.java +++ b/eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderSerializer.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderView.java b/eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderView.java similarity index 93% rename from src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderView.java rename to eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderView.java index 55e78393..f5df5d4a 100644 --- a/src/test/java/com/rbmhtechnology/example/japi/ordermgnt/OrderView.java +++ b/eventuate-examples/src/main/java/com/rbmhtechnology/example/japi/ordermgnt/OrderView.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/resources/log4j.properties b/eventuate-examples/src/main/resources/log4j.properties similarity index 100% rename from src/test/resources/log4j.properties rename to eventuate-examples/src/main/resources/log4j.properties diff --git a/src/test/resources/ordermgnt/location-A.conf b/eventuate-examples/src/main/resources/ordermgnt/location-A.conf similarity index 100% rename from src/test/resources/ordermgnt/location-A.conf rename to eventuate-examples/src/main/resources/ordermgnt/location-A.conf diff --git a/src/test/resources/ordermgnt/location-B.conf b/eventuate-examples/src/main/resources/ordermgnt/location-B.conf similarity index 100% rename from src/test/resources/ordermgnt/location-B.conf rename to eventuate-examples/src/main/resources/ordermgnt/location-B.conf diff --git a/src/test/resources/ordermgnt/location-C.conf b/eventuate-examples/src/main/resources/ordermgnt/location-C.conf similarity index 100% rename from src/test/resources/ordermgnt/location-C.conf rename to eventuate-examples/src/main/resources/ordermgnt/location-C.conf diff --git a/src/test/resources/ordermgnt/location-D.conf b/eventuate-examples/src/main/resources/ordermgnt/location-D.conf similarity index 100% rename from src/test/resources/ordermgnt/location-D.conf rename to eventuate-examples/src/main/resources/ordermgnt/location-D.conf diff --git a/src/test/resources/ordermgnt/location-E.conf b/eventuate-examples/src/main/resources/ordermgnt/location-E.conf similarity index 100% rename from src/test/resources/ordermgnt/location-E.conf rename to eventuate-examples/src/main/resources/ordermgnt/location-E.conf diff --git a/src/test/resources/ordermgnt/location-F.conf b/eventuate-examples/src/main/resources/ordermgnt/location-F.conf similarity index 100% rename from src/test/resources/ordermgnt/location-F.conf rename to eventuate-examples/src/main/resources/ordermgnt/location-F.conf diff --git a/src/test/scala/com/rbmhtechnology/example/ordermgnt/Order.scala b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/Order.scala similarity index 86% rename from src/test/scala/com/rbmhtechnology/example/ordermgnt/Order.scala rename to eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/Order.scala index 8d8f93bc..f7b542b1 100644 --- a/src/test/scala/com/rbmhtechnology/example/ordermgnt/Order.scala +++ b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/Order.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/example/ordermgnt/OrderActor.scala b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/OrderActor.scala similarity index 97% rename from src/test/scala/com/rbmhtechnology/example/ordermgnt/OrderActor.scala rename to eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/OrderActor.scala index 8036105e..c68a2668 100644 --- a/src/test/scala/com/rbmhtechnology/example/ordermgnt/OrderActor.scala +++ b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/OrderActor.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/example/ordermgnt/OrderExample.scala b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/OrderExample.scala similarity index 96% rename from src/test/scala/com/rbmhtechnology/example/ordermgnt/OrderExample.scala rename to eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/OrderExample.scala index 88ac7b74..7cc2599e 100644 --- a/src/test/scala/com/rbmhtechnology/example/ordermgnt/OrderExample.scala +++ b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/OrderExample.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/example/ordermgnt/OrderManager.scala b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/OrderManager.scala similarity index 94% rename from src/test/scala/com/rbmhtechnology/example/ordermgnt/OrderManager.scala rename to eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/OrderManager.scala index 5d4cf63d..7ae94bd4 100644 --- a/src/test/scala/com/rbmhtechnology/example/ordermgnt/OrderManager.scala +++ b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/OrderManager.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/example/ordermgnt/OrderView.scala b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/OrderView.scala similarity index 90% rename from src/test/scala/com/rbmhtechnology/example/ordermgnt/OrderView.scala rename to eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/OrderView.scala index f6000b38..8f0e69d8 100644 --- a/src/test/scala/com/rbmhtechnology/example/ordermgnt/OrderView.scala +++ b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/OrderView.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/example/ordermgnt/package.scala b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/package.scala similarity index 85% rename from src/test/scala/com/rbmhtechnology/example/ordermgnt/package.scala rename to eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/package.scala index 8eefc74a..25c4aa6e 100644 --- a/src/test/scala/com/rbmhtechnology/example/ordermgnt/package.scala +++ b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/package.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/example/querydb/Emitter.scala b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/querydb/Emitter.scala similarity index 92% rename from src/test/scala/com/rbmhtechnology/example/querydb/Emitter.scala rename to eventuate-examples/src/main/scala/com/rbmhtechnology/example/querydb/Emitter.scala index 267bebcd..fc72cbdd 100644 --- a/src/test/scala/com/rbmhtechnology/example/querydb/Emitter.scala +++ b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/querydb/Emitter.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/scala/com/rbmhtechnology/example/querydb/Writer.scala b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/querydb/Writer.scala similarity index 79% rename from src/test/scala/com/rbmhtechnology/example/querydb/Writer.scala rename to eventuate-examples/src/main/scala/com/rbmhtechnology/example/querydb/Writer.scala index e562846a..597cbbe0 100644 --- a/src/test/scala/com/rbmhtechnology/example/querydb/Writer.scala +++ b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/querydb/Writer.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -33,7 +33,7 @@ import scala.concurrent.Future class Writer(val id: String, val eventLog: ActorRef, session: Session) extends EventsourcedWriter[Long, Unit] { - import com.rbmhtechnology.eventuate.log.cassandra.{ listenableFutureToFuture => ftr } + import Writer._ import context.dispatcher val insertCustomerStmt = session.prepare( @@ -84,8 +84,8 @@ class Writer(val id: String, val eventLog: ActorRef, session: Session) override def write(): Future[Unit] = { val snr = lastSequenceNr val res = for { - _ <- Future.sequence(batch.map(stmt => ftr(session.executeAsync(stmt)))) - _ <- session.executeAsync(updateProgressStmt.bind(snr: JLong)) + _ <- Future.sequence(batch.map(stmt => session.executeAsync(stmt).toFuture)) + _ <- session.executeAsync(updateProgressStmt.bind(snr: JLong)).toFuture } yield () batch = Vector.empty // clear batch res @@ -96,7 +96,7 @@ class Writer(val id: String, val eventLog: ActorRef, session: Session) * once during writer initialization (after start or restart). */ override def read(): Future[Long] = { - session.executeAsync("SELECT sequence_nr FROM PROGRESS WHERE id = 0") + session.executeAsync("SELECT sequence_nr FROM PROGRESS WHERE id = 0").toFuture .map(rs => if (rs.isExhausted) 0L else rs.one().getLong(0)) } @@ -107,4 +107,25 @@ class Writer(val id: String, val eventLog: ActorRef, session: Session) override def readSuccess(result: Long): Option[Long] = Some(result + 1L) } + +object Writer { + import java.util.concurrent.Executor + + import com.google.common.util.concurrent.ListenableFuture + + import scala.concurrent.{ ExecutionContext, Promise } + import scala.language.implicitConversions + import scala.util.Try + + implicit class ListenableFutureConverter[A](lf: ListenableFuture[A])(implicit executionContext: ExecutionContext) { + + def toFuture: Future[A] = { + val promise = Promise[A] + lf.addListener(new Runnable { + def run() = promise.complete(Try(lf.get())) + }, executionContext.asInstanceOf[Executor]) + promise.future + } + } +} //# diff --git a/src/test/scala/com/rbmhtechnology/example/querydb/WriterApp.scala b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/querydb/WriterApp.scala similarity index 95% rename from src/test/scala/com/rbmhtechnology/example/querydb/WriterApp.scala rename to eventuate-examples/src/main/scala/com/rbmhtechnology/example/querydb/WriterApp.scala index 2398e5ca..141bdbea 100644 --- a/src/test/scala/com/rbmhtechnology/example/querydb/WriterApp.scala +++ b/eventuate-examples/src/main/scala/com/rbmhtechnology/example/querydb/WriterApp.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/it/resources/application.conf b/eventuate-log-cassandra/src/it/resources/application.conf similarity index 67% rename from src/it/resources/application.conf rename to eventuate-log-cassandra/src/it/resources/application.conf index 2511c23b..311d717e 100644 --- a/src/it/resources/application.conf +++ b/eventuate-log-cassandra/src/it/resources/application.conf @@ -1,8 +1,6 @@ akka.loglevel = "ERROR" -akka.test.single-expect-default = 10s +akka.test.single-expect-default = 20s -eventuate.snapshot.filesystem.dir = target/test-snapshot - -eventuate.log.leveldb.dir = target/test-log eventuate.log.cassandra.default-port = 9142 eventuate.log.cassandra.index-update-limit = 100 +eventuate.snapshot.filesystem.dir = target/test-snapshot diff --git a/src/it/resources/log4j.properties b/eventuate-log-cassandra/src/it/resources/log4j.properties similarity index 100% rename from src/it/resources/log4j.properties rename to eventuate-log-cassandra/src/it/resources/log4j.properties diff --git a/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecCassandra.scala b/eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecCassandra.scala similarity index 89% rename from src/it/scala/com/rbmhtechnology/eventuate/LocationSpecCassandra.scala rename to eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecCassandra.scala index ab0741e5..51df3857 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecCassandra.scala +++ b/eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecCassandra.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -65,10 +65,8 @@ object SingleLocationSpecCassandra { override def currentSystemTime: Long = 0L override def unhandled(message: Any): Unit = message match { - case "boom" => - throw boom - case _ => - super.unhandled(message) + case "boom" => throw IntegrationTestException + case _ => super.unhandled(message) } private[eventuate] override def createIndexStore(cassandra: Cassandra, logId: String) = @@ -85,19 +83,19 @@ object SingleLocationSpecCassandra { override def writeAsync(aggregateEvents: AggregateEvents, clock: EventLogClock)(implicit executor: ExecutionContext): Future[EventLogClock] = if (failureSpec.failBeforeIndexIncrementWrite && !writeIncrementFailed) { writeIncrementFailed = true - Future.failed(boom) + Future.failed(IntegrationTestException) } else if (failureSpec.failAfterIndexIncrementWrite && !writeIncrementFailed) { writeIncrementFailed = true for { _ <- super.writeAsync(aggregateEvents, clock) - r <- Future.failed(boom) + r <- Future.failed(IntegrationTestException) } yield r } else super.writeAsync(aggregateEvents, clock) override def readEventLogClockAsync(implicit executor: ExecutionContext): Future[EventLogClock] = if (failureSpec.failOnClockRead && !readClockFailed) { readClockFailed = true - Future.failed(boom) + Future.failed(IntegrationTestException) } else super.readEventLogClockAsync } } @@ -138,6 +136,12 @@ trait SingleLocationSpecCassandra extends SingleLocationSpec with LocationCleanu trait MultiLocationSpecCassandra extends MultiLocationSpec with LocationCleanupCassandra { override val logFactory: String => Props = id => CassandraEventLog.props(id) + override val providerConfig = ConfigFactory.parseString( + s""" + |eventuate.log.cassandra.default-port = 9142 + |eventuate.log.cassandra.index-update-limit = 3 + """.stripMargin) + override def beforeAll(): Unit = { super.beforeAll() EmbeddedCassandraServerHelper.startEmbeddedCassandra(60000) diff --git a/eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecsCassandra.scala b/eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecsCassandra.scala new file mode 100644 index 00000000..425d15a5 --- /dev/null +++ b/eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecsCassandra.scala @@ -0,0 +1,52 @@ +/* + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * + * Licensed 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 com.rbmhtechnology.eventuate + +import akka.actor.{Props, ActorSystem} +import akka.testkit.TestKit + +// -------------------------------------------------------------------------- +// Provider-specific single-location specs +// -------------------------------------------------------------------------- + +class EventsourcedProcessorIntegrationSpecCassandra extends TestKit(ActorSystem("test")) with EventsourcedProcessorIntegrationSpec with SingleLocationSpecCassandra { + override def beforeEach(): Unit = { + super.beforeEach() + init() + } +} + +class EventsourcedActorIntegrationSpecCassandra extends TestKit(ActorSystem("test")) with EventsourcedActorIntegrationSpec with SingleLocationSpecCassandra { + override def batching = false +} + +class PersistOnEventIntegrationSpecCassandra extends TestKit(ActorSystem("test")) with PersistOnEventIntegrationSpec with SingleLocationSpecCassandra +class EventsourcedActorThroughputSpecCassandra extends TestKit(ActorSystem("test")) with EventsourcedActorThroughputSpec with SingleLocationSpecCassandra + +// -------------------------------------------------------------------------- +// Provider-specific multi-location specs +// -------------------------------------------------------------------------- + +class EventsourcedActorCausalitySpecCassandra extends EventsourcedActorCausalitySpec with MultiLocationSpecCassandra { + override val logFactory: String => Props = id => SingleLocationSpecCassandra.TestEventLog.props(id, batching = true) +} + +class ReplicationIntegrationSpecCassandra extends ReplicationIntegrationSpec with MultiLocationSpecCassandra { + def customPort = 2554 +} + +class ReplicationCycleSpecCassandra extends ReplicationCycleSpec with MultiLocationSpecCassandra diff --git a/src/it/scala/com/rbmhtechnology/eventuate/log/CircuitBreakerIntregrationSpec.scala b/eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/log/CircuitBreakerIntregrationSpecCassandra.scala similarity index 97% rename from src/it/scala/com/rbmhtechnology/eventuate/log/CircuitBreakerIntregrationSpec.scala rename to eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/log/CircuitBreakerIntregrationSpecCassandra.scala index b5e78979..e28db5d9 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/log/CircuitBreakerIntregrationSpec.scala +++ b/eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/log/CircuitBreakerIntregrationSpecCassandra.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -19,12 +19,12 @@ package com.rbmhtechnology.eventuate.log import java.util.concurrent.CountDownLatch import akka.actor._ -import akka.testkit._ import akka.pattern.ask +import akka.testkit._ import akka.util.Timeout -import com.rbmhtechnology.eventuate._ import com.rbmhtechnology.eventuate.ReplicationProtocol._ +import com.rbmhtechnology.eventuate._ import com.rbmhtechnology.eventuate.log.cassandra._ import com.rbmhtechnology.eventuate.utilities.AwaitHelper import com.typesafe.config._ @@ -44,7 +44,7 @@ object CircuitBreakerIntregrationSpecCassandra { val config: Config = ConfigFactory.parseString( """ |akka.loglevel = "ERROR" - |akka.test.single-expect-default = 10s + |akka.test.single-expect-default = 20s | |eventuate.log.circuit-breaker.open-after-retries = 2 |eventuate.log.cassandra.write-retry-max = 3 @@ -266,4 +266,4 @@ class CircuitBreakerIntregrationSpecCassandra extends TestKit(ActorSystem("test" def request(actor: ActorRef, command: String): Future[String] = actor.ask(command).mapTo[String] -} \ No newline at end of file +} diff --git a/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogPartitioningSpec.scala b/eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogPartitioningSpecCassandra.scala similarity index 94% rename from src/it/scala/com/rbmhtechnology/eventuate/log/EventLogPartitioningSpec.scala rename to eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogPartitioningSpecCassandra.scala index 0d9cd488..77e2f95d 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogPartitioningSpec.scala +++ b/eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogPartitioningSpecCassandra.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -17,11 +17,10 @@ package com.rbmhtechnology.eventuate.log import akka.actor.ActorSystem -import akka.testkit.{TestProbe, TestKit} +import akka.testkit.{ TestKit, TestProbe } import com.rbmhtechnology.eventuate.EventsourcingProtocol._ import com.rbmhtechnology.eventuate.SingleLocationSpecCassandra - import com.typesafe.config._ import scala.collection.immutable.Seq @@ -30,7 +29,7 @@ object EventLogPartitioningSpecCassandra { val config: Config = ConfigFactory.parseString( """ |akka.loglevel = "ERROR" - |akka.test.single-expect-default = 10s + |akka.test.single-expect-default = 20s | |eventuate.snapshot.filesystem.dir = target/test-snapshot | @@ -102,4 +101,3 @@ class EventLogPartitioningSpecCassandra extends TestKit(ActorSystem("test", Even } } } - diff --git a/eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogSpecCassandra.scala b/eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogSpecCassandra.scala new file mode 100644 index 00000000..6d641455 --- /dev/null +++ b/eventuate-log-cassandra/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogSpecCassandra.scala @@ -0,0 +1,223 @@ +/* + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * + * Licensed 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 com.rbmhtechnology.eventuate.log + +import akka.actor._ +import akka.testkit._ +import akka.pattern.ask + +import com.rbmhtechnology.eventuate._ +import com.rbmhtechnology.eventuate.DurableEvent._ +import com.rbmhtechnology.eventuate.EventsourcingProtocol._ +import com.rbmhtechnology.eventuate.ReplicationFilter.NoFilter +import com.rbmhtechnology.eventuate.ReplicationProtocol._ +import com.rbmhtechnology.eventuate.SingleLocationSpecCassandra.TestFailureSpec +import com.rbmhtechnology.eventuate.log.cassandra.CassandraIndex +import com.rbmhtechnology.eventuate.utilities._ +import com.typesafe.config._ + +object EventLogSpecCassandra { + val config: Config = ConfigFactory.parseString( + """ + |eventuate.log.cassandra.default-port = 9142 + |eventuate.log.cassandra.index-update-limit = 3 + |eventuate.log.cassandra.init-retry-delay = 1s + """.stripMargin).withFallback(EventLogSpec.config) +} + +class EventLogSpecCassandra extends TestKit(ActorSystem("test", EventLogSpecCassandra.config)) with EventLogSpec with SingleLocationSpecCassandra { + import EventLogSpec._ + import CassandraIndex._ + + var probe: TestProbe = _ + + override def beforeEach(): Unit = { + super.beforeEach() + + probe = TestProbe() + indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 0L), 0)) + } + + def expectReplay(aggregateId: Option[String], payloads: String *): Unit = + expectReplay(1L, aggregateId, payloads: _*) + + def expectReplay(fromSequenceNr: Long, aggregateId: Option[String], payloads: String *): Unit = { + log.tell(Replay(fromSequenceNr, None, aggregateId, 0), replyToProbe.ref) + val act = replyToProbe.expectMsgClass(classOf[ReplaySuccess]).events.map(_.payload) + val exp = payloads.toVector + act should be(exp) + } + + "A Cassandra event log" must { + "serve small replication reads efficiently" in { + val num = 1000 + + val events = 1 to num map { i => + event(s"e-$i", timestamp(i, 0), emitterIdA) + } + + writeEmittedEvents(events) + + 1 to num foreach { i => + log.tell(ReplicationRead(i, 1, NoFilter, "test-target-log-id", dl, VectorTime()), probe.ref) + probe.expectMsgClass(classOf[ReplicationReadSuccess]) + } + } + } + + "A Cassandra event log and its index" must { + "run an index update on initialization" in { + writeEmittedEvents(List(event("a"), event("b"))) + log ! "boom" + indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 2L, versionVector = timestamp(2L)), 1)) + } + "retry an index update on initialization if sequence number read fails" in { + val failureLog = createLog(TestFailureSpec(failOnClockRead = true), indexProbe.ref) + indexProbe.expectMsg(ReadClockFailure(IntegrationTestException)) + indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 0L, versionVector = VectorTime()), 0)) + } + "retry an index update on initialization if index update fails" in { + val failureLog = createLog(TestFailureSpec(failBeforeIndexIncrementWrite = true), indexProbe.ref) + indexProbe.expectMsg(UpdateIndexFailure(IntegrationTestException)) + indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 0L, versionVector = VectorTime()), 0)) + writeEmittedEvents(List(event("a"), event("b")), failureLog) + failureLog ! "boom" + indexProbe.expectMsg(UpdateIndexFailure(IntegrationTestException)) + indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 2L, versionVector = timestamp(2L)), 1)) + } + "run an index update after reaching the update limit with a single event batch" in { + writeEmittedEvents(List(event("a"), event("b"), event("c"), event("d"))) + indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 4L, versionVector = timestamp(4L)), 2)) + } + "run an index update after reaching the update limit with a several event batches" in { + writeEmittedEvents(List(event("a"), event("b"))) + writeEmittedEvents(List(event("c"), event("d"))) + indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 4L, versionVector = timestamp(4L)), 2)) + } + "run an index update on initialization and after reaching the update limit" in { + writeEmittedEvents(List(event("a"), event("b"))) + log ! "boom" + indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 2L, versionVector = timestamp(2L)), 1)) + writeEmittedEvents(List(event("d"), event("e"), event("f"))) + indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 5L, versionVector = timestamp(5L)), 1)) + } + "return the initial value for a replication progress" in { + log.tell(GetReplicationProgress(remoteLogId), probe.ref) + probe.expectMsg(GetReplicationProgressSuccess(remoteLogId, 0L, VectorTime())) + } + "return the updated value for a replication progress" in { + writeReplicatedEvents(List(event("a").remote, event("b").remote), 4L) + log.tell(GetReplicationProgress(remoteLogId), probe.ref) + probe.expectMsg(GetReplicationProgressSuccess(remoteLogId, 4L, VectorTime())) + } + "add events with emitter aggregate id to index" in { + writeEmittedEvents(List( + event("a", None), + event("b", Some("a1")), + event("c", None), + event("d", Some("a1")), + event("e", None), + event("f", Some("a1")))) + + expectReplay(None, "a", "b", "c", "d", "e", "f") + expectReplay(Some("a1"), "b", "d", "f") + } + "add events with custom routing destinations to index" in { + writeEmittedEvents(List( + event("a", None), + event("b", None, Set("a1")), + event("c", None), + event("d", None, Set("a1")), + event("e", None), + event("f", None, Set("a1", "a2")))) + + expectReplay(None, "a", "b", "c", "d", "e", "f") + expectReplay(Some("a1"), "b", "d", "f") + expectReplay(Some("a2"), "f") + } + "add events with emitter aggregate id and custom routing destinations to index" in { + writeEmittedEvents(List( + event("a", None), + event("b", Some("a1"), Set("a2")), + event("c", None), + event("d", Some("a1"), Set("a2")), + event("e", None), + event("f", Some("a1"), Set("a3")))) + + expectReplay(None, "a", "b", "c", "d", "e", "f") + expectReplay(Some("a1"), "b", "d", "f") + expectReplay(Some("a2"), "b", "d") + expectReplay(Some("a3"), "f") + } + "replay aggregate events from log" in { + writeEmittedEvents(List( + event("a", Some("a1")), + event("b", Some("a1")))) + + expectReplay(Some("a1"), "a", "b") + } + "replay aggregate events from index and log" in { + writeEmittedEvents(List( + event("a", Some("a1")), + event("b", Some("a1")), + event("c", Some("a1")))) + + indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 3L, versionVector = timestamp(3L)), 1)) + + writeEmittedEvents(List( + event("d", Some("a1")))) + + expectReplay(Some("a1"), "a", "b", "c", "d") + } + "replay aggregate events from index and log with a lower sequence number bound" in { + writeEmittedEvents(List( + event("a", Some("a1")), + event("b", Some("a1")), + event("c", Some("a1")))) + + indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 3L, versionVector = timestamp(3L)), 1)) + + writeEmittedEvents(List( + event("d", Some("a1")))) + + expectReplay(3L, Some("a1"), "c", "d") + } + "replay aggregate events from index and log in batches" in { + writeEmittedEvents(List( + event("a", Some("a1")), + event("b", Some("a1")), + event("c", Some("a1")))) + + indexProbe.expectMsg(UpdateIndexSuccess(EventLogClock(sequenceNr = 3L, versionVector = timestamp(3L)), 1)) + + writeEmittedEvents(List( + event("d", Some("a1")))) + + log.tell(Replay(1L, 2, None, Some("a1"), 0), replyToProbe.ref) + replyToProbe.expectMsgClass(classOf[ReplaySuccess]).events.map(_.payload) should be (Seq("a", "b")) + log.tell(Replay(3L, 2, None, Some("a1"), 0), replyToProbe.ref) + replyToProbe.expectMsgClass(classOf[ReplaySuccess]).events.map(_.payload) should be (Seq("c", "d")) + } + "replication-read deleted (replicated or local) events" in { + generateEmittedEvents() + generateReplicatedEvents() + (log ? Delete(generatedReplicatedEvents(1).localSequenceNr)).await + log.tell(ReplicationRead(1, Int.MaxValue, NoFilter, UndefinedLogId, dl, VectorTime()), replyToProbe.ref) + replyToProbe.expectMsg(ReplicationReadSuccess(generatedEmittedEvents ++ generatedReplicatedEvents, 6, UndefinedLogId, VectorTime(logId -> 3L, remoteLogId -> 9L))) + } + } +} diff --git a/eventuate-log-cassandra/src/main/resources/reference.conf b/eventuate-log-cassandra/src/main/resources/reference.conf new file mode 100644 index 00000000..63a01675 --- /dev/null +++ b/eventuate-log-cassandra/src/main/resources/reference.conf @@ -0,0 +1,80 @@ +eventuate { + log.cassandra { + # Comma-separated list of contact points in the cluster (comma-separated + # hostname or hostname:port list). + contact-points = ["127.0.0.1"] + + # Default port of contact points in the cluster. Ports defined in + # contact-points override this setting. + default-port = 9042 + + # Default Cassandra username + username = "cassandra" + + # Default Cassandra password + password = "cassandra" + + # Name of the keyspace created/used by Eventuate. + keyspace = "eventuate" + + # Whether or not to auto-create the keyspace. + keyspace-autocreate = true + + # Prefix of all tables created/used by Eventuate. + table-prefix = "log" + + # Replication factor to use when creating the keyspace. + replication-factor = 1 + + # Maximum number of times a failed write should be retried until the event + # log actor gives up and stops itself. The delay between write retries can + # be configured with eventuate.log.write-timeout. + write-retry-max = 65536 + + # Write consistency level + write-consistency = "QUORUM" + + # Read consistency level + read-consistency = "QUORUM" + + # Maximum number of events stored per event log partition. Must be greater + # than eventuate.log.write-batch-size. + partition-size = 131072 + + # Minimum number of new events that must have been written before another + # index update is triggered. + index-update-limit = 64 + + # Maximum number event log initialization retries. Initialization includes + # recovery of the current sequence number and version vector as well as + # indexing of not yet indexed log entries. + init-retry-max = 3 + + # Delay between event log initialization retries. Initialization includes + # recovery of the current sequence number and version vector as well as + # indexing of not yet indexed log entries. + init-retry-delay = 5s + + # Maximum number of initial connection retries to a Cassandra cluster. + connect-retry-max = 3 + + # Delay between initial connection retries to a Cassandra cluster. + connect-retry-delay = 5s + } + + log.dispatchers { + write-dispatcher { + executor = "thread-pool-executor" + type = PinnedDispatcher + } + + read-dispatcher { + type = Dispatcher + executor = "fork-join-executor" + fork-join-executor { + parallelism-min = 2 + parallelism-max = 16 + } + } + } +} diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/Cassandra.scala b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/Cassandra.scala similarity index 98% rename from src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/Cassandra.scala rename to eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/Cassandra.scala index 7b795bdf..0e63efdc 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/Cassandra.scala +++ b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/Cassandra.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraDeletedToStore.scala b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraDeletedToStore.scala similarity index 88% rename from src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraDeletedToStore.scala rename to eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraDeletedToStore.scala index abe5763d..f36594b3 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraDeletedToStore.scala +++ b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraDeletedToStore.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLog.scala b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLog.scala similarity index 98% rename from src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLog.scala rename to eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLog.scala index f2039bbf..6fe7bd6b 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLog.scala +++ b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLog.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLogSettings.scala b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLogSettings.scala similarity index 96% rename from src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLogSettings.scala rename to eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLogSettings.scala index 03898ad9..28aafa84 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLogSettings.scala +++ b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLogSettings.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLogStore.scala b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLogStore.scala similarity index 96% rename from src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLogStore.scala rename to eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLogStore.scala index e519f239..18157b70 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLogStore.scala +++ b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraEventLogStore.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraIndex.scala b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraIndex.scala similarity index 97% rename from src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraIndex.scala rename to eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraIndex.scala index 4e58e74f..7ecc36df 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraIndex.scala +++ b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraIndex.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraIndexStore.scala b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraIndexStore.scala similarity index 96% rename from src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraIndexStore.scala rename to eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraIndexStore.scala index a7f3908b..acafc5cd 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraIndexStore.scala +++ b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraIndexStore.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraReplicationProgressStore.scala b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraReplicationProgressStore.scala similarity index 91% rename from src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraReplicationProgressStore.scala rename to eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraReplicationProgressStore.scala index ab3f27e2..49330909 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraReplicationProgressStore.scala +++ b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraReplicationProgressStore.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraStatements.scala b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraStatements.scala similarity index 96% rename from src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraStatements.scala rename to eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraStatements.scala index aed3562f..f508cda7 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraStatements.scala +++ b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/CassandraStatements.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/package.scala b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/package.scala similarity index 87% rename from src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/package.scala rename to eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/package.scala index 45f1ace3..956e5ca6 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/package.scala +++ b/eventuate-log-cassandra/src/main/scala/com/rbmhtechnology/eventuate/log/cassandra/package.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/multi-jvm/resources/log4j.properties b/eventuate-log-cassandra/src/multi-jvm/resources/log4j.properties similarity index 100% rename from src/multi-jvm/resources/log4j.properties rename to eventuate-log-cassandra/src/multi-jvm/resources/log4j.properties diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdcSettings.scala b/eventuate-log-cassandra/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeConfigCassandra.scala similarity index 51% rename from src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdcSettings.scala rename to eventuate-log-cassandra/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeConfigCassandra.scala index 5c617a7e..2302a037 100644 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdcSettings.scala +++ b/eventuate-log-cassandra/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeConfigCassandra.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -14,13 +14,15 @@ * limitations under the License. */ -package com.rbmhtechnology.example.dbreplica.cdc +package com.rbmhtechnology.eventuate -import com.rbmhtechnology.eventuate.ReplicationEndpoint -import com.rbmhtechnology.eventuate.ReplicationProtocol.ReplicationEndpointInfo import com.typesafe.config._ -class AssetCdcSettings(config: Config) { - val logId: String = - ReplicationEndpointInfo.logId(config.getString("eventuate.endpoint.id"), ReplicationEndpoint.DefaultLogName) +object MultiNodeConfigCassandra { + val providerConfig: Config = ConfigFactory.parseString( + s""" + |eventuate.log.cassandra.default-port = 9142 + |eventuate.log.cassandra.index-update-limit = 3 + |eventuate.log.cassandra.table-prefix = mnt + """.stripMargin) } diff --git a/eventuate-log-cassandra/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSpecsCassandra.scala b/eventuate-log-cassandra/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSpecsCassandra.scala new file mode 100644 index 00000000..7e1f1f14 --- /dev/null +++ b/eventuate-log-cassandra/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSpecsCassandra.scala @@ -0,0 +1,67 @@ +/* + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * + * Licensed 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 com.rbmhtechnology.eventuate + +import com.typesafe.config.ConfigFactory + +import MultiNodeConfigCassandra._ + +class BasicReplicationSpecCassandra extends BasicReplicationSpec(new BasicReplicationConfig(providerConfig)) with MultiNodeSupportCassandra { + override def logName = "br" +} +class BasicReplicationSpecCassandraMultiJvmNode1 extends BasicReplicationSpecCassandra +class BasicReplicationSpecCassandraMultiJvmNode2 extends BasicReplicationSpecCassandra +class BasicReplicationSpecCassandraMultiJvmNode3 extends BasicReplicationSpecCassandra + +object BasicReplicationThroughputSpecCassandra { + val config = ConfigFactory.parseString("eventuate.log.cassandra.index-update-limit = 200") +} +class BasicReplicationThroughputSpecCassandra extends BasicReplicationThroughputSpec(new BasicReplicationThroughputConfig(BasicReplicationThroughputSpecCassandra.config.withFallback(providerConfig))) with MultiNodeSupportCassandra { + override def logName = "brt" +} +class BasicReplicationThroughputSpecCassandraMultiJvmNode1 extends BasicReplicationThroughputSpecCassandra +class BasicReplicationThroughputSpecCassandraMultiJvmNode2 extends BasicReplicationThroughputSpecCassandra +class BasicReplicationThroughputSpecCassandraMultiJvmNode3 extends BasicReplicationThroughputSpecCassandra +class BasicReplicationThroughputSpecCassandraMultiJvmNode4 extends BasicReplicationThroughputSpecCassandra +class BasicReplicationThroughputSpecCassandraMultiJvmNode5 extends BasicReplicationThroughputSpecCassandra +class BasicReplicationThroughputSpecCassandraMultiJvmNode6 extends BasicReplicationThroughputSpecCassandra + + +class BasicCausalitySpecCassandra extends BasicCausalitySpec(new BasicCausalityConfig(providerConfig)) with MultiNodeSupportCassandra { + override def logName = "bc" +} +class BasicCausalitySpecCassandraMultiJvmNode1 extends BasicCausalitySpecCassandra +class BasicCausalitySpecCassandraMultiJvmNode2 extends BasicCausalitySpecCassandra + +class BasicPersistOnEventSpecCassandra extends BasicPersistOnEventSpec(new BasicPersistOnEventConfig(providerConfig)) with MultiNodeSupportCassandra { + override def logName = "bpe" +} +class BasicPersistOnEventSpecCassandraMultiJvmNode1 extends BasicPersistOnEventSpecCassandra +class BasicPersistOnEventSpecCassandraMultiJvmNode2 extends BasicPersistOnEventSpecCassandra + +class FailureDetectionSpecCassandra extends FailureDetectionSpec(new FailureDetectionConfig(providerConfig)) with MultiNodeSupportCassandra { + override def logName = "fd" +} +class FailureDetectionSpecCassandraMultiJvmNode1 extends FailureDetectionSpecCassandra +class FailureDetectionSpecCassandraMultiJvmNode2 extends FailureDetectionSpecCassandra + +class FilteredReplicationSpecCassandra extends FilteredReplicationSpec(new FilteredReplicationConfig(providerConfig)) with MultiNodeSupportCassandra { + override def logName = "fr" +} +class FilteredReplicationSpecCassandraMultiJvmNode1 extends FilteredReplicationSpecCassandra +class FilteredReplicationSpecCassandraMultiJvmNode2 extends FilteredReplicationSpecCassandra + diff --git a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSupport.scala b/eventuate-log-cassandra/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSupportCassandra.scala similarity index 62% rename from src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSupport.scala rename to eventuate-log-cassandra/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSupportCassandra.scala index a122af12..371704e3 100644 --- a/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSupport.scala +++ b/eventuate-log-cassandra/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSupportCassandra.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -22,36 +22,12 @@ import akka.actor.Props import akka.remote.testconductor.RoleName import akka.remote.testkit.MultiNodeSpec -import com.rbmhtechnology.eventuate.log.cassandra.{Cassandra, CassandraEventLog} -import com.rbmhtechnology.eventuate.log.leveldb.LeveldbEventLog +import com.rbmhtechnology.eventuate.log.cassandra._ import org.apache.commons.io.FileUtils import org.cassandraunit.utils.EmbeddedCassandraServerHelper - import org.scalatest.BeforeAndAfterAll -trait MultiNodeSupportLeveldb extends BeforeAndAfterAll { this: MultiNodeSpec with MultiNodeWordSpec => - val coordinator = RoleName("nodeA") - - def logProps(logId: String): Props = - LeveldbEventLog.props(logId) - - override def afterAll(): Unit = { - // get all config data before shutting down node - val snapshotRootDir = new File(system.settings.config.getString("eventuate.snapshot.filesystem.dir")) - val logRootDir = new File(system.settings.config.getString("eventuate.log.leveldb.dir")) - - // shut down node - super.afterAll() - - // delete log and snapshot files - if (isNode(coordinator)) { - FileUtils.deleteDirectory(snapshotRootDir) - FileUtils.deleteDirectory(logRootDir) - } - } -} - trait MultiNodeSupportCassandra extends BeforeAndAfterAll { this: MultiNodeSpec with MultiNodeWordSpec => val coordinator = RoleName("nodeA") diff --git a/eventuate-log-leveldb/src/it/resources/application.conf b/eventuate-log-leveldb/src/it/resources/application.conf new file mode 100644 index 00000000..7d8111fe --- /dev/null +++ b/eventuate-log-leveldb/src/it/resources/application.conf @@ -0,0 +1,5 @@ +akka.loglevel = "ERROR" +akka.test.single-expect-default = 20s + +eventuate.log.leveldb.dir = target/test-log +eventuate.snapshot.filesystem.dir = target/test-snapshot diff --git a/src/it/scala/com/rbmhtechnology/eventuate/DeleteEventsSpec.scala b/eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/DeleteEventsSpecLeveldb.scala similarity index 91% rename from src/it/scala/com/rbmhtechnology/eventuate/DeleteEventsSpec.scala rename to eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/DeleteEventsSpecLeveldb.scala index fffcdf1c..8572fa04 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/DeleteEventsSpec.scala +++ b/eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/DeleteEventsSpecLeveldb.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -17,21 +17,19 @@ package com.rbmhtechnology.eventuate import akka.actor._ - import com.rbmhtechnology.eventuate.utilities.AwaitHelper import com.typesafe.config.ConfigFactory +import org.scalatest.{Matchers, WordSpec} -import org.scalatest.Matchers -import org.scalatest.WordSpec - -import scala.util.Failure -import scala.util.Success +import scala.util.{Failure, Success} object DeleteEventsSpecLeveldb { class Emitter(locationId: String, val eventLog: ActorRef) extends EventsourcedActor with ActorLogging { - override def id = s"${locationId}_Emitter" + override def id = + s"${locationId}_Emitter" - override def onEvent = Actor.emptyBehavior + override def onEvent = + Actor.emptyBehavior override def onCommand = { case msg => persist(msg) { @@ -57,8 +55,8 @@ object DeleteEventsSpecLeveldb { } class DeleteEventsSpecLeveldb extends WordSpec with Matchers with MultiLocationSpecLeveldb { - import ReplicationIntegrationSpec.replicationConnection import DeleteEventsSpecLeveldb._ + import ReplicationIntegrationSpec.replicationConnection "Deleting events" must { "not replay deleted events on restart" in { diff --git a/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecLeveldb.scala b/eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecLeveldb.scala similarity index 77% rename from src/it/scala/com/rbmhtechnology/eventuate/LocationSpecLeveldb.scala rename to eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecLeveldb.scala index 8d6432ed..920efee5 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecLeveldb.scala +++ b/eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecLeveldb.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -23,6 +23,7 @@ import akka.actor._ import com.rbmhtechnology.eventuate.log._ import com.rbmhtechnology.eventuate.log.leveldb.LeveldbEventLog import com.rbmhtechnology.eventuate.utilities.RestarterActor +import com.typesafe.config.ConfigFactory trait LocationCleanupLeveldb extends LocationCleanup { override def storageLocations: List[File] = @@ -39,12 +40,9 @@ object SingleLocationSpecLeveldb { class TestEventLog(id: String) extends LeveldbEventLog(id, "log-test") with SingleLocationSpec.TestEventLog { override def unhandled(message: Any): Unit = message match { - case "boom" => - throw boom - case "dir" => - sender() ! logDir - case _ => - super.unhandled(message) + case "boom" => throw IntegrationTestException + case "dir" => sender() ! logDir + case _ => super.unhandled(message) } } } @@ -68,4 +66,11 @@ trait SingleLocationSpecLeveldb extends SingleLocationSpec with LocationCleanupL trait MultiLocationSpecLeveldb extends MultiLocationSpec with LocationCleanupLeveldb { override val logFactory: String => Props = id => LeveldbEventLog.props(id) + + override val providerConfig = ConfigFactory.parseString( + s""" + |eventuate.log.leveldb.dir = target/test-log + |eventuate.log.leveldb.index-update-limit = 3 + |eventuate.log.leveldb.deletion-retry-delay = 1 ms + """.stripMargin) } diff --git a/eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecsLeveldb.scala b/eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecsLeveldb.scala new file mode 100644 index 00000000..8e459a82 --- /dev/null +++ b/eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/LocationSpecsLeveldb.scala @@ -0,0 +1,52 @@ +/* + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * + * Licensed 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 com.rbmhtechnology.eventuate + +import akka.actor.{Props, ActorSystem} +import akka.testkit.TestKit + +// -------------------------------------------------------------------------- +// Provider-specific single-location specs +// -------------------------------------------------------------------------- + +class EventsourcedProcessorIntegrationSpecLeveldb extends TestKit(ActorSystem("test")) with EventsourcedProcessorIntegrationSpec with SingleLocationSpecLeveldb { + override def beforeEach(): Unit = { + super.beforeEach() + init() + } +} + +class EventsourcedActorIntegrationSpecLeveldb extends TestKit(ActorSystem("test")) with EventsourcedActorIntegrationSpec with SingleLocationSpecLeveldb { + override def batching = false +} + +class PersistOnEventIntegrationSpecLeveldb extends TestKit(ActorSystem("test")) with PersistOnEventIntegrationSpec with SingleLocationSpecLeveldb +class EventsourcedActorThroughputSpecLeveldb extends TestKit(ActorSystem("test")) with EventsourcedActorThroughputSpec with SingleLocationSpecLeveldb + +// -------------------------------------------------------------------------- +// Provider-specific multi-location specs +// -------------------------------------------------------------------------- + +class EventsourcedActorCausalitySpecLeveldb extends EventsourcedActorCausalitySpec with MultiLocationSpecLeveldb { + override val logFactory: String => Props = id => SingleLocationSpecLeveldb.TestEventLog.props(id, batching = true) +} + +class ReplicationIntegrationSpecLeveldb extends ReplicationIntegrationSpec with MultiLocationSpecLeveldb { + def customPort = 2553 +} + +class ReplicationCycleSpecLeveldb extends ReplicationCycleSpec with MultiLocationSpecLeveldb diff --git a/src/it/scala/com/rbmhtechnology/eventuate/RecoverySpec.scala b/eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/RecoverySpecLeveldb.scala similarity index 98% rename from src/it/scala/com/rbmhtechnology/eventuate/RecoverySpec.scala rename to eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/RecoverySpecLeveldb.scala index 32de3aaa..0c7488c3 100644 --- a/src/it/scala/com/rbmhtechnology/eventuate/RecoverySpec.scala +++ b/eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/RecoverySpecLeveldb.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -22,11 +22,9 @@ import akka.actor._ import akka.pattern.ask import akka.testkit.TestProbe import akka.util.Timeout - import com.rbmhtechnology.eventuate.log.leveldb.LeveldbEventLogSettings import com.rbmhtechnology.eventuate.utilities._ import com.typesafe.config.ConfigFactory - import org.apache.commons.io.FileUtils import org.scalatest._ @@ -65,14 +63,14 @@ object RecoverySpecLeveldb { } } -class RecoverySpecLeveldb extends WordSpec with Matchers with MultiLocationSpec with LocationCleanupLeveldb { +class RecoverySpecLeveldb extends WordSpec with Matchers with MultiLocationSpecLeveldb { import ReplicationIntegrationSpec.replicationConnection import RecoverySpecLeveldb._ val customPort: Int = 2555 - val logFactory: String => Props = + override val logFactory: String => Props = id => SingleLocationSpecLeveldb.TestEventLog.props(id, batching = true) def assertConvergence(expected: Set[String], endpoints: ReplicationEndpoint *): Unit = { diff --git a/eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogSpecLeveldb.scala b/eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogSpecLeveldb.scala new file mode 100644 index 00000000..c8912a9c --- /dev/null +++ b/eventuate-log-leveldb/src/it/scala/com/rbmhtechnology/eventuate/log/EventLogSpecLeveldb.scala @@ -0,0 +1,150 @@ +/* + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * + * Licensed 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 com.rbmhtechnology.eventuate.log + +import akka.actor._ +import akka.pattern.ask +import akka.testkit._ +import akka.util.Timeout + +import com.rbmhtechnology.eventuate._ +import com.rbmhtechnology.eventuate.DurableEvent._ +import com.rbmhtechnology.eventuate.EventsourcingProtocol._ +import com.rbmhtechnology.eventuate.ReplicationFilter.NoFilter +import com.rbmhtechnology.eventuate.ReplicationProtocol._ +import com.rbmhtechnology.eventuate.SingleLocationSpec._ +import com.rbmhtechnology.eventuate.utilities.RestarterActor.restartActor +import com.rbmhtechnology.eventuate.utilities._ +import com.typesafe.config._ + +import org.scalatest.time._ +import org.scalatest.concurrent.Eventually + +object EventLogSpecLeveldb { + val config: Config = ConfigFactory.parseString( + """ + |eventuate.log.leveldb.dir = target/test-log + |eventuate.log.leveldb.index-update-limit = 6 + |eventuate.log.leveldb.deletion-batch-size = 2 + |eventuate.log.leveldb.deletion-retry-delay = 1ms + """.stripMargin).withFallback(EventLogSpec.config) +} + +class EventLogSpecLeveldb extends TestKit(ActorSystem("test", EventLogSpecLeveldb.config)) with EventLogSpec with SingleLocationSpecLeveldb { + "A LeveldbEventLog" must { + "not delete events required for restoring the EventLogClock" in { + generateEmittedEvents() + val currentEventLogClock = (log ? GetEventLogClock).mapTo[GetEventLogClockSuccess].await + (log ? Delete(generatedEmittedEvents.last.localSequenceNr)).await + val restartedLog = restartActor(log) + val restoredEventLogClock = (restartedLog ? GetEventLogClock).mapTo[GetEventLogClockSuccess].await + restoredEventLogClock should be(currentEventLogClock) + } + } +} + +object EventLogWithImmediateEventLogClockSnapshotSpecLeveldb { + val config = ConfigFactory.parseString("eventuate.log.leveldb.state-snapshot-limit = 1") +} + +class EventLogWithImmediateEventLogClockSnapshotSpecLeveldb + extends TestKit(ActorSystem("test", EventLogWithImmediateEventLogClockSnapshotSpecLeveldb.config.withFallback(EventLogSpecLeveldb.config))) + with EventLogSpecSupport with SingleLocationSpecLeveldb with Eventually { + + import EventLogSpec._ + + private val dl: ActorRef = + system.deadLetters + + implicit val implicitTimeout = + Timeout(timeoutDuration) + + override implicit def patienceConfig = + PatienceConfig(Span(10, Seconds), Span(100, Millis)) + + "A LeveldbEventLog" must { + "actually delete events from the log and an index" in { + generateEmittedEvents(customDestinationAggregateIds = Set("a")) + generateEmittedEvents() + (log ? Delete(generatedEmittedEvents(4).localSequenceNr)).await + eventually { + val probe = TestProbe() + log.tell(Replay(IgnoreDeletedSequenceNr, None, 0), probe.ref) + probe.expectMsg(ReplaySuccess(generatedEmittedEvents.slice(5, 6), generatedEmittedEvents(5).localSequenceNr, 0)) + } + eventually { + val probe = TestProbe() + log.tell(Replay(IgnoreDeletedSequenceNr, None, Some("a"), 0), probe.ref) + probe.expectMsg(ReplaySuccess(Nil, 0L, 0)) + } + } + "actually delete events from the log and an index when overlapping conditional delete and replication requests are sent" in { + generateEmittedEvents(customDestinationAggregateIds = Set("a"), num = 50) + generateEmittedEvents(num = 50) + generatedEmittedEvents.foreach { event => + (log ? Delete(event.localSequenceNr, Set(remoteLogId))).await + log ! ReplicationRead((event.localSequenceNr - 10) max 0, Int.MaxValue, NoFilter, remoteLogId, dl, VectorTime()) + } + log ! ReplicationRead(generatedEmittedEvents.last.localSequenceNr + 1, Int.MaxValue, NoFilter, remoteLogId, dl, VectorTime()) + eventually { + val probe = TestProbe() + log.tell(Replay(IgnoreDeletedSequenceNr, None, 0), probe.ref) + probe.expectMsg(ReplaySuccess(Nil, 0L, 0)) + } + eventually { + val probe = TestProbe() + log.tell(Replay(IgnoreDeletedSequenceNr, None, Some("a"), 0), probe.ref) + probe.expectMsg(ReplaySuccess(Nil, 0L, 0)) + } + } + "not replication-read unconditionally deleted (replicated or local) events" in { + generateEmittedEvents() + generateReplicatedEvents() + (log ? Delete(generatedReplicatedEvents(1).localSequenceNr)).await + eventually { + val probe = TestProbe() + log.tell(ReplicationRead(1, Int.MaxValue, NoFilter, UndefinedLogId, dl, VectorTime()), probe.ref) + probe.expectMsg(ReplicationReadSuccess(List(generatedReplicatedEvents.last), 6, UndefinedLogId, VectorTime(logId -> 3L, remoteLogId -> 9L))) + } + } + "continue with unfinished conditional deletion of replicated events after restart" in { + generateEmittedEvents() + (log ? Delete(generatedEmittedEvents.last.localSequenceNr, Set(remoteLogId))).await + val restartedLog = restartActor(log) + restartedLog ! ReplicationRead(generatedEmittedEvents.last.localSequenceNr + 1, Int.MaxValue, NoFilter, remoteLogId, dl, VectorTime()) + eventually { + val probe = TestProbe() + restartedLog.tell(Replay(IgnoreDeletedSequenceNr, None, 0), probe.ref) + probe.expectMsg(ReplaySuccess(Nil, 0L, 0)) + } + } + "delete events after successful replication if conditionally deleted" in { + generateEmittedEvents() + (log ? Delete(generatedEmittedEvents(1).localSequenceNr, Set(remoteLogId))).await + log.tell(ReplicationRead(1, Int.MaxValue, NoFilter, remoteLogId, dl, VectorTime()), replyToProbe.ref) + replyToProbe.expectMsg(ReplicationReadSuccess(generatedEmittedEvents, 3, remoteLogId, VectorTime(logId -> 3L))) + // indicate that remoteLogId has successfully replicated all events + log.tell(ReplicationRead(generatedEmittedEvents.last.localSequenceNr + 1, Int.MaxValue, NoFilter, remoteLogId, dl, VectorTime()), ActorRef.noSender) + + eventually { + val probe = TestProbe() + log.tell(ReplicationRead(1, Int.MaxValue, NoFilter, "otherLog", dl, VectorTime()), probe.ref) + probe.expectMsg(ReplicationReadSuccess(List(generatedEmittedEvents.last), 3, "otherLog", VectorTime(logId -> 3L))) + } + } + } +} diff --git a/eventuate-log-leveldb/src/main/resources/reference.conf b/eventuate-log-leveldb/src/main/resources/reference.conf new file mode 100644 index 00000000..d4886903 --- /dev/null +++ b/eventuate-log-leveldb/src/main/resources/reference.conf @@ -0,0 +1,22 @@ +eventuate { + log.leveldb { + # Root directory for storing the log directories of individual event logs. + dir = target + + # Use fsync on write. + fsync = on + + # Minimum number of new events that must have been written before another + # snapshot of the log's internal state (sequence number and merged vector + # time) is written. + state-snapshot-limit = 128 + + # Maximum number of events that are physically deleted in a single batch + # operation. + deletion-batch-size = 100 + + # Delay between two tries to physically delete all requested events while + # keeping those that are not yet replicated. + deletion-retry-delay = 1m + } +} diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbDeletionActor.scala b/eventuate-log-leveldb/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbDeletionActor.scala similarity index 93% rename from src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbDeletionActor.scala rename to eventuate-log-leveldb/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbDeletionActor.scala index 12eeb7e4..e622c746 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbDeletionActor.scala +++ b/eventuate-log-leveldb/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbDeletionActor.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -37,7 +37,7 @@ private object LeveldbDeletionActor { Props(new LeveldbDeletionActor(leveldb, leveldbReadOptions, leveldbWriteOptions, batchSize, toSequenceNr, promise)) } -class LeveldbDeletionActor( +private class LeveldbDeletionActor( val leveldb: DB, val leveldbReadOptions: ReadOptions, val leveldbWriteOptions: WriteOptions, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbDeletionMetadataStore.scala b/eventuate-log-leveldb/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbDeletionMetadataStore.scala similarity index 87% rename from src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbDeletionMetadataStore.scala rename to eventuate-log-leveldb/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbDeletionMetadataStore.scala index 37add3cf..f7b4bff3 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbDeletionMetadataStore.scala +++ b/eventuate-log-leveldb/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbDeletionMetadataStore.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -24,7 +24,7 @@ import com.rbmhtechnology.eventuate.log.leveldb.LeveldbEventLog.longBytes import org.iq80.leveldb.DB import org.iq80.leveldb.WriteOptions -class LeveldbDeletionMetadataStore(val leveldb: DB, val leveldbWriteOptions: WriteOptions, classifier: Int) extends WithBatch { +private class LeveldbDeletionMetadataStore(val leveldb: DB, val leveldbWriteOptions: WriteOptions, classifier: Int) extends WithBatch { private val DeletedToSequenceNrKey: Int = 1 private val RemoteLogIdsKey: Int = 2 diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbEventLog.scala b/eventuate-log-leveldb/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbEventLog.scala similarity index 98% rename from src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbEventLog.scala rename to eventuate-log-leveldb/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbEventLog.scala index 5c7f529b..376cdb62 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbEventLog.scala +++ b/eventuate-log-leveldb/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbEventLog.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbNumericIdentifierStore.scala b/eventuate-log-leveldb/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbNumericIdentifierStore.scala similarity index 92% rename from src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbNumericIdentifierStore.scala rename to eventuate-log-leveldb/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbNumericIdentifierStore.scala index fead865d..d4a49fbd 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbNumericIdentifierStore.scala +++ b/eventuate-log-leveldb/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbNumericIdentifierStore.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbReplicationProgressStore.scala b/eventuate-log-leveldb/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbReplicationProgressStore.scala similarity index 93% rename from src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbReplicationProgressStore.scala rename to eventuate-log-leveldb/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbReplicationProgressStore.scala index 286111d4..246a8f03 100644 --- a/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbReplicationProgressStore.scala +++ b/eventuate-log-leveldb/src/main/scala/com/rbmhtechnology/eventuate/log/leveldb/LeveldbReplicationProgressStore.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetService.java b/eventuate-log-leveldb/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeConfigLeveldb.scala similarity index 55% rename from src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetService.java rename to eventuate-log-leveldb/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeConfigLeveldb.scala index a69e9583..1bf061e0 100644 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetService.java +++ b/eventuate-log-leveldb/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeConfigLeveldb.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -14,12 +14,10 @@ * limitations under the License. */ -package com.rbmhtechnology.example.japi.dbreplica.service; +package com.rbmhtechnology.eventuate -import com.rbmhtechnology.example.japi.dbreplica.domain.Asset; +import com.typesafe.config._ -public interface AssetService extends AssetFinder, AssetListeners { - void create(final Asset asset); - - void update(final Asset asset); +object MultiNodeConfigLeveldb { + val providerConfig: Config = ConfigFactory.parseString("eventuate.log.leveldb.dir = target/test-log") } diff --git a/eventuate-log-leveldb/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSpecsLeveldb.scala b/eventuate-log-leveldb/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSpecsLeveldb.scala new file mode 100644 index 00000000..df3638e1 --- /dev/null +++ b/eventuate-log-leveldb/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSpecsLeveldb.scala @@ -0,0 +1,48 @@ +/* + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * + * Licensed 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 com.rbmhtechnology.eventuate + +import MultiNodeConfigLeveldb._ + +class BasicReplicationSpecLeveldb extends BasicReplicationSpec(new BasicReplicationConfig(providerConfig)) with MultiNodeSupportLeveldb +class BasicReplicationSpecLeveldbMultiJvmNode1 extends BasicReplicationSpecLeveldb +class BasicReplicationSpecLeveldbMultiJvmNode2 extends BasicReplicationSpecLeveldb +class BasicReplicationSpecLeveldbMultiJvmNode3 extends BasicReplicationSpecLeveldb + +class BasicReplicationThroughputSpecLeveldb extends BasicReplicationThroughputSpec(new BasicReplicationThroughputConfig(providerConfig)) with MultiNodeSupportLeveldb +class BasicReplicationThroughputSpecLeveldbMultiJvmNode1 extends BasicReplicationThroughputSpecLeveldb +class BasicReplicationThroughputSpecLeveldbMultiJvmNode2 extends BasicReplicationThroughputSpecLeveldb +class BasicReplicationThroughputSpecLeveldbMultiJvmNode3 extends BasicReplicationThroughputSpecLeveldb +class BasicReplicationThroughputSpecLeveldbMultiJvmNode4 extends BasicReplicationThroughputSpecLeveldb +class BasicReplicationThroughputSpecLeveldbMultiJvmNode5 extends BasicReplicationThroughputSpecLeveldb +class BasicReplicationThroughputSpecLeveldbMultiJvmNode6 extends BasicReplicationThroughputSpecLeveldb + +class BasicCausalitySpecLeveldb extends BasicCausalitySpec(new BasicCausalityConfig(providerConfig)) with MultiNodeSupportLeveldb +class BasicCausalitySpecLeveldbMultiJvmNode1 extends BasicCausalitySpecLeveldb +class BasicCausalitySpecLeveldbMultiJvmNode2 extends BasicCausalitySpecLeveldb + +class BasicPersistOnEventSpecLeveldb extends BasicPersistOnEventSpec(new BasicPersistOnEventConfig(providerConfig)) with MultiNodeSupportLeveldb +class BasicPersistOnEventSpecLeveldbMultiJvmNode1 extends BasicPersistOnEventSpecLeveldb +class BasicPersistOnEventSpecLeveldbMultiJvmNode2 extends BasicPersistOnEventSpecLeveldb + +class FailureDetectionSpecLeveldb extends FailureDetectionSpec(new FailureDetectionConfig(providerConfig)) with MultiNodeSupportLeveldb +class FailureDetectionSpecLeveldbMultiJvmNode1 extends FailureDetectionSpecLeveldb +class FailureDetectionSpecLeveldbMultiJvmNode2 extends FailureDetectionSpecLeveldb + +class FilteredReplicationSpecLeveldb extends FilteredReplicationSpec(new FilteredReplicationConfig(providerConfig)) with MultiNodeSupportLeveldb +class FilteredReplicationSpecLeveldbMultiJvmNode1 extends FilteredReplicationSpecLeveldb +class FilteredReplicationSpecLeveldbMultiJvmNode2 extends FilteredReplicationSpecLeveldb diff --git a/eventuate-log-leveldb/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSupportLeveldb.scala b/eventuate-log-leveldb/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSupportLeveldb.scala new file mode 100644 index 00000000..0ab204f7 --- /dev/null +++ b/eventuate-log-leveldb/src/multi-jvm/scala/com/rbmhtechnology/eventuate/MultiNodeSupportLeveldb.scala @@ -0,0 +1,50 @@ +/* + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * + * Licensed 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 com.rbmhtechnology.eventuate + +import java.io.File + +import akka.actor.Props +import akka.remote.testconductor.RoleName +import akka.remote.testkit.MultiNodeSpec + +import com.rbmhtechnology.eventuate.log.leveldb.LeveldbEventLog + +import org.apache.commons.io.FileUtils +import org.scalatest.BeforeAndAfterAll + +trait MultiNodeSupportLeveldb extends BeforeAndAfterAll { this: MultiNodeSpec with MultiNodeWordSpec => + val coordinator = RoleName("nodeA") + + def logProps(logId: String): Props = + LeveldbEventLog.props(logId) + + override def afterAll(): Unit = { + // get all config data before shutting down node + val snapshotRootDir = new File(system.settings.config.getString("eventuate.snapshot.filesystem.dir")) + val logRootDir = new File(system.settings.config.getString("eventuate.log.leveldb.dir")) + + // shut down node + super.afterAll() + + // delete log and snapshot files + if (isNode(coordinator)) { + FileUtils.deleteDirectory(snapshotRootDir) + FileUtils.deleteDirectory(logRootDir) + } + } +} diff --git a/example/dbreplica b/example/dbreplica deleted file mode 100755 index 2dd51394..00000000 --- a/example/dbreplica +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -# generate example classpath script only once -sbt exampleClasspath - -for location in A B C -do - if command -v osascript >/dev/null 2>&1; then - osascript -e "tell app \"Terminal\" - do script \"cd `pwd`; ./example/dbreplica-location $* $location\" - end tell" - else - if command -v xterm >/dev/null 2>&1; then - xterm -title "location $location" -e "./example/dbreplica-location $* $location" & - else - echo "Neither osascript nor xterm were found"; - fi - fi -done diff --git a/example/dbreplica-location b/example/dbreplica-location deleted file mode 100755 index 06727557..00000000 --- a/example/dbreplica-location +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh - -DB_REPLICA_MAIN=com.rbmhtechnology.example.dbreplica.DBReplica -DB_REPLICA_LOCATION=$1 - -while [[ $# > 1 ]]; do - key="$1" - case $key in - -j|--java) - DB_REPLICA_MAIN=com.rbmhtechnology.example.japi.dbreplica.DBReplica - DB_REPLICA_LOCATION=$2 - ;; - *) - # unknown option - ;; - esac - shift # past argument or value -done - -# try to generate the classpath script -# although it will be usually generated by './example' already -if [[ ! -f ./example/.example-classpath ]]; then - sbt exampleClasspath || exit 1 -fi - -source ./example/.example-classpath - -exec java -cp "$EXAMPLE_CLASSPATH" $DB_REPLICA_MAIN $DB_REPLICA_LOCATION diff --git a/project/Formatting.scala b/project/Formatting.scala deleted file mode 100644 index 4949ec82..00000000 --- a/project/Formatting.scala +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.eventuate - -import sbt._ -import com.typesafe.sbt.SbtMultiJvm.MultiJvmKeys.MultiJvm -import com.typesafe.sbt.SbtScalariform -import com.typesafe.sbt.SbtScalariform.ScalariformKeys - -object Formatting { - lazy val formatSettings = SbtScalariform.scalariformSettings ++ Seq( - ScalariformKeys.preferences in Compile := formattingPreferences, - ScalariformKeys.preferences in Test := formattingPreferences, - ScalariformKeys.preferences in MultiJvm := formattingPreferences - ) - - private val formattingPreferences = { - import scalariform.formatter.preferences._ - FormattingPreferences() - .setPreference(AlignSingleLineCaseStatements, true) - } - -} diff --git a/project/ProjectDependencies.scala b/project/ProjectDependencies.scala new file mode 100644 index 00000000..38b435df --- /dev/null +++ b/project/ProjectDependencies.scala @@ -0,0 +1,41 @@ +/* + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * + * Licensed 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. + */ + +import sbt._ + +object ProjectDependencyVersions { + val AkkaVersion = "2.4.1" + val ProtobufVersion = "2.5.0" +} + +object ProjectDependencies { + import ProjectDependencyVersions._ + + val AkkaRemote = "com.typesafe.akka" %% "akka-remote" % AkkaVersion + val AkkaTestkit = "com.typesafe.akka" %% "akka-testkit" % AkkaVersion + val AkkaTestkitMultiNode = "com.typesafe.akka" %% "akka-multi-node-testkit" % AkkaVersion + val CassandraDriver = "com.datastax.cassandra" % "cassandra-driver-core" % "2.1.5" + val CassandraUnit = "org.cassandraunit" % "cassandra-unit" % "2.0.2.2" + val CommonsIo = "commons-io" % "commons-io" % "2.4" + val Leveldb = "org.fusesource.leveldbjni" % "leveldbjni-all" % "1.8" + val Java8Compat = "org.scala-lang.modules" % "scala-java8-compat_2.11" % "0.7.0" + val Javaslang = "com.javaslang" % "javaslang" % "2.0.0-RC3" + val JunitInterface = "com.novocode" % "junit-interface" % "0.11" + val Protobuf = "com.google.protobuf" % "protobuf-java" % ProtobufVersion + val Scalatest = "org.scalatest" %% "scalatest" % "2.1.4" + val Scalaz = "org.scalaz" %% "scalaz-core" % "7.1.0" +} + diff --git a/project/ProjectSettings.scala b/project/ProjectSettings.scala new file mode 100644 index 00000000..db52b0e9 --- /dev/null +++ b/project/ProjectSettings.scala @@ -0,0 +1,199 @@ +/* + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * + * Licensed 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. + */ + +import sbt._ +import sbt.Keys._ + +import java.nio.file._ +import java.nio.file.StandardOpenOption._ + +import com.typesafe.sbt.SbtGhPages.ghpages +import com.typesafe.sbt.SbtGit.git +import com.typesafe.sbt.SbtMultiJvm +import com.typesafe.sbt.SbtMultiJvm.MultiJvmKeys._ +import com.typesafe.sbt.SbtScalariform +import com.typesafe.sbt.SbtScalariform.ScalariformKeys +import com.typesafe.sbt.SbtSite.site + +import de.heikoseeberger.sbtheader.{ HeaderPlugin, AutomateHeaderPlugin } +import de.heikoseeberger.sbtheader.HeaderKey._ +import de.heikoseeberger.sbtheader.license.Apache2_0 + +import sbtprotobuf.ProtobufPlugin +import sbtunidoc.Plugin.{ unidocSettings, ScalaUnidoc } + +object ProjectSettings { + import ProjectDependencyVersions._ + import ProjectDependencies._ + + lazy val commonSettings: Seq[Setting[_]] = + formatterSettings ++ + compilerSettings ++ + headerSettings ++ + testSettings ++ + publishSettings + + lazy val integrationTestSettings: Seq[Setting[_]] = + integrationTestHeaderSettings ++ + integrationTestSingleNodeSettings ++ + integrationTestMultiNodeSettings + + // ---------------------------------------------------------------------- + // Common settings + // ---------------------------------------------------------------------- + + lazy val compilerSettings: Seq[Setting[_]] = Seq( + scalacOptions ++= Seq("-feature", "-unchecked", "-deprecation", "-Xlint") + ) + + lazy val testSettings: Seq[Setting[_]] = Seq( + parallelExecution in Test := false, + fork in Test := true + ) + + lazy val headerSettings: Seq[Setting[_]] = { + val header = Apache2_0("2015 - 2016", "Red Bull Media House GmbH - all rights reserved.") + + Seq(headers := Map( + "scala" -> header, + "java" -> header) + ) + } + + // ---------------------------------------------------------------------- + // Integration test settings + // ---------------------------------------------------------------------- + + lazy val integrationTestSingleNodeSettings = Defaults.itSettings ++ Seq( + createHeaders in IntegrationTest <<= (createHeaders in IntegrationTest) triggeredBy (createHeaders in Test), + compile in IntegrationTest <<= (compile in IntegrationTest) triggeredBy (compile in Test), + test in IntegrationTest <<= (test in IntegrationTest) triggeredBy (test in Test), + parallelExecution in IntegrationTest := false, + fork in IntegrationTest := true + ) + + lazy val integrationTestMultiNodeSettings = SbtMultiJvm.multiJvmSettings ++ Seq( + createHeaders in MultiJvm <<= (createHeaders in MultiJvm) triggeredBy (createHeaders in Test), + compile in MultiJvm <<= (compile in MultiJvm) triggeredBy (compile in Test), + executeTests in Test <<= (executeTests in Test, executeTests in MultiJvm) map { + case (testResults, multiJvmResults) => + val overall = + if (testResults.overall.id < multiJvmResults.overall.id) multiJvmResults.overall + else testResults.overall + Tests.Output(overall, + testResults.events ++ multiJvmResults.events, + testResults.summaries ++ multiJvmResults.summaries) + } + ) + + lazy val integrationTestHeaderSettings: Seq[Setting[_]] = + HeaderPlugin.settingsFor(IntegrationTest, MultiJvm) ++ + AutomateHeaderPlugin.automateFor(IntegrationTest, MultiJvm) + + // ---------------------------------------------------------------------- + // Protobuf compiler settings + // ---------------------------------------------------------------------- + + lazy val protocSettings: Seq[Setting[_]] = ProtobufPlugin.protobufSettings ++ Seq( + version in ProtobufPlugin.protobufConfig := ProtobufVersion, + ProtobufPlugin.runProtoc in ProtobufPlugin.protobufConfig := (args => com.github.os72.protocjar.Protoc.runProtoc("-v250" +: args.toArray)), + libraryDependencies += Protobuf + ) + + // ---------------------------------------------------------------------- + // Code formatter settings + // ---------------------------------------------------------------------- + + lazy val formatterSettings: Seq[Setting[_]] = { + import scalariform.formatter.preferences._ + + val formattingPreferences = FormattingPreferences().setPreference(AlignSingleLineCaseStatements, true) + + SbtScalariform.scalariformSettings ++ Seq( + ScalariformKeys.preferences in Compile := formattingPreferences, + ScalariformKeys.preferences in Test := formattingPreferences, + ScalariformKeys.preferences in MultiJvm := formattingPreferences + ) + } + + // ---------------------------------------------------------------------- + // Publish settings + // ---------------------------------------------------------------------- + + lazy val publishSettings: Seq[Setting[_]] = { + val jFrogCredentials = Credentials( + "Artifactory Realm", + "oss.jfrog.org", + sys.env.getOrElse("OSS_JFROG_USER", ""), + sys.env.getOrElse("OSS_JFROG_PASS", "") + ) + + val jFrogBase = + "https://oss.jfrog.org/artifactory/" + + val jFrogSnapshotRepo = Some("OJO Snapshots" at jFrogBase + "oss-snapshot-local") + val jFrogReleaseRepo = Some("OJO Releases" at jFrogBase + "oss-release-local") + + Seq( + credentials += jFrogCredentials, + publishTo := (if (isSnapshot.value) jFrogSnapshotRepo else jFrogReleaseRepo), + publishMavenStyle := true + ) + } + + // ---------------------------------------------------------------------- + // Documentation settings + // ---------------------------------------------------------------------- + + lazy val documentationSettings: Seq[Setting[_]] = + unidocSettings ++ + site.settings ++ + site.sphinxSupport() ++ + site.includeScaladoc() ++ + ghpages.settings ++ + Seq( + git.remoteRepo := "git@github.com:RBMHTechnology/eventuate.git", + site.addMappingsToSiteDir(mappings in (ScalaUnidoc, packageDoc), "latest/api"), + unmanagedSourceDirectories in Test += baseDirectory.value / "src" / "sphinx"/ "code", + scalacOptions in (Compile, doc) := List("-skip-packages", "akka") + ) + + // ---------------------------------------------------------------------- + // Example application settings + // ---------------------------------------------------------------------- + + lazy val exampleSettings: Seq[Setting[_]] = { + lazy val generateClasspath = taskKey[Unit]("generate example classpath script") + + Seq( + generateClasspath <<= generateClasspath.dependsOn(sbt.Keys.compile in Test), + generateClasspath := { + val cpaths = (fullClasspath in Compile).value.map(_.data).mkString(":") + val output = + s"""|#!/bin/sh + | + |# this file is automatically generated by the sbt 'generateClasspath' command + | + |export EXAMPLE_CLASSPATH="$cpaths" + |""".stripMargin + + val file = Paths.get(baseDirectory.value.toString, "bin", ".example-classpath") + + Files.write(file, output.getBytes, CREATE, TRUNCATE_EXISTING) + file.toFile.setExecutable(true) + }) + } +} \ No newline at end of file diff --git a/project/build.properties b/project/build.properties index 748703f7..78614b75 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.7 +sbt.version=0.13.11 diff --git a/project/plugins.sbt b/project/plugins.sbt index 9adc9439..52ccce5e 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -6,9 +6,11 @@ addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "0.8.1") addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.5.3") +addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.3.3") + addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.3.0") -addSbtPlugin("de.heikoseeberger" % "sbt-header" % "1.0.0") +addSbtPlugin("de.heikoseeberger" % "sbt-header" % "1.5.1") addSbtPlugin("com.github.gseitz" % "sbt-protobuf" % "0.4.0") diff --git a/src/it/scala/com/rbmhtechnology/eventuate/LocationConfig.scala b/src/it/scala/com/rbmhtechnology/eventuate/LocationConfig.scala deleted file mode 100644 index c40a8667..00000000 --- a/src/it/scala/com/rbmhtechnology/eventuate/LocationConfig.scala +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.eventuate - -import com.typesafe.config._ - -object LocationConfig { - def create(port: Int = 0, customConfig: Config = ConfigFactory.empty()): Config = { - val defaultConfig = ConfigFactory.parseString( - s""" - |akka.actor.provider = "akka.remote.RemoteActorRefProvider" - |akka.remote.enabled-transports = ["akka.remote.netty.tcp"] - |akka.remote.netty.tcp.hostname = "127.0.0.1" - |akka.remote.netty.tcp.port = ${port} - |akka.remote.retry-gate-closed-for = 300ms - |akka.test.single-expect-default = 20s - |akka.loglevel = "ERROR" - | - |eventuate.log.write-batch-size = 3 - |eventuate.log.replication.retry-delay = 1s - |eventuate.log.replication.failure-detection-limit = 3s - |eventuate.log.leveldb.dir = target/test-log - |eventuate.log.leveldb.index-update-limit = 3 - |eventuate.log.cassandra.default-port = 9142 - |eventuate.log.cassandra.index-update-limit = 3 - |eventuate.log.leveldb.deletion-retry-delay = 1 ms - |eventuate.snapshot.filesystem.dir = target/test-snapshot - """.stripMargin) - - customConfig.withFallback(defaultConfig) - } -} diff --git a/src/sphinx/architecture.rst b/src/sphinx/architecture.rst index 04c33fff..bc15b8e0 100644 --- a/src/sphinx/architecture.rst +++ b/src/sphinx/architecture.rst @@ -234,6 +234,6 @@ We haven’t started yet working on this. Should you have any preferences or pro .. _ticket 68: https://github.com/RBMHTechnology/eventuate/issues/68 .. _ticket 103: https://github.com/RBMHTechnology/eventuate/issues/103 -.. _let us know: https://groups.google.com/forum/#!forum/eventuate +.. _let us know: https://gitter.im/RBMHTechnology/eventuate .. [#] :ref:`event-sourced-processors` can be used to connect otherwise partitioned event logs. diff --git a/src/sphinx/code/EventLogDoc.scala b/src/sphinx/code/EventLogDoc.scala index 6b7cc6af..3eb8fccf 100644 --- a/src/sphinx/code/EventLogDoc.scala +++ b/src/sphinx/code/EventLogDoc.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/sphinx/code/EventRoutingDoc.scala b/src/sphinx/code/EventRoutingDoc.scala index 1a6da5d4..493a62e5 100644 --- a/src/sphinx/code/EventRoutingDoc.scala +++ b/src/sphinx/code/EventRoutingDoc.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/sphinx/code/EventSourcingDoc.scala b/src/sphinx/code/EventSourcingDoc.scala index 665ae4da..1bf68c94 100644 --- a/src/sphinx/code/EventSourcingDoc.scala +++ b/src/sphinx/code/EventSourcingDoc.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, @@ -354,4 +354,4 @@ object BehaviorChanges { } //# } -} \ No newline at end of file +} diff --git a/src/sphinx/code/ReliableDeliveryDoc.scala b/src/sphinx/code/ReliableDeliveryDoc.scala index cdacc4b7..12478dd5 100644 --- a/src/sphinx/code/ReliableDeliveryDoc.scala +++ b/src/sphinx/code/ReliableDeliveryDoc.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/sphinx/code/UserGuideDoc.scala b/src/sphinx/code/UserGuideDoc.scala index 945fd290..e29c9d57 100644 --- a/src/sphinx/code/UserGuideDoc.scala +++ b/src/sphinx/code/UserGuideDoc.scala @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. + * Copyright 2015 - 2016 Red Bull Media House GmbH - all rights reserved. * * Licensed 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 + * 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, diff --git a/src/sphinx/current-limitations.rst b/src/sphinx/current-limitations.rst index c4bb6a72..70167f85 100644 --- a/src/sphinx/current-limitations.rst +++ b/src/sphinx/current-limitations.rst @@ -13,4 +13,4 @@ The following is a list of known limitations that are going to be addressed in f - No performance optimizations have been made yet. .. _Akka Cluster: http://doc.akka.io/docs/akka/2.4.1/scala/cluster-usage.html -.. _let us know: https://groups.google.com/forum/#!forum/eventuate +.. _let us know: https://gitter.im/RBMHTechnology/eventuate diff --git a/src/sphinx/download.rst b/src/sphinx/download.rst index e983cd94..41ac7162 100644 --- a/src/sphinx/download.rst +++ b/src/sphinx/download.rst @@ -2,6 +2,29 @@ Download -------- +Eventuate is a multi-module project with the following modules: + +.. list-table:: Table 1: Eventuate modules + :header-rows: 1 + + * - Module + - Description + * - ``eventuate-core`` + - Core module, required for all applications. + * - ``eventuate-log-cassandra`` + - Provides the :ref:`cassandra-storage-backend`. + * - ``eventuate-log-leveldb`` + - Provides the :ref:`leveldb-storage-backend`. + * - ``eventuate-crdt`` + - Provides :ref:`commutative-replicated-data-types`. + * - ``eventuate-examples`` + - Provides :ref:`example-application` among others. + +| + +.. note:: + An Eventuate application requires at least ``eventuate-core`` and one storage backend module as dependency. + Binaries -------- @@ -10,7 +33,7 @@ Release binaries are published to Bintray_, snapshot binaries to OJO_ (oss.jfrog Maven ~~~~~ -To include the latest release into a Maven project, add the following to your ``pom.xml``:: +To include the latest release into a Maven project, add the following dependencies to your ``pom.xml``:: eventuate-releases @@ -20,8 +43,26 @@ To include the latest release into a Maven project, add the following to your `` com.rbmhtechnology - eventuate_2.11 - 0.5 + eventuate-core_2.11 + 0.6 + + + + com.rbmhtechnology + eventuate-log-leveldb_2.11 + 0.6 + + + + com.rbmhtechnology + eventuate-log-cassandra_2.11 + 0.6 + + + + com.rbmhtechnology + eventuate-crdt_2.11 + 0.6 To include the latest development snapshot:: @@ -34,24 +75,54 @@ To include the latest development snapshot:: com.rbmhtechnology - eventuate_2.11 - 0.6-SNAPSHOT + eventuate-core_2.11 + 0.7-SNAPSHOT + + + + com.rbmhtechnology + eventuate-log-leveldb_2.11 + 0.7-SNAPSHOT + + + + com.rbmhtechnology + eventuate-log-cassandra_2.11 + 0.7-SNAPSHOT + + + + com.rbmhtechnology + eventuate-crdt_2.11 + 0.7-SNAPSHOT SBT ~~~ -To include the latest release into an sbt_ project, add the following to your ``build.sbt``:: +To include the latest release into an sbt_ project, add the following dependencies to your ``build.sbt``:: resolvers += "Eventuate Releases" at "https://dl.bintray.com/rbmhtechnology/maven" - libraryDependencies += "com.rbmhtechnology" %% "eventuate" % "0.5" + libraryDependencies += "com.rbmhtechnology" %% "eventuate-core" % "0.6" + + libraryDependencies += "com.rbmhtechnology" %% "eventuate-log-leveldb" % "0.6" + + libraryDependencies += "com.rbmhtechnology" %% "eventuate-log-cassandra" % "0.6" + + libraryDependencies += "com.rbmhtechnology" %% "eventuate-crdt" % "0.6" To include the latest development snapshot:: resolvers += "OJO Snapshots" at "https://oss.jfrog.org/oss-snapshot-local" - libraryDependencies += "com.rbmhtechnology" %% "eventuate" % "0.6-SNAPSHOT" + libraryDependencies += "com.rbmhtechnology" %% "eventuate-core" % "0.7-SNAPSHOT" + + libraryDependencies += "com.rbmhtechnology" %% "eventuate-log-leveldb" % "0.7-SNAPSHOT" + + libraryDependencies += "com.rbmhtechnology" %% "eventuate-log-cassandra" % "0.7-SNAPSHOT" + + libraryDependencies += "com.rbmhtechnology" %% "eventuate-crdt" % "0.7-SNAPSHOT" Sources ------- diff --git a/src/sphinx/example-application.rst b/src/sphinx/example-application.rst index 5e923e2e..b2b10c95 100644 --- a/src/sphinx/example-application.rst +++ b/src/sphinx/example-application.rst @@ -14,7 +14,7 @@ Domain The ``Order`` domain object is defined as follows: -.. includecode:: ../test/scala/com/rbmhtechnology/example/ordermgnt/Order.scala +.. includecode:: ../../eventuate-examples/src/main/scala/com/rbmhtechnology/example/ordermgnt/Order.scala :snippet: order-definition Order creation and updates are tracked as events in a replicated event log. At each location, there is one event-sourced ``OrderActor`` instance per created ``Order`` instance and one event-sourced ``OrderView`` instance that counts the updates made to all orders. @@ -64,23 +64,23 @@ Running Before you can run the example application, install sbt_ and run:: - sbt test:compile + sbt compile from the project's root directory (needs to be done only once). Then, run:: - ./example/ordermgnt + ./eventuate-example/bin/ordermgnt This should open six terminal windows, representing locations A - F. For running the Java version of the example application use the ``-j`` or ``--java`` option:: - ./example/ordermgnt --java + ./eventuate-example/bin/ordermgnt --java Create and update some orders and see how changes are propagated to other locations. To make concurrent updates to an order, for example, enter ``exit`` at location ``C``, and add different items to that order at locations ``B`` and ``F``. When starting location ``C`` again with:: - ./example/ordermgnt-location A + ./eventuate-example/bin/ordermgnt-location A or the Java version with:: - ./example/ordermgnt-location --java A + ./eventuate-example/bin/ordermgnt-location --java A both updates propagate to all other locations which are then displayed as conflict. Resolve the conflict with the ``resolve`` command. Conflict resolution writes a conflict resolution event to the replicated event log so that the conflict is automatically resolved at all locations. @@ -91,11 +91,11 @@ Disaster recovery :ref:`disaster-recovery` in the example application can be tested by removing the event log of a location and starting the location again with disaster recovery enabled. For example, to remove the event log at location ``C``, stop the location with ``exit`` and delete its LevelDB directory:: - rm -r target/example-logs/s-C_default/ + rm -r eventuate-example/target/example-logs/s-C_default/ To delete the event log written by the Java version of the example application run:: - rm -r target/example-logs/j-C_default/ + rm -r eventuate-example/target/example-logs/j-C_default/ To start location ``C`` again with disaster recovery enabled, use the ``-r`` or ``--recover`` option:: @@ -103,7 +103,7 @@ To start location ``C`` again with disaster recovery enabled, use the ``-r`` or or the Java version with:: - ./example/ordermgnt-location --recover --java C + ./eventuate-example/bin/ordermgnt-location --recover --java C Recovery may take up to 20 seconds when using the default :ref:`configuration` settings for event replication and disaster recovery. To speed up the process you may want to the use following configuration settings:: diff --git a/src/sphinx/getting-started.rst b/src/sphinx/getting-started.rst index 2a153314..4082d656 100644 --- a/src/sphinx/getting-started.rst +++ b/src/sphinx/getting-started.rst @@ -13,5 +13,5 @@ If you have any questions or comments, please `let us know`_. .. _Java 8: http://www.oracle.com/technetwork/java/javase/downloads/index.html .. _Eventuate Github repository: https://github.com/RBMHTechnology/eventuate -.. _let us know: https://groups.google.com/forum/#!forum/eventuate +.. _let us know: https://gitter.im/RBMHTechnology/eventuate diff --git a/src/sphinx/project.rst b/src/sphinx/project.rst index 91341135..1ac24f6a 100644 --- a/src/sphinx/project.rst +++ b/src/sphinx/project.rst @@ -8,8 +8,8 @@ Project Community --------- -- `User mailing list`_ - `Gitter chat room`_ +- `User mailing list`_ License ------- diff --git a/src/sphinx/reference/configuration.rst b/src/sphinx/reference/configuration.rst index 64a9ae3e..c1ee9809 100644 --- a/src/sphinx/reference/configuration.rst +++ b/src/sphinx/reference/configuration.rst @@ -6,6 +6,24 @@ Configuration This is the reference configuration of Eventuate. It is processed by Typesafe's config_ library and can be overridden by applications: -.. literalinclude:: ../../main/resources/reference.conf +eventuate-core +-------------- + +.. literalinclude:: ../../../eventuate-core/src/main/resources/reference.conf + +eventuate-crdt +-------------- + +.. literalinclude:: ../../../eventuate-crdt/src/main/resources/reference.conf + +eventuate-log-cassandra +----------------------- + +.. literalinclude:: ../../../eventuate-log-cassandra/src/main/resources/reference.conf + +eventuate-log-leveldb +--------------------- + +.. literalinclude:: ../../../eventuate-log-leveldb/src/main/resources/reference.conf .. _config: https://github.com/typesafehub/config diff --git a/src/sphinx/reference/event-sourcing.rst b/src/sphinx/reference/event-sourcing.rst index 7822e178..a870f059 100644 --- a/src/sphinx/reference/event-sourcing.rst +++ b/src/sphinx/reference/event-sourcing.rst @@ -37,7 +37,7 @@ State synchronization As explained in section :ref:`command-handler`, events are persisted asynchronously. What happens if another command is sent to an event-sourced actor while persistence is in progress? This depends on the value of ``stateSync``, a member of ``EventsourcedActor`` that can be overridden. -.. includecode:: ../../main/scala/com/rbmhtechnology/eventuate/EventsourcedActor.scala +.. includecode:: ../../../eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedActor.scala :snippet: state-sync If ``stateSync`` is ``true`` (default), new commands are stashed_ while persistence is in progress. Consequently, new commands see actor state that is *in sync* with the events in the event log. A consequence is limited write throughput, because :ref:`batching` of write requests is not possible in this case\ [#]_. This setting is recommended for event-sourced actors that must validate commands against current state. @@ -97,7 +97,7 @@ Like event-sourced views, event-sourced writers can only consume events from an This section outlines how to update a persistent read model in Cassandra_ from events consumed by an event-sourced writer. The relevant events are: -.. includecode:: ../../test/scala/com/rbmhtechnology/example/querydb/Emitter.scala +.. includecode:: ../../../eventuate-examples/src/main/scala/com/rbmhtechnology/example/querydb/Emitter.scala :snippet: events The persistent read model is a ``CUSTOMER`` table with the following structure:: @@ -118,11 +118,11 @@ The stored sequence number is that of the last successfully processed event. An The event-sourced ``Writer`` in the following example implements ``EventsourcedWriter[Long, Unit]`` (where ``Long`` is the type of the initial read result and ``Unit`` the type of write results). It is initialized with an ``eventLog`` from which it consumes events and a Cassandra ``Session`` for writing event processing results. -.. includecode:: ../../test/scala/com/rbmhtechnology/example/querydb/Writer.scala +.. includecode:: ../../../eventuate-examples/src/main/scala/com/rbmhtechnology/example/querydb/Writer.scala :snippet: writer .. hint:: - The full example source code is available `here `_. + The full example source code is available `here `_. On a high level, the example ``Writer`` implements the following behavior: @@ -159,7 +159,7 @@ The following example ``Processor`` is an implementation of ``EventsourcedProces The event handler implemented by a processor is ``processEvent``. The type of the handler is defined as: -.. includecode:: ../../main/scala/com/rbmhtechnology/eventuate/EventsourcedProcessor.scala +.. includecode:: ../../../eventuate-core/src/main/scala/com/rbmhtechnology/eventuate/EventsourcedProcessor.scala :snippet: process Processed events, to be written to the target event log, are returned by the handler as ``Seq[Any]``. With this handler signature, events from the source log can be diff --git a/src/sphinx/user-guide.rst b/src/sphinx/user-guide.rst index 4790f216..4a619047 100644 --- a/src/sphinx/user-guide.rst +++ b/src/sphinx/user-guide.rst @@ -207,7 +207,7 @@ A formal to approach to commutative replicated data types (CmRDTs) or operation- Eventuate currently implements 4 out of 12 operation-based CRDTs specified in the paper. These are *Counter*, *MV-Register*, *LWW-Register* and *OR-Set*. They can be instantiated and used via their corresponding *CRDT services*. CRDT operations are asynchronous methods on the service interfaces. CRDT services free applications from dealing with low-level details like event-sourced actors or command messages directly. The following is the definition of ORSetService_: -.. includecode:: ../main/scala/com/rbmhtechnology/eventuate/crdt/ORSet.scala +.. includecode:: ../../eventuate-crdt/src/main/scala/com/rbmhtechnology/eventuate/crdt/ORSet.scala :snippet: or-set-service The ORSetService_ is a CRDT service that manages ORSet_ instances. It implements the asynchronous ``add`` and ``remove`` methods and inherits the ``value(id: String): Future[Set[A]]`` method from ``CRDTService[ORSet[A], Set[A]]`` for reading the current value. Their ``id`` parameter identifies an ``ORSet`` instance. Instances are automatically created by the service on demand. A usage example is the ReplicatedOrSetSpec_ that is based on Akka’s `multi node testkit`_. diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/DBReplica.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/DBReplica.java deleted file mode 100644 index 346aba2e..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/DBReplica.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica; - -import akka.actor.ActorSystem; -import akka.actor.Props; -import com.rbmhtechnology.eventuate.ReplicationConnection; -import com.rbmhtechnology.example.japi.dbreplica.cdc.AssetCdcOutbound; -import com.rbmhtechnology.example.japi.dbreplica.cdc.AssetCdcSettings; -import com.rbmhtechnology.example.japi.dbreplica.cli.DBReplicaCLI; -import com.rbmhtechnology.example.japi.dbreplica.domain.Asset; -import com.rbmhtechnology.example.japi.dbreplica.repository.StorageBackend; -import com.rbmhtechnology.example.japi.dbreplica.service.AssetFinder; -import com.rbmhtechnology.example.japi.dbreplica.service.AssetListener; -import com.rbmhtechnology.example.japi.dbreplica.service.AssetListeners; -import com.typesafe.config.Config; -import com.typesafe.config.ConfigFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.*; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -import java.util.Collection; - -public class DBReplica { - private static final String LOCATION_PATH = "com.rbmhtechnology.example.japi.dbreplica.DBReplica$Location%s"; - private static final String EVENTUATE_CLI_DISPATCHER = "eventuate.cli-dispatcher"; - - @Configuration - public static class LocationA extends DBReplicaLocation { - @Override - public Config getConfig() { - return ConfigFactory.load("dbreplica/location-A.conf"); - } - } - - @Configuration - public static class LocationB extends DBReplicaLocation { - @Override - public Config getConfig() { - return ConfigFactory.load("dbreplica/location-B.conf"); - } - } - - @Configuration - public static class LocationC extends DBReplicaLocation { - @Override - public Config getConfig() { - return ConfigFactory.load("dbreplica/location-C.conf"); - } - } - - @EnableAspectJAutoProxy - @EnableTransactionManagement - @ComponentScan("com.rbmhtechnology.example.japi.dbreplica") - public static abstract class DBReplicaLocation { - - @Bean - public abstract Config getConfig(); - - @Bean - public AssetCdcSettings getSettings() { - return AssetCdcSettings.create(getConfig()); - } - - @Bean - public StorageBackend getStorageBackend() { - return StorageBackend.create(getConfig()); - } - - @Bean - public PlatformTransactionManager getTxManager() { - return new DataSourceTransactionManager(getStorageBackend().getDataSource()); - } - - @Bean - public JdbcTemplate getJdbcTemplate() { - return new JdbcTemplate(getStorageBackend().getDataSource()); - } - - @Bean(destroyMethod = "terminate") - public ActorSystem getSystem() { - return ActorSystem.create(ReplicationConnection.DefaultRemoteSystemName(), getConfig()); - } - } - - public static class DBReplicaListener implements AssetListener { - - @Override - public void assetCreated(final Asset asset) { - printAsset(asset, "created"); - } - - @Override - public void assetUpdated(final Asset asset) { - printAsset(asset, "updated"); - } - - @Override - public void assetSelected(final Asset asset, final Collection conflicts) { - conflicts.forEach(conflict -> printAsset(conflict, "conflict")); - printAsset(asset, "selected"); - } - - private void printAsset(final Asset asset, final String action) { - System.out.println(String.format("%s: %s", action, asset)); - } - } - - public static void main(final String[] args) throws ClassNotFoundException { - final String location = args[0]; - final String locationClass = String.format(LOCATION_PATH, location); - final ApplicationContext context = new AnnotationConfigApplicationContext(Class.forName(locationClass)); - - final AssetListeners listeners = context.getBean(AssetListeners.class); - final AssetCdcOutbound assetService = context.getBean(AssetCdcOutbound.class); - final AssetFinder assetFinder = context.getBean(AssetFinder.class); - final ActorSystem system = context.getBean(ActorSystem.class); - - listeners.addListener(new DBReplicaListener()); - system.actorOf(Props.create(DBReplicaCLI.class, () -> new DBReplicaCLI(assetService, assetFinder)).withDispatcher(EVENTUATE_CLI_DISPATCHER)); - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdc.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdc.java deleted file mode 100644 index b6cce8b8..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdc.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.cdc; - -import com.rbmhtechnology.example.japi.dbreplica.domain.Asset; -import com.rbmhtechnology.example.japi.dbreplica.event.AssetEvent; -import com.rbmhtechnology.example.japi.dbreplica.event.AssetEvent.AssetContentUpdated; -import com.rbmhtechnology.example.japi.dbreplica.event.AssetEvent.AssetCreated; -import com.rbmhtechnology.example.japi.dbreplica.event.AssetEvent.AssetSubjectUpdated; -import javaslang.control.Match; - -import java.util.function.BiFunction; - -public class AssetCdc { - - public static BiFunction eventProjection = (asset, event) -> - Match.of(event) - .whenType(AssetCreated.class).then(ev -> new Asset(ev.assetId, ev.subject, ev.content)) - .whenType(AssetSubjectUpdated.class).then(ev -> asset.setSubject(ev.subject)) - .whenType(AssetContentUpdated.class).then(ev -> asset.setContent(ev.content)) - .get(); -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcActor.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcActor.java deleted file mode 100644 index aba6f5d5..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcActor.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.cdc; - -import akka.actor.AbstractActor; -import akka.actor.ActorRef; -import akka.actor.ActorSystem; -import akka.actor.Props; -import akka.japi.pf.ReceiveBuilder; -import com.rbmhtechnology.eventuate.DurableEvent; -import com.rbmhtechnology.eventuate.ReplicationEndpoint; -import com.rbmhtechnology.eventuate.ReplicationProtocol.*; -import com.rbmhtechnology.eventuate.VectorTime; -import com.rbmhtechnology.eventuate.log.EventLogClock; -import com.rbmhtechnology.eventuate.log.NotificationChannel; -import com.rbmhtechnology.eventuate.log.NotificationChannel.Updated; -import javaslang.Tuple; -import javaslang.Tuple2; -import javaslang.collection.List; -import javaslang.collection.Stream; -import javaslang.collection.Vector; -import javaslang.control.Try; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; -import java.util.Collection; -import java.util.concurrent.CompletableFuture; - -import static com.rbmhtechnology.example.japi.dbreplica.util.CollectionUtil.asJava; -import static com.rbmhtechnology.example.japi.dbreplica.util.CollectionUtil.asScala; -import static com.rbmhtechnology.example.japi.dbreplica.util.ScalaObjects.ReplicationProtocol.GetEventLogClock; - -public class AssetCdcActor extends AbstractActor { - - @Component - public static class Runner { - private final AssetCdcOutbound assetCdcOutbound; - private final ReplicationEndpoint endpoint; - - @Autowired - public Runner(final AssetCdcInbound assetCdcInbound, final AssetCdcOutbound assetCdcOutbound, final ActorSystem system) { - this.assetCdcOutbound = assetCdcOutbound; - - this.endpoint = ReplicationEndpoint.create( - id -> Props.create(AssetCdcActor.class, () -> new AssetCdcActor(id, assetCdcInbound, assetCdcOutbound)), - system - ); - } - - private ActorRef getLog() { - return endpoint.logs().get(ReplicationEndpoint.DefaultLogName()).get(); - } - - @PostConstruct - private void activate() { - assetCdcOutbound.setUpdateNotificationTarget(getLog()); - endpoint.activate(); - } - } - - private static final EventLogClock EVENT_LOG_CLOCK = new EventLogClock(0L, VectorTime.Zero()); - - private final String id; - private final AssetCdcInbound assetCdcInbound; - private final AssetCdcOutbound assetCdcOutbound; - private final ActorRef channel; - private EventLogClock clock; - - public AssetCdcActor(final String id, final AssetCdcInbound assetCdcInbound, final AssetCdcOutbound assetCdcOutbound) { - this.id = id; - this.assetCdcInbound = assetCdcInbound; - this.assetCdcOutbound = assetCdcOutbound; - this.channel = getContext().actorOf(Props.create(NotificationChannel.class, () -> new NotificationChannel(id))); - this.clock = EVENT_LOG_CLOCK; - - receive(ReceiveBuilder - .match(GetReplicationProgress.class, this::handleGetReplicationProgress) - .match(ReplicationRead.class, this::handleReplicationRead) - .match(ReplicationWrite.class, this::handleReplicationWrite) - .match(Updated.class, updated -> channel.tell(updated, self())) - .match(GetEventLogClock.getClass(), getClock -> sender().tell(new GetEventLogClockSuccess(EVENT_LOG_CLOCK), self())) - .build()); - } - - private void handleGetReplicationProgress(final GetReplicationProgress replicationProgess) { - final ActorRef sender = sender(); - final EventLogClock clk = this.clock; - final String sourceLogId = replicationProgess.sourceLogId(); - - CompletableFuture.supplyAsync(() -> assetCdcInbound.readReplicationProgressAndVersion(sourceLogId, clk)) - .whenComplete((result, err) -> { - if (err == null) { - sender.tell(new GetReplicationProgressSuccess(sourceLogId, result._1, result._2), self()); - } else { - sender.tell(new GetReplicationProgressFailure(err), self()); - } - }); - } - - private void handleReplicationRead(final ReplicationRead replicationRead) { - final List targets = List.of(sender(), channel); - final EventLogClock clk = this.clock; - - channel.tell(replicationRead, self()); - - CompletableFuture.supplyAsync(() -> assetCdcOutbound.readEventsAndVersion(replicationRead.fromSequenceNr(), clk)) - .whenComplete((result, err) -> { - if (err == null) { - final Collection events = result._1; - final VectorTime version = result._2; - - final Collection filteredEvents = Stream.ofAll(events) - .filter(e -> e.replicable(replicationRead.currentTargetVersionVector(), replicationRead.filter())) - .toJavaList(); - final Long readProgress = Stream.ofAll(events).lastOption().map(DurableEvent::localSequenceNr).getOrElse(() -> version.localTime(id)); - - targets.forEach(t -> t.tell(new ReplicationReadSuccess(asScala(filteredEvents), readProgress, replicationRead.targetLogId(), version), self())); - } else { - targets.forEach(t -> t.tell(new ReplicationReadFailure(err.getMessage(), replicationRead.targetLogId()), self())); - } - }); - } - - private void handleReplicationWrite(final ReplicationWrite replicationWrite) { - clock = assetCdcInbound.readClock(this.clock); - - final Tuple2> updatedClockWithEvents = Stream.ofAll(asJava(replicationWrite.events())) - .foldLeft( - Tuple.of(clock, Vector.empty()), - (acc, evt) -> { - final EventLogClock updatedClock = acc._1; - final Vector updatedEvents = acc._2; - - if (evt.before(updatedClock.versionVector())) { - return acc; - } else { - return Tuple.of(updatedClock.update(evt), updatedEvents.append(evt)); - } - }); - - final EventLogClock updatedClock = updatedClockWithEvents._1; - final Vector updatedEvents = updatedClockWithEvents._2; - - Try.run(() -> updatedEvents.forEach(assetCdcInbound::handle)) - .onSuccess(res -> { - clock = updatedClock; - Try.run(() -> assetCdcInbound.writeReplicationProgress(replicationWrite.sourceLogId(), replicationWrite.replicationProgress())) - .onSuccess(res2 -> sender().tell(new ReplicationWriteSuccess(updatedEvents.size(), - replicationWrite.sourceLogId(), replicationWrite.replicationProgress(), VectorTime.Zero()), self())) - .onFailure(err -> sender().tell(new ReplicationWriteFailure(err), self())); - channel.tell(replicationWrite, self()); - channel.tell(new Updated(asScala(updatedEvents)), self()); - }) - .onFailure(err -> sender().tell(new ReplicationWriteFailure(err), self())); - } - - @Override - public void preStart() throws Exception { - clock = assetCdcInbound.readClock(clock); - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcInbound.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcInbound.java deleted file mode 100644 index 426b5e57..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcInbound.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.cdc; - -import com.rbmhtechnology.eventuate.*; -import com.rbmhtechnology.eventuate.log.EventLogClock; -import com.rbmhtechnology.example.japi.dbreplica.domain.Asset; -import com.rbmhtechnology.example.japi.dbreplica.domain.AssetDoesNotExistException; -import com.rbmhtechnology.example.japi.dbreplica.event.AssetEvent; -import com.rbmhtechnology.example.japi.dbreplica.event.AssetEvent.AssetCreated; -import com.rbmhtechnology.example.japi.dbreplica.repository.AssetClockRepository; -import com.rbmhtechnology.example.japi.dbreplica.repository.AssetEventRepository; -import com.rbmhtechnology.example.japi.dbreplica.repository.ProgressRepository; -import com.rbmhtechnology.example.japi.dbreplica.service.AssetService; -import com.rbmhtechnology.example.japi.dbreplica.util.ScalaObjects; -import javaslang.Tuple; -import javaslang.Tuple2; -import javaslang.collection.Stream; -import javaslang.control.Match; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -import static com.rbmhtechnology.example.japi.dbreplica.cdc.AssetCdc.eventProjection; - -@Service -public class AssetCdcInbound { - @Autowired - private AssetService assetService; - @Autowired - private AssetEventRepository assetEventRepository; - @Autowired - private AssetClockRepository assetClockRepository; - @Autowired - private ProgressRepository progressRepository; - @Autowired - private AssetCdcSettings assetCdcSettings; - - @Transactional(readOnly = true) - public EventLogClock readClock(final EventLogClock clock) { - return assetEventRepository.readClock(clock); - } - - @Transactional(readOnly = true) - public Tuple2 readReplicationProgressAndVersion(final String logId, final EventLogClock clock) { - return Tuple.of(progressRepository.readReplicationProgress(logId), readClock(clock).versionVector()); - } - - @Transactional - public void writeReplicationProgress(final String logId, final Long progress) { - progressRepository.writeReplicationProgress(logId, progress); - } - - @Transactional - public void handle(final DurableEvent durableEvent) { - final Long sequenceNr = assetEventRepository.updateSequenceNr(); - final DurableEvent updatedEvent = ScalaObjects.DurableEvent.from(durableEvent).setLocalLogIdAndSequenceNr(getLogId(), sequenceNr); - - Match.of(updatedEvent.payload()) - .whenType(AssetCreated.class).thenRun(ev -> handleCreated(updatedEvent, ev)) - .whenType(AssetEvent.class).thenRun(ev -> handleUpdated(updatedEvent, ev)); - } - - private void handleCreated(final DurableEvent durableEvent, final AssetCreated assetEvent) { - assetEventRepository.insert(assetEvent.assetId, durableEvent); - assetClockRepository.insert(assetEvent.assetId, durableEvent.vectorTimestamp()); - assetService.create(eventProjection.apply(null, assetEvent)); - } - - private void handleUpdated(final DurableEvent durableEvent, final AssetEvent assetEvent) { - final Tuple2 assetWithClock = - assetService.find(assetEvent.assetId) - .flatMap(a -> assetClockRepository.find(assetEvent.assetId).map(c -> Tuple.of(a, c))) - .getOrElseThrow(() -> new AssetDoesNotExistException(assetEvent.assetId)); - - final Asset asset = assetWithClock._1; - final ScalaObjects.VectorTime clock = ScalaObjects.VectorTime.from(assetWithClock._2); - - if (clock.lt(durableEvent.vectorTimestamp())) { - final Asset updatedAsset = eventProjection.apply(asset, assetEvent); - persistUpdate(assetEvent, durableEvent, clock.get(), updatedAsset, durableEvent.vectorTimestamp()); - } else { - final ConcurrentVersions recoveredVersions = recoverVersions(assetEvent.assetId); - final ConcurrentVersions concurrentVersions = recoveredVersions.update(assetEvent, durableEvent.vectorTimestamp(), durableEvent.systemTimestamp(), durableEvent.processId()); - final List> conflictingVersions = concurrentVersions.getAll(); - final Versioned resolvedVersion = Stream.ofAll(resolveVersions(concurrentVersions).getAll()).last(); - - assetService.notifySelected(resolvedVersion.value(), Stream.ofAll(conflictingVersions).map(Versioned::value).toJavaList()); - persistUpdate(assetEvent, durableEvent, clock.get(), resolvedVersion.value(), resolvedVersion.vectorTimestamp()); - } - } - - private void persistUpdate(final AssetEvent assetEvent, final DurableEvent durableEvent, final VectorTime clock, final Asset updatedAsset, - final VectorTime updateTimestamp) { - assetEventRepository.insert(assetEvent.assetId, durableEvent); - assetClockRepository.update(assetEvent.assetId, clock.merge(updateTimestamp)); - assetService.update(updatedAsset); - } - - private ConcurrentVersions recoverVersions(final String assetId) { - return Stream.ofAll(assetEventRepository.findFor(assetId)) - .foldLeft( - zeroConcurrentVersions(), - (acc, upd) -> { - final ConcurrentVersions updated = acc.update((AssetEvent) upd.payload(), upd.vectorTimestamp(), upd.systemTimestamp(), upd.processId()); - if (updated.conflict()) { - return resolveVersions(updated); - } else { - return updated; - } - } - ); - } - - private ConcurrentVersions resolveVersions(final ConcurrentVersions concurrentVersions) { - final Versioned winningVersion = Stream.ofAll(concurrentVersions.getAll()) - .sort((v1, v2) -> { - // Let version with higher timestamp win, in case of equal timestamps that with higher processId (= creator) wins - if (v1.systemTimestamp() == v2.systemTimestamp()) { - return v1.creator().compareTo(v2.creator()); - } else { - return new Long(v1.systemTimestamp()).compareTo(v2.systemTimestamp()); - } - }).last(); - - return concurrentVersions.resolve(winningVersion.vectorTimestamp()); - } - - private String getLogId() { - return assetCdcSettings.getLogId(); - } - - private ConcurrentVersions zeroConcurrentVersions() { - return ConcurrentVersionsTree.create(eventProjection); - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcOutbound.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcOutbound.java deleted file mode 100644 index 480934f3..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcOutbound.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.cdc; - -import akka.actor.ActorRef; -import com.rbmhtechnology.eventuate.DurableEvent; -import com.rbmhtechnology.eventuate.VectorTime; -import com.rbmhtechnology.eventuate.log.EventLogClock; -import com.rbmhtechnology.eventuate.log.NotificationChannel.Updated; -import com.rbmhtechnology.example.japi.dbreplica.domain.Asset; -import com.rbmhtechnology.example.japi.dbreplica.domain.AssetDoesNotExistException; -import com.rbmhtechnology.example.japi.dbreplica.event.AssetEvent; -import com.rbmhtechnology.example.japi.dbreplica.event.AssetEvent.AssetCreated; -import com.rbmhtechnology.example.japi.dbreplica.repository.AssetClockRepository; -import com.rbmhtechnology.example.japi.dbreplica.repository.AssetEventRepository; -import com.rbmhtechnology.example.japi.dbreplica.service.AssetService; -import com.rbmhtechnology.example.japi.dbreplica.util.ScalaObjects; -import javaslang.Tuple; -import javaslang.Tuple2; -import javaslang.control.Match; -import javaslang.control.Option; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Collection; -import java.util.Collections; - -import static com.rbmhtechnology.example.japi.dbreplica.cdc.AssetCdc.eventProjection; -import static com.rbmhtechnology.example.japi.dbreplica.util.CollectionUtil.asScala; - - -@Service -public class AssetCdcOutbound { - @Autowired - private AssetService assetService; - @Autowired - private AssetEventRepository assetEventRepository; - @Autowired - private AssetClockRepository assetClockRepository; - @Autowired - private AssetCdcSettings assetCdcSettings; - - private Option updateNotificationTarget = Option.none(); - - public void setUpdateNotificationTarget(final ActorRef updateNotificationTarget) { - this.updateNotificationTarget = Option.some(updateNotificationTarget); - } - - public Tuple2, VectorTime> readEventsAndVersion(final long sequenceNr, final EventLogClock clock) { - return Tuple.of(assetEventRepository.findFrom(sequenceNr), assetEventRepository.readClock(clock).versionVector()); - } - - @Transactional - public void handle(final AssetEvent assetEvent) { - final long sequenceNr = assetEventRepository.updateSequenceNr(); - final DurableEvent durableEvent = - ScalaObjects.DurableEvent.create(assetEvent, sequenceNr, ScalaObjects.VectorTime.create(Tuple.of(getLogId(), sequenceNr)), System.currentTimeMillis(), getLogId()); - - final DurableEvent updatedEvent = Match.of(assetEvent) - .whenType(AssetCreated.class).then(ev -> handleCreated(durableEvent, ev)) - .whenType(AssetEvent.class).then(ev -> handleUpdated(durableEvent, ev)) - .get(); - - updateNotificationTarget.forEach(t -> t.tell(new Updated(asScala(Collections.singletonList(updatedEvent))), null)); - } - - private DurableEvent handleCreated(final DurableEvent durableEvent, final AssetCreated assetEvent) { - assetEventRepository.insert(assetEvent.assetId, durableEvent); - assetClockRepository.insert(assetEvent.assetId, durableEvent.vectorTimestamp()); - assetService.create(eventProjection.apply(null, assetEvent)); - - return durableEvent; - } - - private DurableEvent handleUpdated(final DurableEvent durableEvent, final AssetEvent assetEvent) { - final Tuple2 assetWithClock = - assetService.find(assetEvent.assetId) - .flatMap(a -> assetClockRepository.find(assetEvent.assetId).map(c -> Tuple.of(a, c))) - .getOrElseThrow(() -> new AssetDoesNotExistException(assetEvent.assetId)); - - final Asset asset = assetWithClock._1; - final VectorTime clock = assetWithClock._2; - - final Asset updatedAsset = eventProjection.apply(asset, assetEvent); - final VectorTime updatedClock = durableEvent.vectorTimestamp().merge(clock); - final DurableEvent updatedEvent = ScalaObjects.DurableEvent.from(durableEvent).setVectorTimestamp(updatedClock); - - assetEventRepository.insert(assetEvent.assetId, updatedEvent); - assetClockRepository.update(assetEvent.assetId, updatedClock); - assetService.update(updatedAsset); - - return updatedEvent; - } - - private String getLogId() { - return this.assetCdcSettings.getLogId(); - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcSettings.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcSettings.java deleted file mode 100644 index fa10b960..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cdc/AssetCdcSettings.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.cdc; - -import com.rbmhtechnology.eventuate.ReplicationEndpoint; -import com.typesafe.config.Config; - -import static com.rbmhtechnology.example.japi.dbreplica.util.ScalaObjects.ReplicationProtocol.ReplicationEndpointInfo; - -public class AssetCdcSettings { - - private final String logId; - - private AssetCdcSettings(final String logId) { - this.logId = logId; - } - - public static AssetCdcSettings create(final Config config) { - return new AssetCdcSettings(ReplicationEndpointInfo.logId(config.getString("eventuate.endpoint.id"), - ReplicationEndpoint.DefaultLogName())); - } - - public String getLogId() { - return logId; - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cli/Command.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cli/Command.java deleted file mode 100644 index 20c8475e..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cli/Command.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.cli; - -import javaslang.Tuple; -import javaslang.Tuple2; -import javaslang.collection.HashMap; -import javaslang.collection.List; -import javaslang.collection.Map; - -import java.util.Arrays; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -enum Command { - CREATE("^create (?\\d+) (?\\w+) (?\\w+)$", Parameters.ID, Parameters.SUBJECT, Parameters.CONTENT), - SUBJECT("^subject (?\\d+) (?\\w+)$", Parameters.ID, Parameters.SUBJECT), - CONTENT("^content (?\\d+) (?\\w+)$", Parameters.ID, Parameters.CONTENT), - LIST("^list$"), - UNKNOWN("$"); - - private final Pattern pattern; - private final List paramNames; - - Command(final String regex, final String... paramNames) { - this.pattern = Pattern.compile(regex); - this.paramNames = List.ofAll(Arrays.asList(paramNames)); - } - - public static Tuple2> fromString(final String str) { - for (Command command : Command.values()) { - final Matcher m = command.pattern.matcher(str); - - if (m.matches()) { - return Tuple.of(command, getValues(m, command.paramNames)); - } - } - return Tuple.of(UNKNOWN, HashMap.empty()); - } - - private static Map getValues(final Matcher matcher, final List paramNames) { - return paramNames.toMap(param -> Tuple.of(param, matcher.group(param))); - } - - public class Parameters { - public static final String ID = "id"; - public static final String SUBJECT = "subject"; - public static final String CONTENT = "content"; - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cli/DBReplicaCLI.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cli/DBReplicaCLI.java deleted file mode 100644 index bb1c4a3d..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/cli/DBReplicaCLI.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.cli; - -import akka.actor.AbstractActor; -import akka.actor.ActorRef; -import akka.japi.pf.ReceiveBuilder; -import com.rbmhtechnology.example.japi.dbreplica.cdc.AssetCdcOutbound; -import com.rbmhtechnology.example.japi.dbreplica.domain.AssetDoesNotExistException; -import com.rbmhtechnology.example.japi.dbreplica.event.AssetEvent.AssetContentUpdated; -import com.rbmhtechnology.example.japi.dbreplica.event.AssetEvent.AssetCreated; -import com.rbmhtechnology.example.japi.dbreplica.event.AssetEvent.AssetSubjectUpdated; -import com.rbmhtechnology.example.japi.dbreplica.service.AssetFinder; -import javaslang.Tuple2; -import javaslang.collection.Map; -import javaslang.control.Match; -import org.apache.commons.lang3.StringUtils; -import org.springframework.dao.DuplicateKeyException; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; - -import static com.rbmhtechnology.example.japi.dbreplica.cli.Command.Parameters.*; - -public class DBReplicaCLI extends AbstractActor { - - private final AssetCdcOutbound service; - private final AssetFinder assetFinder; - - private BufferedReader reader; - - public DBReplicaCLI(final AssetCdcOutbound service, final AssetFinder assetFinder) { - this.service = service; - this.assetFinder = assetFinder; - this.reader = new BufferedReader(new InputStreamReader(System.in)); - - receive(ReceiveBuilder - .match(String.class, this::handleCommand) - .build() - ); - } - - private void handleCommand(final String command) throws IOException { - final Tuple2> cmdWithValues = Command.fromString(command); - final Command cmd = cmdWithValues._1; - final Map values = cmdWithValues._2; - - try { - switch (cmd) { - case CREATE: - service.handle(new AssetCreated(values.get(ID).get(), values.get(SUBJECT).get(), values.get(CONTENT).get())); - break; - case SUBJECT: - service.handle(new AssetSubjectUpdated(values.get(ID).get(), values.get(SUBJECT).get())); - break; - case CONTENT: - service.handle(new AssetContentUpdated(values.get(ID).get(), values.get(CONTENT).get())); - break; - case LIST: - assetFinder.findAll().forEach(System.out::println); - break; - case UNKNOWN: - // fall through - default: - if (!StringUtils.isBlank(command)) { - System.out.println(String.format("unknown command: %s", command)); - } - } - } catch (AssetDoesNotExistException e) { - System.out.println(e.getMessage()); - } catch (DuplicateKeyException e) { - System.out.println(String.format("asset with id '%s' is already present", values.get(ID).get())); - } - prompt(); - } - - private void prompt() throws IOException { - final ActorRef self = self(); - final String line = reader.readLine(); - - Match.of(line) - .when((String l) -> l.equals("exit")).thenRun(() -> getContext().system().terminate()) - .otherwiseRun(l -> self.tell(l, null)); - } - - @Override - public void preStart() throws Exception { - prompt(); - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/domain/Asset.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/domain/Asset.java deleted file mode 100644 index 63288981..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/domain/Asset.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.domain; - -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; -import org.apache.commons.lang3.builder.ReflectionToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; - -public class Asset { - - private final String id; - private final String subject; - private final String content; - - public Asset(final String id, final String subject, final String content) { - this.id = id; - this.subject = subject; - this.content = content; - } - - public String getId() { - return id; - } - - public String getSubject() { - return subject; - } - - public String getContent() { - return content; - } - - public Asset setSubject(final String subject) { - return new Asset(this.id, subject, this.content); - } - - public Asset setContent(final String content) { - return new Asset(this.id, this.subject, content); - } - - @Override - public boolean equals(final Object that) { - return EqualsBuilder.reflectionEquals(this, that); - } - - @Override - public int hashCode() { - return HashCodeBuilder.reflectionHashCode(this, false); - } - - @Override - public String toString() { - return ReflectionToStringBuilder.toString(this, ToStringStyle.SIMPLE_STYLE); - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/domain/AssetDoesNotExistException.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/domain/AssetDoesNotExistException.java deleted file mode 100644 index 091d57fd..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/domain/AssetDoesNotExistException.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.domain; - -public class AssetDoesNotExistException extends RuntimeException { - - public AssetDoesNotExistException(final String assetId) { - super(String.format("asset with id '%s' does not exist", assetId)); - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/event/AssetEvent.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/event/AssetEvent.java deleted file mode 100644 index 1a5e7a55..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/event/AssetEvent.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.event; - -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; -import org.apache.commons.lang3.builder.ReflectionToStringBuilder; - -import java.io.Serializable; -import java.util.UUID; - -public abstract class AssetEvent implements Serializable { - public final String assetId; - - protected AssetEvent(final String assetId) { - this.assetId = assetId; - } - - @Override - public boolean equals(final Object other) { - return EqualsBuilder.reflectionEquals(this, other); - } - - @Override - public int hashCode() { - return HashCodeBuilder.reflectionHashCode(this, false); - } - - @Override - public String toString() { - return ReflectionToStringBuilder.toString(this); - } - - public static class AssetCreated extends AssetEvent { - public final String subject; - public final String content; - - public AssetCreated(final String id, final String subject, final String content) { - super(id); - this.subject = subject; - this.content = content; - } - - public static AssetCreated create(final String subject, final String content) { - return new AssetCreated(UUID.randomUUID().toString(), subject, content); - } - } - - public static class AssetSubjectUpdated extends AssetEvent { - public final String subject; - - public AssetSubjectUpdated(final String id, final String subject) { - super(id); - this.subject = subject; - } - } - - public static class AssetContentUpdated extends AssetEvent { - public final String content; - - public AssetContentUpdated(final String id, final String content) { - super(id); - this.content = content; - } - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/AssetClockRepository.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/AssetClockRepository.java deleted file mode 100644 index 9694147a..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/AssetClockRepository.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.repository; - -import akka.actor.ActorSystem; -import akka.serialization.Serialization; -import akka.serialization.SerializationExtension; -import com.rbmhtechnology.eventuate.VectorTime; -import javaslang.control.Option; -import javaslang.control.Try; -import org.apache.commons.io.IOUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Repository; - -import static com.rbmhtechnology.example.japi.dbreplica.util.CollectionUtil.headOption; -import static com.rbmhtechnology.example.japi.dbreplica.util.RepositoryUtil.createJdbcBlob; - -@Repository -public class AssetClockRepository { - private final JdbcTemplate template; - private final Serialization serialization; - - private final RowMapper assetClockMapper = (rs, rowNum) -> - Try.of(() -> deserializeVectorTime(IOUtils.toByteArray(rs.getBlob("vectorClock").getBinaryStream()))).get(); - - private VectorTime deserializeVectorTime(final byte[] vectorTimeBytes) { - return serialization.deserialize(vectorTimeBytes, VectorTime.class).get(); - } - - @Autowired - public AssetClockRepository(final JdbcTemplate template, final ActorSystem system) { - this.template = template; - this.serialization = SerializationExtension.get(system); - } - - public Option find(final String assetId) { - return headOption(template.query("SELECT * FROM AssetClock WHERE assetId = ? FOR UPDATE", assetClockMapper, assetId)); - } - - public int insert(final String assetId, final VectorTime clock) { - return template.update("INSERT INTO AssetClock (assetId, vectorClock) VALUES (?, ?)", assetId, createJdbcBlob(serializeVectorTime(clock))); - } - - private byte[] serializeVectorTime(final VectorTime vectorTime) { - return serialization.serialize(vectorTime).get(); - } - - public int update(final String assetId, final VectorTime clock) { - return template.update("UPDATE AssetClock SET vectorClock = ? WHERE assetId = ?", serializeVectorTime(clock), assetId); - } - - public int delete(final String assetId) { - return template.update("DELETE FROM AssetClock WHERE assetId = ?", assetId); - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/AssetEventRepository.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/AssetEventRepository.java deleted file mode 100644 index 11092f9c..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/AssetEventRepository.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.repository; - -import akka.actor.ActorSystem; -import akka.serialization.Serialization; -import akka.serialization.SerializationExtension; -import com.rbmhtechnology.eventuate.DurableEvent; -import com.rbmhtechnology.eventuate.log.EventLogClock; -import javaslang.collection.List; -import javaslang.control.Try; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Repository; - -import java.util.Collection; - -import static com.rbmhtechnology.example.japi.dbreplica.util.RepositoryUtil.createJdbcBlob; -import static org.apache.commons.io.IOUtils.toByteArray; - -@Repository -public class AssetEventRepository { - private final JdbcTemplate template; - private final Serialization serialization; - - private RowMapper sequenceNrMapper = (rs, rowNum) -> rs.getLong(1); - - private RowMapper eventMapper = (rs, rowNum) -> - Try.of(() -> deserializeDurableEvent(toByteArray(rs.getBlob(1).getBinaryStream()))).get(); - - private DurableEvent deserializeDurableEvent(final byte[] eventBytes) { - return serialization.deserialize(eventBytes, DurableEvent.class).get(); - } - - @Autowired - public AssetEventRepository(final JdbcTemplate template, final ActorSystem system) { - this.template = template; - this.serialization = SerializationExtension.get(system); - } - - public EventLogClock readClock(final EventLogClock clock) { - return List.ofAll(findFrom(clock.sequenceNr() + 1)).foldLeft(clock, EventLogClock::update); - } - - public Collection findFrom(final Long sequenceNr) { - return template.query("SELECT event FROM AssetEventLog WHERE id >= ? ORDER BY id ASC", eventMapper, sequenceNr); - } - - public Collection findFor(final String assetId) { - return template.query("SELECT event FROM AssetEventLog WHERE assetId = ? ORDER BY id ASC", eventMapper, assetId); - } - - public int insert(final String assetId, final DurableEvent event) { - return template.update("INSERT INTO AssetEventLog (id, assetId, event) VALUES (?, ?, ?)", event.localSequenceNr(), assetId, createJdbcBlob(serializeDurableEvent(event))); - } - - private byte[] serializeDurableEvent(final DurableEvent event) { - return serialization.serialize(event).get(); - } - - public long updateSequenceNr() { - return template.queryForObject("CALL NEXT VALUE FOR AssetEventLogSequence", sequenceNrMapper); - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/AssetRepository.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/AssetRepository.java deleted file mode 100644 index 4fd39b7c..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/AssetRepository.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.repository; - -import com.rbmhtechnology.example.japi.dbreplica.domain.Asset; -import javaslang.control.Option; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Repository; - -import java.util.Collection; - -import static com.rbmhtechnology.example.japi.dbreplica.util.CollectionUtil.headOption; - -@Repository -public class AssetRepository { - - @Autowired - private JdbcTemplate template; - - private final RowMapper assetMapper = (rs, rowNum) -> - new Asset( - rs.getString("id"), - rs.getString("subject"), - rs.getString("content") - ); - - public Collection findAll() { - return template.query("SELECT * FROM Asset ORDER BY id ASC", assetMapper); - } - - public Option find(final String assetId) { - return headOption(template.query("SELECT * FROM Asset WHERE id = ?", assetMapper, assetId)); - } - - public int insert(final Asset asset) { - return template.update("INSERT INTO Asset(id, subject, content) VALUES (?,?,?)", asset.getId(), asset.getSubject(), asset.getContent()); - } - - public int update(final Asset asset) { - return template.update("UPDATE Asset SET subject = ?, content = ? WHERE id = ?", asset.getSubject(), asset.getContent(), asset.getId()); - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/ProgressRepository.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/ProgressRepository.java deleted file mode 100644 index ca4f0025..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/ProgressRepository.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.repository; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.core.ConnectionCallback; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Repository; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import static com.rbmhtechnology.example.japi.dbreplica.util.CollectionUtil.headOption; - -@Repository -public class ProgressRepository { - - @Autowired - private JdbcTemplate template; - - private final RowMapper progressMapper = (rs, rowNum) -> rs.getLong("progress"); - - public long readReplicationProgress(final String logId) { - return headOption(template.query("SELECT progress FROM ReplicationProgress WHERE logId = ?", progressMapper, logId)).getOrElse(0L); - } - - public void writeReplicationProgress(final String logId, final long progress) { - template.execute(new WriteCallback(logId, progress)); - } - - private static class WriteCallback implements ConnectionCallback { - private final String logId; - private final long progress; - - public WriteCallback(final String logId, final long progress) { - this.logId = logId; - this.progress = progress; - } - - @Override - public Void doInConnection(final Connection con) throws SQLException, DataAccessException { - insertOrUpdate(con, String.format("SELECT * FROM ReplicationProgress WHERE logId = '%s'", logId), rs -> { - rs.updateString("logId", logId); - rs.updateLong("progress", progress); - }); - return null; - } - - private void insertOrUpdate(final Connection connection, final String query, final CheckedSqlConsumer operations) throws SQLException { - final Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); - final ResultSet rs = statement.executeQuery(query); - if (rs.next()) { - operations.accept(rs); - rs.updateRow(); - } else { - rs.moveToInsertRow(); - operations.accept(rs); - rs.insertRow(); - } - } - } - - private interface CheckedSqlConsumer { - void accept(T t) throws SQLException; - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/StorageBackend.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/StorageBackend.java deleted file mode 100644 index 4e163236..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/repository/StorageBackend.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.repository; - -import com.typesafe.config.Config; -import org.hsqldb.jdbc.JDBCDriver; -import org.springframework.jdbc.datasource.SimpleDriverDataSource; -import org.springframework.jdbc.datasource.embedded.ConnectionProperties; -import org.springframework.jdbc.datasource.embedded.DataSourceFactory; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; - -import javax.sql.DataSource; -import java.sql.Driver; - -public class StorageBackend { - private static final String DB_URL = "jdbc:hsqldb:file:target/DB/EP-%s"; - private static final String USERNAME = "sa"; - private static final String PASSWORD = ""; - private static final String INIT_SCRIPT_PATH = "dbreplica/create.sql"; - private static final String CONFIG_EVENTUATE_ENDPOINT_ID = "eventuate.endpoint.id"; - - private final DataSource dataSource; - - private StorageBackend(final DataSource dataSource) { - this.dataSource = dataSource; - } - - public static StorageBackend create(final Config config) { - final String endpoint = config.getString(CONFIG_EVENTUATE_ENDPOINT_ID); - final String url = String.format(DB_URL, endpoint); - - return new StorageBackend( - new EmbeddedDatabaseBuilder().setDataSourceFactory(StorageDataSourceFactory.create(url)).addScript(INIT_SCRIPT_PATH).build() - ); - } - - public DataSource getDataSource() { - return dataSource; - } - - private static class StorageDataSourceFactory implements DataSourceFactory { - private final DataSource dataSource; - - private StorageDataSourceFactory(final DataSource dataSource) { - this.dataSource = dataSource; - } - - public static StorageDataSourceFactory create(final String url) { - return new StorageDataSourceFactory(new SimpleDriverDataSource(JDBCDriver.driverInstance, url, USERNAME, PASSWORD)); - } - - @Override - public ConnectionProperties getConnectionProperties() { - return new ConnectionProperties() { - @Override - public void setDriverClass(final Class driverClass) { - } - - @Override - public void setUrl(final String url) { - } - - @Override - public void setUsername(final String username) { - } - - @Override - public void setPassword(final String password) { - } - }; - } - - @Override - public DataSource getDataSource() { - return dataSource; - } - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetFinder.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetFinder.java deleted file mode 100644 index c6889afd..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetFinder.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.service; - -import com.rbmhtechnology.example.japi.dbreplica.domain.Asset; -import javaslang.control.Option; - -import java.util.Collection; - -public interface AssetFinder { - - Collection findAll(); - - Option find(final String assetId); -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetListener.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetListener.java deleted file mode 100644 index 3188052d..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetListener.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.service; - -import com.rbmhtechnology.example.japi.dbreplica.domain.Asset; - -import java.util.Collection; - -public interface AssetListener { - - void assetCreated(Asset asset); - - void assetUpdated(Asset asset); - - void assetSelected(Asset asset, Collection conflicts); -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetListeners.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetListeners.java deleted file mode 100644 index 91a06092..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetListeners.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.service; - -import com.rbmhtechnology.example.japi.dbreplica.domain.Asset; - -import java.util.Collection; - -public interface AssetListeners { - - void addListener(final AssetListener listener); - - void notifyCreated(final Asset asset); - - void notifyUpdated(final Asset asset); - - void notifySelected(final Asset asset, final Collection conflicts); -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetListenersImpl.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetListenersImpl.java deleted file mode 100644 index 9eeb6962..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetListenersImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.service; - -import com.rbmhtechnology.example.japi.dbreplica.domain.Asset; -import javaslang.collection.List; - -import java.util.Collection; - -public abstract class AssetListenersImpl implements AssetListeners { - volatile private List listeners = List.empty(); - - public void addListener(final AssetListener listener) { - this.listeners = listeners.append(listener); - } - - public void notifyCreated(final Asset asset) { - listeners.forEach(l -> l.assetCreated(asset)); - } - - public void notifyUpdated(final Asset asset) { - listeners.forEach(l -> l.assetUpdated(asset)); - } - - public void notifySelected(final Asset asset, final Collection conflicts) { - listeners.forEach(l -> l.assetSelected(asset, conflicts)); - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetServiceImpl.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetServiceImpl.java deleted file mode 100644 index 05b4faaf..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/service/AssetServiceImpl.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.service; - -import com.rbmhtechnology.example.japi.dbreplica.domain.Asset; -import com.rbmhtechnology.example.japi.dbreplica.repository.AssetRepository; -import javaslang.control.Option; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Collection; - -import static org.springframework.transaction.annotation.Propagation.REQUIRED; - -@Service -public class AssetServiceImpl extends AssetListenersImpl implements AssetService { - - @Autowired - private AssetRepository assetRepository; - - @Transactional(readOnly = true) - public Collection findAll() { - return assetRepository.findAll(); - } - - @Transactional(readOnly = true) - public Option find(final String assetId) { - return assetRepository.find(assetId); - } - - @Transactional(propagation = REQUIRED) - public void create(final Asset asset) { - assetRepository.insert(asset); - notifyCreated(asset); - } - - @Transactional(propagation = REQUIRED) - public void update(final Asset asset) { - assetRepository.update(asset); - notifyUpdated(asset); - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/util/CollectionUtil.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/util/CollectionUtil.java deleted file mode 100644 index 0c58f3f2..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/util/CollectionUtil.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.util; - -import javaslang.control.Option; -import scala.collection.JavaConversions; -import scala.collection.immutable.Seq; - -import java.util.Collection; - -public final class CollectionUtil { - - private CollectionUtil() { - } - - public static Option headOption(final Collection collection) { - return Option.when(!collection.isEmpty(), () -> collection.iterator().next()); - } - - public static Seq asScala(final Iterable i) { - return JavaConversions.iterableAsScalaIterable(i).toList(); - } - - public static Collection asJava(final Seq seq) { - return JavaConversions.seqAsJavaList(seq); - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/util/RepositoryUtil.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/util/RepositoryUtil.java deleted file mode 100644 index 8740e367..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/util/RepositoryUtil.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.util; - -import javaslang.control.Try; -import org.hsqldb.jdbc.JDBCBlob; - -public final class RepositoryUtil { - - private RepositoryUtil() { - } - - public static JDBCBlob createJdbcBlob(final byte[] content) { - return Try.of(() -> new JDBCBlob(content)).get(); - } -} diff --git a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/util/ScalaObjects.java b/src/test/java/com/rbmhtechnology/example/japi/dbreplica/util/ScalaObjects.java deleted file mode 100644 index fd4f8afd..00000000 --- a/src/test/java/com/rbmhtechnology/example/japi/dbreplica/util/ScalaObjects.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.japi.dbreplica.util; - -import com.rbmhtechnology.example.japi.dbreplica.event.AssetEvent; -import javaslang.Tuple2; -import javaslang.collection.Stream; -import scala.Option; -import scala.collection.immutable.Set$; - -import static com.rbmhtechnology.example.japi.dbreplica.util.CollectionUtil.asScala; - -public final class ScalaObjects { - private ScalaObjects() { - } - - public static class ReplicationProtocol { - public static final com.rbmhtechnology.eventuate.ReplicationProtocol.GetEventLogClock$ GetEventLogClock = com.rbmhtechnology.eventuate.ReplicationProtocol.GetEventLogClock$.MODULE$; - public static final com.rbmhtechnology.eventuate.ReplicationProtocol.ReplicationEndpointInfo$ ReplicationEndpointInfo = com.rbmhtechnology.eventuate.ReplicationProtocol.ReplicationEndpointInfo$.MODULE$; - } - - public static class VectorTime { - private static final scala.math.PartialOrdering ordering = com.rbmhtechnology.eventuate.VectorTime.VectorTimePartialOrdering$.MODULE$; - - private final com.rbmhtechnology.eventuate.VectorTime vectorTime; - - private VectorTime(final com.rbmhtechnology.eventuate.VectorTime vectorTime) { - this.vectorTime = vectorTime; - } - - @SafeVarargs - public static com.rbmhtechnology.eventuate.VectorTime create(final Tuple2... entries) { - return com.rbmhtechnology.eventuate.VectorTime.apply(asScala(Stream.of(entries).map(e -> scala.Tuple2.apply(e._1, e._2)).toList()).toBuffer()); - } - - public static VectorTime from(final com.rbmhtechnology.eventuate.VectorTime vectorTime) { - return new VectorTime(vectorTime); - } - - public boolean lt(final com.rbmhtechnology.eventuate.VectorTime other) { - return vectorTime.$less(other, ordering); - } - - public com.rbmhtechnology.eventuate.VectorTime get() { - return vectorTime; - } - } - - public static class DurableEvent { - private final com.rbmhtechnology.eventuate.DurableEvent durableEvent; - - private DurableEvent(final com.rbmhtechnology.eventuate.DurableEvent durableEvent) { - this.durableEvent = durableEvent; - } - - public static com.rbmhtechnology.eventuate.DurableEvent create(final AssetEvent assetEvent, final long sequenceNr, - final com.rbmhtechnology.eventuate.VectorTime vectorTimestamp, - final long systemTimestamp, final String logId) { - return new com.rbmhtechnology.eventuate.DurableEvent( - assetEvent, - assetEvent.assetId, - Option.empty(), - Set$.MODULE$.empty(), - systemTimestamp, - vectorTimestamp, - logId, - logId, - sequenceNr, - Option.empty()); - } - - public static DurableEvent from(final com.rbmhtechnology.eventuate.DurableEvent durableEvent) { - return new DurableEvent(durableEvent); - } - - public com.rbmhtechnology.eventuate.DurableEvent get() { - return durableEvent; - } - - public com.rbmhtechnology.eventuate.DurableEvent setVectorTimestamp(final com.rbmhtechnology.eventuate.VectorTime vectorTimestamp) { - return durableEvent.copy( - durableEvent.payload(), - durableEvent.emitterId(), - durableEvent.emitterAggregateId(), - durableEvent.customDestinationAggregateIds(), - durableEvent.systemTimestamp(), - vectorTimestamp, - durableEvent.processId(), - durableEvent.localLogId(), - durableEvent.localSequenceNr(), - durableEvent.persistOnEventSequenceNr()); - } - - public com.rbmhtechnology.eventuate.DurableEvent setLocalLogIdAndSequenceNr(final String localLogId, final Long localSequenceNr) { - return durableEvent.copy( - durableEvent.payload(), - durableEvent.emitterId(), - durableEvent.emitterAggregateId(), - durableEvent.customDestinationAggregateIds(), - durableEvent.systemTimestamp(), - durableEvent.vectorTimestamp(), - durableEvent.processId(), - localLogId, - localSequenceNr, - durableEvent.persistOnEventSequenceNr()); - } - } -} diff --git a/src/test/resources/dbreplica/create.sql b/src/test/resources/dbreplica/create.sql deleted file mode 100644 index e5045dce..00000000 --- a/src/test/resources/dbreplica/create.sql +++ /dev/null @@ -1,24 +0,0 @@ -CREATE TABLE IF NOT EXISTS Asset ( - id VARCHAR(64) PRIMARY KEY, - subject VARCHAR(64), - content VARCHAR(64), -); - -CREATE TABLE IF NOT EXISTS ReplicationProgress ( - logId VARCHAR(64) PRIMARY KEY, - progress BIGINT -); - -CREATE TABLE IF NOT EXISTS AssetClock ( - assetId VARCHAR(64) PRIMARY KEY, - vectorClock BLOB -); - -CREATE TABLE IF NOT EXISTS AssetEventLog ( - id BIGINT PRIMARY KEY, - assetId VARCHAR(64), - event BLOB -); - -CREATE SEQUENCE IF NOT EXISTS AssetEventLogSequence AS BIGINT START WITH 1 INCREMENT BY 1; - diff --git a/src/test/resources/dbreplica/location-A.conf b/src/test/resources/dbreplica/location-A.conf deleted file mode 100644 index 9ec77b19..00000000 --- a/src/test/resources/dbreplica/location-A.conf +++ /dev/null @@ -1,29 +0,0 @@ -akka { - actor { - provider = "akka.remote.RemoteActorRefProvider" - } - - remote { - enabled-transports = ["akka.remote.netty.tcp"] - netty.tcp { - hostname = "127.0.0.1" - port = 2552 - } - } - - loglevel = "OFF" -} - -eventuate { - endpoint { - id = "A" - connections = ["127.0.0.1:2553", "127.0.0.1:2554"] - application.name = "dbreplica" - application.version = "1.0" - } - - cli-dispatcher { - executor = "thread-pool-executor" - type = PinnedDispatcher - } -} diff --git a/src/test/resources/dbreplica/location-B.conf b/src/test/resources/dbreplica/location-B.conf deleted file mode 100644 index a846a425..00000000 --- a/src/test/resources/dbreplica/location-B.conf +++ /dev/null @@ -1,29 +0,0 @@ -akka { - actor { - provider = "akka.remote.RemoteActorRefProvider" - } - - remote { - enabled-transports = ["akka.remote.netty.tcp"] - netty.tcp { - hostname = "127.0.0.1" - port = 2553 - } - } - - loglevel = "OFF" -} - -eventuate { - endpoint { - id = "B" - connections = ["127.0.0.1:2552", "127.0.0.1:2554"] - application.name = "dbreplica" - application.version = "1.0" - } - - cli-dispatcher { - executor = "thread-pool-executor" - type = PinnedDispatcher - } -} diff --git a/src/test/resources/dbreplica/location-C.conf b/src/test/resources/dbreplica/location-C.conf deleted file mode 100644 index c735c0b7..00000000 --- a/src/test/resources/dbreplica/location-C.conf +++ /dev/null @@ -1,29 +0,0 @@ -akka { - actor { - provider = "akka.remote.RemoteActorRefProvider" - } - - remote { - enabled-transports = ["akka.remote.netty.tcp"] - netty.tcp { - hostname = "127.0.0.1" - port = 2554 - } - } - - loglevel = "OFF" -} - -eventuate { - endpoint { - id = "C" - connections = ["127.0.0.1:2552", "127.0.0.1:2553"] - application.name = "dbreplica" - application.version = "1.0" - } - - cli-dispatcher { - executor = "thread-pool-executor" - type = PinnedDispatcher - } -} diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/DBReplica.scala b/src/test/scala/com/rbmhtechnology/example/dbreplica/DBReplica.scala deleted file mode 100644 index 88a35b37..00000000 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/DBReplica.scala +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.dbreplica - -import akka.actor._ - -import com.rbmhtechnology.example.dbreplica.cdc._ -import com.rbmhtechnology.example.dbreplica.domain._ -import com.rbmhtechnology.example.dbreplica.event._ -import com.rbmhtechnology.example.dbreplica.repository._ -import com.rbmhtechnology.example.dbreplica.service._ -import com.rbmhtechnology.eventuate._ -import com.typesafe.config._ - -import org.springframework.context.annotation._ -import org.springframework.jdbc.core.JdbcTemplate -import org.springframework.jdbc.datasource._ -import org.springframework.transaction.PlatformTransactionManager -import org.springframework.transaction.annotation.EnableTransactionManagement - -import scala.collection.immutable.Seq -import scala.io.Source - -@Configuration -class LocationA extends DBReplica { - override def config: Config = - ConfigFactory.load("dbreplica/location-A.conf") -} - -@Configuration -class LocationB extends DBReplica { - override def config: Config = - ConfigFactory.load("dbreplica/location-B.conf") -} - -@Configuration -class LocationC extends DBReplica { - override def config: Config = - ConfigFactory.load("dbreplica/location-C.conf") -} - -@EnableAspectJAutoProxy -@EnableTransactionManagement -@ComponentScan(Array("com.rbmhtechnology.example.dbreplica")) -abstract class DBReplica { - @Bean - def config: Config - - @Bean - def settings: AssetCdcSettings = - new AssetCdcSettings(config) - - @Bean - def storageBackend: StorageBackend = - new StorageBackend(config) - - @Bean - def txManager: PlatformTransactionManager = - new DataSourceTransactionManager(storageBackend.dataSource) - - @Bean - def jdbcTemplate: JdbcTemplate = - new JdbcTemplate(storageBackend.dataSource) - - @Bean(destroyMethod = "terminate") - def system: ActorSystem = - ActorSystem(ReplicationConnection.DefaultRemoteSystemName, config) -} - -class DBReplicaCLI(service: AssetCdcOutbound, finder: AssetFinder) extends Actor { - val lines = Source.stdin.getLines - - def receive = { - case line: String => line.split(' ').toList match { - case "create" :: id :: s :: c :: Nil => - service.handle(AssetCreated(id, s, c)); prompt() - case "subject" :: id :: s :: Nil => - service.handle(AssetSubjectUpdated(id, s)); prompt() - case "content" :: id :: c :: Nil => - service.handle(AssetContentUpdated(id, c)); prompt() - case "list" :: Nil => - finder.findAll.foreach(println); prompt() - case Nil => prompt() - case "" :: Nil => prompt() - case na :: nas => println(s"unknown command: ${na}"); prompt() - } - } - - def prompt(): Unit = { - if (lines.hasNext) lines.next() match { - case "exit" => context.system.terminate() - case line => self ! line - } - } - - override def preStart(): Unit = - prompt() -} - -class DBReplicaListener extends AssetListener { - override def assetCreated(asset: Asset): Unit = - println(s"created: $asset") - - override def assetUpdated(asset: Asset): Unit = - println(s"updated: $asset") - - override def assetSelected(asset: Asset, conflicts: Seq[Asset]): Unit = { - conflicts.foreach { asset => - println(s"conflict: $asset") - } - println(s"selected: $asset") - } -} - -object DBReplica extends App { - val location = args(0) - val context = new AnnotationConfigApplicationContext(Class.forName(s"com.rbmhtechnology.example.dbreplica.Location${location}")) - val listeners = context.getBean(classOf[AssetListeners]) - val service = context.getBean(classOf[AssetCdcOutbound]) - val finder = context.getBean(classOf[AssetFinder]) - val system = context.getBean(classOf[ActorSystem]) - - listeners.addListener(new DBReplicaListener) - system.actorOf(Props(new DBReplicaCLI(service, finder)).withDispatcher("eventuate.cli-dispatcher")) -} diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdc.scala b/src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdc.scala deleted file mode 100644 index 9da803e1..00000000 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdc.scala +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.dbreplica.cdc - -import javax.annotation.PostConstruct - -import akka.actor._ - -import com.rbmhtechnology.eventuate._ -import com.rbmhtechnology.eventuate.ReplicationProtocol._ -import com.rbmhtechnology.eventuate.log._ -import com.rbmhtechnology.eventuate.log.NotificationChannel.Updated - -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.stereotype._ - -import scala.concurrent.Future -import scala.util._ - -@Component -class AssetCdc @Autowired() ( - assetCdcInbound: AssetCdcInbound, - assetCdcOutbound: AssetCdcOutbound, - system: ActorSystem) { - - val endpoint = - ReplicationEndpoint(id => Props(new AssetCdcActor(id, assetCdcInbound, assetCdcOutbound)))(system) - - val log: ActorRef = - endpoint.logs(ReplicationEndpoint.DefaultLogName) - - @PostConstruct - def activate(): Unit = { - assetCdcOutbound.setUpdateNotificationTarget(log) - endpoint.activate() - } -} - -private class AssetCdcActor( - id: String, - assetCdcInbound: AssetCdcInbound, - assetCdcOutbound: AssetCdcOutbound) extends Actor { - - import context.dispatcher - - val channel: ActorRef = - context.actorOf(Props(new NotificationChannel(id))) - - var clock: EventLogClock = - EventLogClock() - - def receive = { - case GetReplicationProgress(sourceLogId) => - val sdr = sender() - val clk = clock - Future(assetCdcInbound.readReplicationProgressAndVersion(sourceLogId, clk)) onComplete { - // ------------------------------------------- - // TODO: send a clock update to self - // (makes future clock reads less expensive) - // ------------------------------------------- - case Success((progress, version)) => sdr ! GetReplicationProgressSuccess(sourceLogId, progress, version) - case Failure(e) => sdr ! GetReplicationProgressFailure(e) - } - case r @ ReplicationRead(from, _, filter, targetLogId, _, currentTargetVersionVector) => - val sdr = sender() - val clk = clock - channel ! r - Future(assetCdcOutbound.readEventsAndVersion(from, clk)) onComplete { - // ------------------------------------------- - // TODO: send a clock update to self - // (makes future clock reads less expensive) - // ------------------------------------------- - case Success((events, version)) => - val filteredEvents = events.filter(_.replicable(currentTargetVersionVector, filter)) - val readProgress = events.lastOption.map(_.localSequenceNr).getOrElse(version.localTime(id)) - List(sdr, channel).foreach(_ ! ReplicationReadSuccess(filteredEvents, readProgress, targetLogId, version)) - case Failure(e) => - List(sdr, channel).foreach(_ ! ReplicationReadFailure(e.getMessage, targetLogId)) - } - case w @ ReplicationWrite(events, sourceLogId, progress, _, _) => - // ------------------------------------------ - // TODO: implement batch replication writes - // ------------------------------------------ - // read the latest clock value to filter duplicates - clock = assetCdcInbound.readClock(clock) - - val (updatedClock, updatedEvents) = events.foldLeft((clock, Vector.empty[DurableEvent])) { - case ((uc, ue), evt) if evt.before(uc.versionVector) => - (uc, ue) - case ((uc, ue), evt) => - (uc.update(evt), ue :+ evt) - } - - Try(updatedEvents.foreach(assetCdcInbound.handle)) match { - case Success(_) => - clock = updatedClock - Try(assetCdcInbound.writeReplicationProgress(sourceLogId, progress)) match { - case Success(_) => sender() ! ReplicationWriteSuccess(updatedEvents.length, sourceLogId, progress, VectorTime.Zero) - case Failure(e) => sender() ! ReplicationWriteFailure(e) - } - channel ! w - channel ! Updated(updatedEvents) - case Failure(e) => - sender() ! ReplicationWriteFailure(e) - } - case Updated(written) => - channel ! Updated(written) - case GetEventLogClock => - sender() ! GetEventLogClockSuccess(EventLogClock()) - } - - override def preStart(): Unit = { - // ---------------------------------------------- - // TODO: start from a persistent clock snapshot - // ---------------------------------------------- - clock = assetCdcInbound.readClock(clock) - } -} \ No newline at end of file diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdcInbound.scala b/src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdcInbound.scala deleted file mode 100644 index 385d26a6..00000000 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdcInbound.scala +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.dbreplica.cdc - -import com.rbmhtechnology.eventuate._ -import com.rbmhtechnology.eventuate.ConcurrentVersions -import com.rbmhtechnology.eventuate.log.EventLogClock -import com.rbmhtechnology.example.dbreplica.domain._ -import com.rbmhtechnology.example.dbreplica.event._ -import com.rbmhtechnology.example.dbreplica.repository._ -import com.rbmhtechnology.example.dbreplica.service._ - -import org.springframework.beans.factory.annotation._ -import org.springframework.stereotype.Service -import org.springframework.transaction.annotation.Transactional - -@Service -class AssetCdcInbound @Autowired() ( - assetService: AssetService, - assetEventRepository: AssetEventRepository, - assetClockRepository: AssetClockRepository, - progressRepository: ProgressRepository, - assetCdcSettings: AssetCdcSettings) { - - import assetCdcSettings._ - - @Transactional(readOnly = true) - def readClock(clock: EventLogClock): EventLogClock = - assetEventRepository.readClock(clock) - - @Transactional(readOnly = true) - def readReplicationProgressAndVersion(logId: String, clock: EventLogClock): (Long, VectorTime) = - (progressRepository.readReplicationProgress(logId), assetEventRepository.readClock(clock).versionVector) - - @Transactional - def writeReplicationProgress(logId: String, progress: Long): Unit = - progressRepository.writeReplicationProgress(logId, progress) - - @Transactional - def handle(durableEvent: DurableEvent): Unit = { - // ------------------------------------------ - // TODO: implement batch replication writes - // ------------------------------------------ - val sequenceNr = assetEventRepository.updateSequenceNr() - val updatedEvent = durableEvent.copy(localLogId = logId, localSequenceNr = sequenceNr) - - updatedEvent.payload match { - case e: AssetCreated => handleCreated(updatedEvent, e) - case e: AssetEvent => handleUpdated(updatedEvent, e) - } - } - - def handleCreated(durableEvent: DurableEvent, assetEvent: AssetCreated): Unit = { - assetEventRepository.insert(assetEvent.assetId, durableEvent) - assetClockRepository.insert(assetEvent.assetId, durableEvent.vectorTimestamp) - assetService.create(eventProjection(null, assetEvent)) - } - - def handleUpdated(durableEvent: DurableEvent, assetEvent: AssetEvent): Unit = { - val current = for { - a <- assetService.find(assetEvent.assetId) - c <- assetClockRepository.find(assetEvent.assetId) - } yield (a, c) - - val (asset, clock) = current.get - val (updatedAsset, updateTimestamp) = - if (clock < durableEvent.vectorTimestamp) { - (eventProjection(asset, assetEvent), durableEvent.vectorTimestamp) - } else { // concurrent update - val recoveredVersions = recoverVersions(assetEvent.assetId) - val concurrentVersions = recoveredVersions.update(assetEvent, durableEvent.vectorTimestamp, durableEvent.systemTimestamp, durableEvent.processId) - val conflictingVersions = concurrentVersions.all - val resolvedVersion = resolveVersions(concurrentVersions).all.head - assetService.notifySelected(resolvedVersion.value, conflictingVersions.map(_.value)) - (resolvedVersion.value, resolvedVersion.vectorTimestamp) - } - - assetEventRepository.insert(assetEvent.assetId, durableEvent) - assetClockRepository.update(assetEvent.assetId, clock.merge(updateTimestamp)) - assetService.update(updatedAsset) - } - - private def recoverVersions(assetId: String): ConcurrentVersions[Asset, AssetEvent] = { - assetEventRepository.findFor(assetId).foldLeft(zeroConcurrentVersions) { - case (acc, upd) => - val updated = acc.update(upd.payload.asInstanceOf[AssetEvent], upd.vectorTimestamp, upd.systemTimestamp, upd.processId) - if (updated.conflict) resolveVersions(updated) else updated - } - } - - private def resolveVersions(concurrentVersions: ConcurrentVersions[Asset, AssetEvent]): ConcurrentVersions[Asset, AssetEvent] = { - val conflictingVersions = concurrentVersions.all.sortWith { (v1, v2) => - // Let version with higher timestamp win, in case of equal timestamps that with higher processId (= creator) wins - if (v1.systemTimestamp == v2.systemTimestamp) v1.creator < v2.creator else v1.systemTimestamp < v2.systemTimestamp - } - concurrentVersions.resolve(conflictingVersions.last.vectorTimestamp) - } - - private def zeroConcurrentVersions: ConcurrentVersions[Asset, AssetEvent] = - ConcurrentVersions[Asset, AssetEvent](null, eventProjection) -} diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdcOutbound.scala b/src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdcOutbound.scala deleted file mode 100644 index 3e425610..00000000 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/AssetCdcOutbound.scala +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.dbreplica.cdc - -import akka.actor.ActorRef - -import com.rbmhtechnology.eventuate._ -import com.rbmhtechnology.eventuate.log.EventLogClock -import com.rbmhtechnology.eventuate.log.NotificationChannel.Updated -import com.rbmhtechnology.example.dbreplica.domain._ -import com.rbmhtechnology.example.dbreplica.event._ -import com.rbmhtechnology.example.dbreplica.repository._ -import com.rbmhtechnology.example.dbreplica.service.AssetService - -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.stereotype.Service -import org.springframework.transaction.annotation.Transactional - -import scala.collection.immutable.Seq - -@Service -class AssetCdcOutbound @Autowired() ( - assetService: AssetService, - assetEventRepository: AssetEventRepository, - assetClockRepository: AssetClockRepository, - assetCdcSettings: AssetCdcSettings) { - - import assetCdcSettings._ - - private var updateNotificationTarget: Option[ActorRef] = - None - - def setUpdateNotificationTarget(target: ActorRef): Unit = - updateNotificationTarget = Some(target) - - @Transactional(readOnly = true) - def readEventsAndVersion(fromSequenceNr: Long, clock: EventLogClock): (Seq[DurableEvent], VectorTime) = - (assetEventRepository.findFrom(fromSequenceNr), assetEventRepository.readClock(clock).versionVector) - - @Transactional - def handle(assetEvent: AssetEvent): Unit = { - val sequenceNr = assetEventRepository.updateSequenceNr() - val durableEvent = createDurableEvent(assetEvent, sequenceNr, VectorTime(logId -> sequenceNr), System.currentTimeMillis) - - val updatedEvent = assetEvent match { - case e: AssetCreated => handleCreated(durableEvent, e) - case e: AssetEvent => handleUpdated(durableEvent, e) - } - - updateNotificationTarget.foreach(_ ! Updated(Seq(updatedEvent))) - } - - private def handleCreated(durableEvent: DurableEvent, assetEvent: AssetCreated): DurableEvent = { - assetEventRepository.insert(assetEvent.assetId, durableEvent) - assetClockRepository.insert(assetEvent.assetId, durableEvent.vectorTimestamp) - assetService.create(eventProjection(null, assetEvent)) - - durableEvent - } - - private def handleUpdated(durableEvent: DurableEvent, assetEvent: AssetEvent): DurableEvent = { - val current = for { - a <- assetService.find(assetEvent.assetId) - c <- assetClockRepository.find(assetEvent.assetId) - } yield (a, c) - - val (asset, clock) = current.getOrElse(throw new AssetDoesNotExistException(assetEvent.assetId)) - val updatedAsset = eventProjection(asset, assetEvent) - val updatedClock = durableEvent.vectorTimestamp.merge(clock) - val updatedEvent = durableEvent.copy(vectorTimestamp = updatedClock) - - assetEventRepository.insert(assetEvent.assetId, updatedEvent) - assetClockRepository.update(assetEvent.assetId, updatedClock) - assetService.update(updatedAsset) - - updatedEvent - } - - private def createDurableEvent(event: AssetEvent, sequenceNr: Long, vectorTimestamp: VectorTime, systemTimestamp: Long): DurableEvent = - DurableEvent( - payload = event, - emitterId = event.assetId, - vectorTimestamp = vectorTimestamp, - systemTimestamp = systemTimestamp, - processId = logId, - localLogId = logId, - localSequenceNr = sequenceNr) -} diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/package.scala b/src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/package.scala deleted file mode 100644 index 09715947..00000000 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/cdc/package.scala +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.dbreplica - -import com.rbmhtechnology.example.dbreplica.domain.Asset -import com.rbmhtechnology.example.dbreplica.event._ - -package object cdc { - val eventProjection: (Asset, AssetEvent) => Asset = { - case (_, e: AssetCreated) => Asset(e.assetId, e.subject, e.content) - case (a, e: AssetSubjectUpdated) => a.copy(subject = e.subject) - case (a, e: AssetContentUpdated) => a.copy(content = e.content) - } -} diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/event/AssetEvent.scala b/src/test/scala/com/rbmhtechnology/example/dbreplica/event/AssetEvent.scala deleted file mode 100644 index 28d9ae64..00000000 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/event/AssetEvent.scala +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.dbreplica.event - -import java.util.UUID - -sealed trait AssetEvent { - def assetId: String -} - -object AssetCreated { - def apply(subject: String, content: String): AssetCreated = - new AssetCreated(UUID.randomUUID().toString, subject, content) -} - -case class AssetCreated(assetId: String, subject: String, content: String) extends AssetEvent -case class AssetSubjectUpdated(assetId: String, subject: String) extends AssetEvent -case class AssetContentUpdated(assetId: String, content: String) extends AssetEvent - diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/repository/AssetClockRepository.scala b/src/test/scala/com/rbmhtechnology/example/dbreplica/repository/AssetClockRepository.scala deleted file mode 100644 index 889c7555..00000000 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/repository/AssetClockRepository.scala +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.dbreplica.repository - -import java.sql.ResultSet - -import akka.actor.ActorSystem -import akka.serialization.SerializationExtension - -import com.rbmhtechnology.eventuate.VectorTime - -import org.apache.commons.io.IOUtils -import org.hsqldb.jdbc.JDBCBlob -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.jdbc.core._ -import org.springframework.stereotype.Repository - -import scala.collection.JavaConverters._ - -@Repository -class AssetClockRepository @Autowired() (template: JdbcTemplate, system: ActorSystem) { - import IOUtils._ - - private val serialization = SerializationExtension(system) - - def find(assetId: String): Option[VectorTime] = - template.query("SELECT * FROM AssetClock WHERE assetId = ? FOR UPDATE", Array[AnyRef](assetId), assetClockMapper).asScala.headOption - - def insert(assetId: String, clock: VectorTime): Int = - template.update("INSERT INTO AssetClock (assetId, vectorClock) VALUES (?, ?)", assetId, new JDBCBlob(serializeVectorTime(clock))) - - def update(assetId: String, clock: VectorTime): Int = - template.update("UPDATE AssetClock SET vectorClock = ? WHERE assetId = ?", serializeVectorTime(clock), assetId) - - def delete(assetId: String): Int = - template.update("DELETE FROM AssetClock WHERE assetId = ?", assetId) - - private def serializeVectorTime(vectorTime: VectorTime): Array[Byte] = - serialization.serialize(vectorTime).get - - private def deserializeVectorTime(vectorTimeBytes: Array[Byte]): VectorTime = - serialization.deserialize(vectorTimeBytes, classOf[VectorTime]).get - - private val assetClockMapper = new RowMapper[VectorTime] { - override def mapRow(rs: ResultSet, rowNum: Int): VectorTime = - deserializeVectorTime(toByteArray(rs.getBlob("vectorClock").getBinaryStream)) - } -} - diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/repository/AssetEventRepository.scala b/src/test/scala/com/rbmhtechnology/example/dbreplica/repository/AssetEventRepository.scala deleted file mode 100644 index 85ad097b..00000000 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/repository/AssetEventRepository.scala +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.dbreplica.repository - -import java.lang.{ Long => JLong } -import java.sql.ResultSet - -import akka.actor.ActorSystem -import akka.serialization.SerializationExtension - -import com.rbmhtechnology.eventuate._ -import com.rbmhtechnology.eventuate.log.EventLogClock - -import org.apache.commons.io.IOUtils -import org.hsqldb.jdbc.JDBCBlob -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.jdbc.core._ -import org.springframework.stereotype._ -import org.springframework.transaction.annotation.Transactional - -import scala.collection.JavaConverters._ -import scala.collection.immutable.Seq -import scala.language.implicitConversions - -@Repository -class AssetEventRepository @Autowired() (template: JdbcTemplate, system: ActorSystem) { - import IOUtils._ - - private val serialization = SerializationExtension(system) - - def readClock(clock: EventLogClock): EventLogClock = - findFrom(clock.sequenceNr + 1L).foldLeft(clock)(_ update _) - - def findFrom(sequenceNr: Long): Seq[DurableEvent] = - template.query("SELECT event FROM AssetEventLog WHERE id >= ? ORDER BY id ASC", Array[AnyRef](sequenceNr: JLong), eventMapper).asScala.toVector - - def findFor(assetId: String): Seq[DurableEvent] = - template.query("SELECT event FROM AssetEventLog WHERE assetId = ? ORDER BY id ASC", Array[AnyRef](assetId), eventMapper).asScala.toVector - - def insert(assetId: String, event: DurableEvent): Int = - template.update("INSERT INTO AssetEventLog (id, assetId, event) VALUES (?, ?, ?)", event.localSequenceNr: JLong, assetId, new JDBCBlob(serializeDurableEvent(event))) - - def updateSequenceNr(): Long = - template.query("CALL NEXT VALUE FOR AssetEventLogSequence", sequenceNrMapper).asScala.head - - private def serializeVectorTime(vectorTime: VectorTime): Array[Byte] = - serialization.serialize(vectorTime).get - - private def deserializeVectorTime(vectorTimeBytes: Array[Byte]): VectorTime = - serialization.deserialize(vectorTimeBytes, classOf[VectorTime]).get - - private def serializeDurableEvent(event: DurableEvent): Array[Byte] = - serialization.serialize(event).get - - private def deserializeDurableEvent(eventBytes: Array[Byte]): DurableEvent = - serialization.deserialize(eventBytes, classOf[DurableEvent]).get - - private val sequenceNrMapper = new RowMapper[Long] { - override def mapRow(rs: ResultSet, rowNum: Int): Long = - rs.getLong(1) - } - - private val eventMapper = new RowMapper[DurableEvent] { - override def mapRow(rs: ResultSet, rowNum: Int): DurableEvent = - deserializeDurableEvent(toByteArray(rs.getBlob(1).getBinaryStream)) - } - - private val versionMapper = new RowMapper[VectorTime] { - override def mapRow(rs: ResultSet, rowNum: Int): VectorTime = - deserializeVectorTime(toByteArray(rs.getBlob(1).getBinaryStream)) - } -} - diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/repository/AssetRepository.scala b/src/test/scala/com/rbmhtechnology/example/dbreplica/repository/AssetRepository.scala deleted file mode 100644 index d2bd0554..00000000 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/repository/AssetRepository.scala +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.dbreplica.repository - -import java.sql.ResultSet - -import com.rbmhtechnology.example.dbreplica.domain.Asset - -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.jdbc.core._ -import org.springframework.stereotype.Repository - -import scala.collection.JavaConverters._ -import scala.collection.immutable.Seq - -@Repository -class AssetRepository @Autowired() (template: JdbcTemplate) { - def findAll(): Seq[Asset] = - template.query("SELECT * FROM Asset ORDER BY id ASC", AssetMapper).asScala.toVector - - def find(assetId: String): Option[Asset] = - template.query("SELECT * FROM Asset WHERE id = ?", Array[AnyRef](assetId), AssetMapper).asScala.headOption - - def insert(asset: Asset): Int = - template.update("INSERT INTO Asset (id, subject, content) VALUES (?, ?, ?)", asset.id, asset.subject, asset.content) - - def update(asset: Asset): Int = - template.update("UPDATE Asset SET subject = ?, content = ? WHERE id = ?", asset.subject, asset.content, asset.id) -} - -private object AssetMapper extends RowMapper[Asset] { - override def mapRow(rs: ResultSet, i: Int): Asset = - Asset(rs.getString("id"), rs.getString("subject"), rs.getString("content")) -} diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/repository/ProgressRepository.scala b/src/test/scala/com/rbmhtechnology/example/dbreplica/repository/ProgressRepository.scala deleted file mode 100644 index db83538a..00000000 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/repository/ProgressRepository.scala +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.dbreplica.repository - -import java.lang.{ Long => JLong } -import java.sql.{ Connection, ResultSet } - -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.jdbc.core._ -import org.springframework.stereotype.Repository - -import scala.collection.JavaConverters._ - -@Repository -class ProgressRepository @Autowired() (template: JdbcTemplate) { - def readReplicationProgress(logId: String): Long = - template.query("SELECT progress FROM ReplicationProgress WHERE logId = ?", Array[AnyRef](logId), ProgressMapper).asScala.headOption.getOrElse(0L) - - def writeReplicationProgress(logId: String, progress: Long): Unit = - template.execute(new WriteCallback(logId, progress)) -} - -private object ProgressMapper extends RowMapper[Long] { - override def mapRow(rs: ResultSet, rowNum: Int): Long = - rs.getLong("progress") -} - -private class WriteCallback(logId: String, progress: Long) extends ConnectionCallback[Unit] { - override def doInConnection(connection: Connection): Unit = { - insertOrUpdate(connection, s"SELECT * FROM ReplicationProgress WHERE logId = '$logId'") { rs => - rs.updateString("logId", logId) - rs.updateLong("progress", progress: JLong) - } - } - - private def insertOrUpdate(connection: Connection, query: String)(operations: ResultSet => Unit) = { - val stmt = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE) - val rs = stmt.executeQuery(query) - if (rs.next()) { - operations(rs) - rs.updateRow() - } else { - rs.moveToInsertRow() - operations(rs) - rs.insertRow() - } - } -} - diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/repository/StorageBackend.scala b/src/test/scala/com/rbmhtechnology/example/dbreplica/repository/StorageBackend.scala deleted file mode 100644 index 92fd9c43..00000000 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/repository/StorageBackend.scala +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.dbreplica.repository - -import java.sql.Driver -import javax.sql.DataSource - -import com.typesafe.config.Config -import org.hsqldb.jdbcDriver - -import org.springframework.jdbc.datasource.SimpleDriverDataSource -import org.springframework.jdbc.datasource.embedded._ - -class StorageBackend(config: Config) { - val endpointId: String = - config.getString("eventuate.endpoint.id") - - val dataSource: DataSource = - new EmbeddedDatabaseBuilder().setDataSourceFactory(dataSourceFactory(s"jdbc:hsqldb:file:target/DB/EP-$endpointId")).addScript("dbreplica/create.sql").build() - - def dataSourceFactory(url: String): DataSourceFactory = new DataSourceFactory { - private val dataSource: SimpleDriverDataSource = new SimpleDriverDataSource - - dataSource.setDriverClass(classOf[jdbcDriver]) - dataSource.setUrl(url) - dataSource.setUsername("sa") - dataSource.setPassword("") - - def getDataSource: DataSource = - dataSource - - def getConnectionProperties: ConnectionProperties = new ConnectionProperties() { - def setDriverClass(driverClass: Class[_ <: Driver]) = () - def setUsername(username: String) = () - def setPassword(password: String) = () - def setUrl(url: String) = () - } - } -} diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/service/AssetListener.scala b/src/test/scala/com/rbmhtechnology/example/dbreplica/service/AssetListener.scala deleted file mode 100644 index 8afb3a68..00000000 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/service/AssetListener.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.dbreplica.service - -import com.rbmhtechnology.example.dbreplica.domain.Asset - -import scala.collection.immutable.Seq - -trait AssetListener { - def assetCreated(asset: Asset): Unit - def assetUpdated(asset: Asset): Unit - def assetSelected(asset: Asset, conflicts: Seq[Asset]): Unit -} diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/service/AssetListeners.scala b/src/test/scala/com/rbmhtechnology/example/dbreplica/service/AssetListeners.scala deleted file mode 100644 index afa38353..00000000 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/service/AssetListeners.scala +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.dbreplica.service - -import com.rbmhtechnology.example.dbreplica.domain._ - -import scala.collection.immutable.Seq - -trait AssetListeners { - @volatile private var listeners: Seq[AssetListener] = Vector.empty - - def addListener(listener: AssetListener): Unit = - listeners = listeners :+ listener - - def notifyCreated(asset: Asset): Unit = - listeners.foreach(_.assetCreated(asset)) - - def notifyUpdated(asset: Asset): Unit = - listeners.foreach(_.assetUpdated(asset)) - - def notifySelected(asset: Asset, conflicts: Seq[Asset]): Unit = - listeners.foreach(_.assetSelected(asset, conflicts)) -} diff --git a/src/test/scala/com/rbmhtechnology/example/dbreplica/service/AssetService.scala b/src/test/scala/com/rbmhtechnology/example/dbreplica/service/AssetService.scala deleted file mode 100644 index 88d63bb8..00000000 --- a/src/test/scala/com/rbmhtechnology/example/dbreplica/service/AssetService.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2015 - 2016 Red Bull Media House GmbH - all rights reserved. - * - * Licensed 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 com.rbmhtechnology.example.dbreplica.service - -import com.rbmhtechnology.example.dbreplica.domain._ -import com.rbmhtechnology.example.dbreplica.repository._ - -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.stereotype.Service -import org.springframework.transaction.annotation.Transactional -import org.springframework.transaction.annotation.Propagation._ - -import scala.collection.immutable.Seq - -trait AssetFinder { - def findAll: Seq[Asset] - def find(assetId: String): Option[Asset] -} - -trait AssetService extends AssetFinder with AssetListeners { - def create(asset: Asset): Unit - def update(asset: Asset): Unit -} - -@Service -class AssetServiceImpl @Autowired() (val assetRepository: AssetRepository) extends AssetService { - @Transactional(readOnly = true) - def findAll: Seq[Asset] = - assetRepository.findAll() - - @Transactional(readOnly = true) - def find(assetId: String): Option[Asset] = - assetRepository.find(assetId) - - @Transactional(propagation = REQUIRED) - def create(asset: Asset): Unit = { - assetRepository.insert(asset) - notifyCreated(asset) - } - - @Transactional(propagation = REQUIRED) - def update(asset: Asset): Unit = { - assetRepository.update(asset) - notifyUpdated(asset) - } -} \ No newline at end of file