synapse-core 0.5.2 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/synapse/auditing/command_metadata_provider.rb +12 -0
- data/lib/synapse/auditing/correlation_data_provider.rb +19 -0
- data/lib/synapse/auditing/data_provider.rb +2 -30
- data/lib/synapse/auditing/dispatch_interceptor.rb +6 -5
- data/lib/synapse/auditing/unit_listener.rb +7 -6
- data/lib/synapse/auditing.rb +2 -0
- data/lib/synapse/configuration/component/command_bus/gateway.rb +1 -0
- data/lib/synapse/configuration/component/command_bus/simple_command_bus.rb +9 -1
- data/lib/synapse/configuration/component/event_bus/simple_event_bus.rb +1 -0
- data/lib/synapse/configuration/component/event_sourcing/aggregate_snapshot_taker.rb +7 -0
- data/lib/synapse/configuration/component/event_sourcing/interval_snapshot_policy.rb +1 -1
- data/lib/synapse/configuration/component/event_sourcing/repository.rb +8 -0
- data/lib/synapse/configuration/component/process_manager/container_resource_injector.rb +22 -0
- data/lib/synapse/configuration/component/process_manager/generic_process_factory.rb +43 -0
- data/lib/synapse/configuration/component/process_manager/mapping_process_manager.rb +102 -0
- data/lib/synapse/configuration/component/process_manager.rb +18 -0
- data/lib/synapse/configuration/component/repository/locking_repository.rb +10 -1
- data/lib/synapse/configuration/component/repository/simple_repository.rb +1 -0
- data/lib/synapse/configuration/component/serialization/converter_factory.rb +2 -1
- data/lib/synapse/configuration/component/serialization/serializer.rb +10 -1
- data/lib/synapse/configuration/component/uow/unit_factory.rb +3 -1
- data/lib/synapse/configuration/component/upcasting/upcaster_chain.rb +3 -1
- data/lib/synapse/configuration/container.rb +17 -2
- data/lib/synapse/configuration/definition_builder.rb +14 -0
- data/lib/synapse/configuration.rb +1 -0
- data/lib/synapse/process_manager/process_manager.rb +9 -0
- data/lib/synapse/serialization/serializer/marshal.rb +4 -2
- data/lib/synapse/version.rb +1 -1
- data/lib/synapse.rb +1 -0
- data/test/auditing/data_provider_test.rb +1 -1
- data/test/auditing/unit_listener_test.rb +1 -1
- data/test/configuration/component/process_manager/container_resource_injector_test.rb +21 -0
- data/test/configuration/component/process_manager/mapping_process_manager_test.rb +37 -0
- data/test/configuration/container_test.rb +24 -0
- metadata +32 -9
- checksums.yaml +0 -7
@@ -0,0 +1,12 @@
|
|
1
|
+
module Synapse
|
2
|
+
module Auditing
|
3
|
+
# Implementation of an audit provider that simply audits a command's metadata
|
4
|
+
class CommandMetadataProvider < AuditDataProvider
|
5
|
+
# @param [CommandMessage] command
|
6
|
+
# @return [Hash]
|
7
|
+
def provide_data_for(command)
|
8
|
+
command.metadata
|
9
|
+
end
|
10
|
+
end # CommandMetadataProvider
|
11
|
+
end # Auditing
|
12
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Synapse
|
2
|
+
module Auditing
|
3
|
+
# Implementation of an audit provider that attaches a command's identifier to each event
|
4
|
+
# produced as a result of the execution of that command
|
5
|
+
class CorrelationDataProvider < AuditDataProvider
|
6
|
+
# @param [Symbol] correlation_key
|
7
|
+
# @return [undefined]
|
8
|
+
def initialize(correlation_key)
|
9
|
+
@correlation_key = correlation_key
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param [CommandMessage] command
|
13
|
+
# @return [Hash]
|
14
|
+
def provide_data_for(command)
|
15
|
+
Hash[@correlation_key, command.id]
|
16
|
+
end
|
17
|
+
end # CorrelationDataProvider
|
18
|
+
end # Auditing
|
19
|
+
end
|
@@ -9,34 +9,6 @@ module Synapse
|
|
9
9
|
# @param [CommandMessage] command
|
10
10
|
# @return [Hash]
|
11
11
|
def provide_data_for(command); end
|
12
|
-
end
|
13
|
-
|
14
|
-
# Implementation of an audit provider that simply audits a command's metadata
|
15
|
-
class CommandMetadataProvider < AuditDataProvider
|
16
|
-
# @param [CommandMessage] command
|
17
|
-
# @return [Hash]
|
18
|
-
def provide_data_for(command)
|
19
|
-
command.metadata
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# Implementation of an audit provider that attaches a command's identifier to each event
|
24
|
-
# produced as a result of the execution of that command
|
25
|
-
class CorrelationDataProvider < AuditDataProvider
|
26
|
-
# The default key to use when correlating events with commands
|
27
|
-
DEFAULT_KEY = :command_id
|
28
|
-
|
29
|
-
# @param [Symbol] correlation_key
|
30
|
-
# @return [undefined]
|
31
|
-
def initialize(correlation_key = DEFAULT_KEY)
|
32
|
-
@correlation_key = correlation_key
|
33
|
-
end
|
34
|
-
|
35
|
-
# @param [CommandMessage] command
|
36
|
-
# @return [Hash]
|
37
|
-
def provide_data_for(command)
|
38
|
-
Hash[@correlation_key, command.id]
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
12
|
+
end # AuditDataProvider
|
13
|
+
end # Auditing
|
42
14
|
end
|
@@ -20,10 +20,11 @@ module Synapse
|
|
20
20
|
audit_listener = AuditingUnitOfWorkListener.new command, @data_providers, @loggers
|
21
21
|
unit.register_listener audit_listener
|
22
22
|
|
23
|
-
chain.proceed
|
24
|
-
|
25
|
-
|
23
|
+
result = chain.proceed command
|
24
|
+
audit_listener.return_value = result
|
25
|
+
|
26
|
+
result
|
26
27
|
end
|
27
|
-
end
|
28
|
-
end
|
28
|
+
end # AuditingDispatchInterceptor
|
29
|
+
end # Auditing
|
29
30
|
end
|
@@ -27,9 +27,10 @@ module Synapse
|
|
27
27
|
audit_data.merge! provider.provide_data_for @command
|
28
28
|
end
|
29
29
|
|
30
|
-
event.and_metadata
|
31
|
-
|
32
|
-
|
30
|
+
event = event.and_metadata audit_data
|
31
|
+
@recorded_events.push event
|
32
|
+
|
33
|
+
event
|
33
34
|
end
|
34
35
|
|
35
36
|
# @param [UnitOfWork] unit
|
@@ -45,9 +46,9 @@ module Synapse
|
|
45
46
|
# @return [undefined]
|
46
47
|
def on_rollback(unit, cause = nil)
|
47
48
|
@loggers.each do |logger|
|
48
|
-
logger.
|
49
|
+
logger.on_failure @command, cause, @recorded_events
|
49
50
|
end
|
50
51
|
end
|
51
|
-
end
|
52
|
-
end
|
52
|
+
end # AuditingUnitOfWorkListener
|
53
|
+
end # Auditing
|
53
54
|
end
|
data/lib/synapse/auditing.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'synapse/auditing/audit_logger'
|
2
2
|
require 'synapse/auditing/data_provider'
|
3
|
+
require 'synapse/auditing/command_metadata_provider'
|
4
|
+
require 'synapse/auditing/correlation_data_provider'
|
3
5
|
require 'synapse/auditing/dispatch_interceptor'
|
4
6
|
require 'synapse/auditing/unit_listener'
|
@@ -14,6 +14,7 @@ module Synapse
|
|
14
14
|
class CommandGatewayDefinitionBuilder < DefinitionBuilder
|
15
15
|
# Changes the command bus that commands are sent from the gateway
|
16
16
|
#
|
17
|
+
# @see Command::CommandBus
|
17
18
|
# @param [Symbol] command_bus
|
18
19
|
# @return [undefined]
|
19
20
|
def use_command_bus(command_bus)
|
@@ -17,6 +17,7 @@ module Synapse
|
|
17
17
|
# Note that command handlers that are tagged must support self-subscription to the
|
18
18
|
# command bus. An example of a handler capable of doing so is the wiring command handler.
|
19
19
|
#
|
20
|
+
# @see Command::MappingCommandHandler
|
20
21
|
# @param [Symbol] handler_tag
|
21
22
|
# @return [undefined]
|
22
23
|
def use_handler_tag(handler_tag)
|
@@ -25,6 +26,7 @@ module Synapse
|
|
25
26
|
|
26
27
|
# Changes the tag to use to automatically register command filters
|
27
28
|
#
|
29
|
+
# @see Command::CommandFilter
|
28
30
|
# @param [Symbol] filter_tag
|
29
31
|
# @return [undefined]
|
30
32
|
def use_filter_tag(filter_tag)
|
@@ -33,6 +35,7 @@ module Synapse
|
|
33
35
|
|
34
36
|
# Changes the tag to use to automatically register command filters
|
35
37
|
#
|
38
|
+
# @see Command::DispatchInterceptor
|
36
39
|
# @param [Symbol] interceptor_tag
|
37
40
|
# @return [undefined]
|
38
41
|
def use_interceptor_tag(interceptor_tag)
|
@@ -43,6 +46,7 @@ module Synapse
|
|
43
46
|
#
|
44
47
|
# By default, the command bus will always rollback on an exception
|
45
48
|
#
|
49
|
+
# @see Command::RollbackPolicy
|
46
50
|
# @param [Symbol] rollback_policy
|
47
51
|
# @return [undefined]
|
48
52
|
def use_rollback_policy(rollback_policy)
|
@@ -51,6 +55,7 @@ module Synapse
|
|
51
55
|
|
52
56
|
# Changes the unit of work factory to use with this command bus
|
53
57
|
#
|
58
|
+
# @see UnitOfWork::UnitOfWorkFactory
|
54
59
|
# @param [Symbol] unit_factory
|
55
60
|
# @return [undefined]
|
56
61
|
def use_unit_factory(unit_factory)
|
@@ -73,7 +78,10 @@ module Synapse
|
|
73
78
|
unit_factory = resolve @unit_factory
|
74
79
|
|
75
80
|
command_bus = create_command_bus unit_factory
|
76
|
-
|
81
|
+
|
82
|
+
if @rollback_policy
|
83
|
+
command_bus.rollback_policy = resolve @rollback_policy
|
84
|
+
end
|
77
85
|
|
78
86
|
with_tagged @handler_tag do |handler|
|
79
87
|
handler.subscribe command_bus
|
@@ -12,6 +12,7 @@ module Synapse
|
|
12
12
|
class SimpleEventBusDefinitionBuilder < DefinitionBuilder
|
13
13
|
# Changes the tag to use to automatically subscribe event listeners
|
14
14
|
#
|
15
|
+
# @see EventBus::EventListener
|
15
16
|
# @param [Symbol] listener_tag
|
16
17
|
# @return [undefined]
|
17
18
|
def use_listener_tag(listener_tag)
|
@@ -11,12 +11,19 @@ module Synapse
|
|
11
11
|
# use_event_store :alt_event_store
|
12
12
|
# end
|
13
13
|
class AggregateSnapshotTakerDefinitionBuilder < DefinitionBuilder
|
14
|
+
# Changes the tag used to find aggregate factories necessary for creating aggregates so that
|
15
|
+
# a snapshot can be taken of their current state
|
16
|
+
#
|
17
|
+
# @see EventSourcing::AggregateFactory
|
14
18
|
# @param [Symbol] aggregate_factory_tag
|
15
19
|
# @return [undefined]
|
16
20
|
def use_aggregate_factory_tag(aggregate_factory_tag)
|
17
21
|
@aggregate_factory_tag = aggregate_factory_tag
|
18
22
|
end
|
19
23
|
|
24
|
+
# Changes the event store used to load and store aggregates
|
25
|
+
#
|
26
|
+
# @see EventStore::SnapshotEventStore
|
20
27
|
# @param [Symbol] event_store
|
21
28
|
# @return [undefined]
|
22
29
|
def use_event_store(event_store)
|
@@ -36,30 +36,38 @@ module Synapse
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
# Changes the aggregate factory used to create aggregates that will have their state
|
40
|
+
# initialized from an event stream
|
41
|
+
#
|
42
|
+
# @see EventSourcing::AggregateFactory
|
39
43
|
# @param [Symbol] aggregate_factory
|
40
44
|
# @return [undefined]
|
41
45
|
def use_aggregate_factory(aggregate_factory)
|
42
46
|
@aggregate_factory = aggregate_factory
|
43
47
|
end
|
44
48
|
|
49
|
+
# @see EventSourcing::ConflictResolver
|
45
50
|
# @param [Symbol] conflict_resolver
|
46
51
|
# @return [undefined]
|
47
52
|
def use_conflict_resolver(conflict_resolver)
|
48
53
|
@conflict_resolver = conflict_resolver
|
49
54
|
end
|
50
55
|
|
56
|
+
# @see EventStore::EventStore
|
51
57
|
# @param [Symbol] event_store
|
52
58
|
# @return [undefined]
|
53
59
|
def use_event_store(event_store)
|
54
60
|
@event_store = event_store
|
55
61
|
end
|
56
62
|
|
63
|
+
# @see EventSourcing::SnapshotPolicy
|
57
64
|
# @param [Symbol] snapshot_policy
|
58
65
|
# @return [undefined]
|
59
66
|
def use_snapshot_policy(snapshot_policy)
|
60
67
|
@snapshot_policy = snapshot_policy
|
61
68
|
end
|
62
69
|
|
70
|
+
# @see EventSourcing::SnapshotTaker
|
63
71
|
# @param [Symbol] snapshot_taker
|
64
72
|
# @return [undefined]
|
65
73
|
def use_snapshot_taker(snapshot_taker)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Synapse
|
2
|
+
module Configuration
|
3
|
+
# Definition builder used to create a resource injector that uses the service container
|
4
|
+
#
|
5
|
+
# @example The minimum possible effort to build a resource injector
|
6
|
+
# container_resource_injector
|
7
|
+
class ContainerResourceInjectorDefinitionBuilder < DefinitionBuilder
|
8
|
+
# No options available for this definition builder
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
# @return [undefined]
|
13
|
+
def populate_defaults
|
14
|
+
identified_by :resource_injector
|
15
|
+
|
16
|
+
use_factory do
|
17
|
+
ProcessManager::ContainerResourceInjector.new @container
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end # ContainerResourceInjectorDefinitionBuilder
|
21
|
+
end # Configuration
|
22
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Synapse
|
2
|
+
module Configuration
|
3
|
+
# Definition builder used to create a generic process factory
|
4
|
+
#
|
5
|
+
# @example The minimum possible effort to build a process factory
|
6
|
+
# process_factory
|
7
|
+
#
|
8
|
+
# @example Use a custom resource injector
|
9
|
+
# process_factory :alt_process_factory do
|
10
|
+
# use_resource_injector :alt_resource_injector
|
11
|
+
# end
|
12
|
+
class GenericProcessFactoryDefinitionBuilder < DefinitionBuilder
|
13
|
+
# Changes the resource injector used by this process factory
|
14
|
+
#
|
15
|
+
# @see ProcessManager::ResourceInjector
|
16
|
+
# @param [Symbol] resource_injector
|
17
|
+
# @return [undefined]
|
18
|
+
def use_resource_injector(resource_injector)
|
19
|
+
@resource_injector = resource_injector
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
# @return [undefined]
|
25
|
+
def populate_defaults
|
26
|
+
identified_by :process_factory
|
27
|
+
|
28
|
+
use_resource_injector :resource_injector
|
29
|
+
|
30
|
+
use_factory do
|
31
|
+
resource_injector = resolve @resource_injector, true
|
32
|
+
|
33
|
+
process_factory = ProcessManager::GenericProcessFactory.new
|
34
|
+
if resource_injector
|
35
|
+
process_factory.resource_injector = resource_injector
|
36
|
+
end
|
37
|
+
|
38
|
+
process_factory
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end # GenericProcessFactoryDefinitionBuilder
|
42
|
+
end # Configuration
|
43
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module Synapse
|
2
|
+
module Configuration
|
3
|
+
# Definition builder used to create a mapping process manager
|
4
|
+
#
|
5
|
+
# Since process managers are effectively listeners on the event bus, definitions created by
|
6
|
+
# this builder will be tagged with `:event_listener`
|
7
|
+
#
|
8
|
+
# @example The minimum possible effort to build a process manager
|
9
|
+
# process_manager do
|
10
|
+
# use_process_types MoneyTransferProcess
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# @example Build a process manager with alternate components
|
14
|
+
# process_manager :alt_process_manager do
|
15
|
+
# use_process_types MoneyTransferProcess
|
16
|
+
#
|
17
|
+
# use_process_repository :alt_process_repository
|
18
|
+
# use_process_factory :alt_process_factory
|
19
|
+
#
|
20
|
+
# # Use a different tag for subscribing to an event bus
|
21
|
+
# replace_tags :alt_event_listener
|
22
|
+
# end
|
23
|
+
class MappingProcessManagerDefinitionBuilder < DefinitionBuilder
|
24
|
+
# Changes the lock manager to use with this process manager
|
25
|
+
#
|
26
|
+
# @see ProcessManager::LockManager
|
27
|
+
# @param [Symbol] lock_manager
|
28
|
+
# @return [undefined]
|
29
|
+
def use_lock_manager(lock_manager)
|
30
|
+
@lock_manager = lock_manager
|
31
|
+
end
|
32
|
+
|
33
|
+
# Changes the lock manager to a pessimistic lock manager
|
34
|
+
#
|
35
|
+
# @see ProcessManager::PessimisticLockManager
|
36
|
+
# @return [undefined]
|
37
|
+
def use_pessimistic_locking
|
38
|
+
@lock_manager_type = ProcessManager::PessimisticLockManager
|
39
|
+
end
|
40
|
+
|
41
|
+
# Changes the process factory to use with this process manager
|
42
|
+
#
|
43
|
+
# @see ProcessManager::ProcessFactory
|
44
|
+
# @param [Symbol] process_factory
|
45
|
+
# @return [undefined]
|
46
|
+
def use_process_factory(process_factory)
|
47
|
+
@process_factory = process_factory
|
48
|
+
end
|
49
|
+
|
50
|
+
# Changes the process repository to use with this process manager
|
51
|
+
#
|
52
|
+
# @see ProcessManager::ProcessRepository
|
53
|
+
# @param [Symbol] process_repository
|
54
|
+
# @return [undefined]
|
55
|
+
def use_process_repository(process_repository)
|
56
|
+
@process_repository = process_repository
|
57
|
+
end
|
58
|
+
|
59
|
+
# Changes the process types that are hosted by this process manager
|
60
|
+
#
|
61
|
+
# @see ProcessManager::Process
|
62
|
+
# @param [Class...] process_types
|
63
|
+
# @return [undefined]
|
64
|
+
def use_process_types(*process_types)
|
65
|
+
@process_types = process_types.flatten
|
66
|
+
end
|
67
|
+
|
68
|
+
protected
|
69
|
+
|
70
|
+
# @return [undefined]
|
71
|
+
def populate_defaults
|
72
|
+
identified_by :process_manager
|
73
|
+
|
74
|
+
tag :event_listener
|
75
|
+
|
76
|
+
use_pessimistic_locking
|
77
|
+
use_process_factory :process_factory
|
78
|
+
use_process_repository :process_repository
|
79
|
+
|
80
|
+
use_factory do
|
81
|
+
lock_manager = build_lock_manager
|
82
|
+
factory = resolve @process_factory
|
83
|
+
repository = resolve @process_repository
|
84
|
+
|
85
|
+
ProcessManager::MappingProcessManager.new repository, factory, lock_manager, @process_types
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# @raise [RuntimeError] If no lock manager was configured
|
90
|
+
# @return [LockManager]
|
91
|
+
def build_lock_manager
|
92
|
+
if @lock_manager
|
93
|
+
resolve @lock_manager
|
94
|
+
elsif @lock_manager_type
|
95
|
+
@lock_manager_type.new
|
96
|
+
else
|
97
|
+
raise 'No lock manager was configured for this process manager'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end # MappingProcessManagerDefinitionBuilder
|
101
|
+
end # Configuration
|
102
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'synapse/configuration/component/process_manager/container_resource_injector'
|
2
|
+
require 'synapse/configuration/component/process_manager/generic_process_factory'
|
3
|
+
require 'synapse/configuration/component/process_manager/mapping_process_manager'
|
4
|
+
|
5
|
+
module Synapse
|
6
|
+
module Configuration
|
7
|
+
class ContainerBuilder
|
8
|
+
# Creates and configures a resource injector that uses the service container
|
9
|
+
builder :container_resource_injector, ContainerResourceInjectorDefinitionBuilder
|
10
|
+
|
11
|
+
# Creates and configures a generic process factory
|
12
|
+
builder :process_factory, GenericProcessFactoryDefinitionBuilder
|
13
|
+
|
14
|
+
# Creates and configures a mapping process manager
|
15
|
+
builder :process_manager, MappingProcessManagerDefinitionBuilder
|
16
|
+
end # ContainerBuilder
|
17
|
+
end # Configuration
|
18
|
+
end
|
@@ -9,6 +9,7 @@ module Synapse
|
|
9
9
|
class LockingRepositoryDefinitionBuilder < DefinitionBuilder
|
10
10
|
# Changes the event bus used to publish aggregate events to
|
11
11
|
#
|
12
|
+
# @see EventBus::EventBus
|
12
13
|
# @param [Symbol] event_bus
|
13
14
|
# @return [undefined]
|
14
15
|
def use_event_bus(event_bus)
|
@@ -16,18 +17,24 @@ module Synapse
|
|
16
17
|
end
|
17
18
|
|
18
19
|
# Uses the lock manager with no locking
|
20
|
+
#
|
21
|
+
# @see Repository::NullLockManager
|
19
22
|
# @return [undefined]
|
20
23
|
def use_no_locking
|
21
24
|
@lock_manager_type = Repository::NullLockManager
|
22
25
|
end
|
23
26
|
|
24
27
|
# Uses the lock manager with pessimistic locking
|
28
|
+
#
|
29
|
+
# @see Repository::PessimisticLockManager
|
25
30
|
# @return [undefined]
|
26
31
|
def use_pessimistic_locking
|
27
32
|
@lock_manager_type = Repository::PessimisticLockManager
|
28
33
|
end
|
29
34
|
|
30
35
|
# Uses the lock manager with optimistic locking
|
36
|
+
#
|
37
|
+
# @see Repository::OptimisticLockManager
|
31
38
|
# @return [undefined]
|
32
39
|
def use_optimistic_locking
|
33
40
|
@lock_manager_type = Repository::OptimisticLockManager
|
@@ -35,6 +42,7 @@ module Synapse
|
|
35
42
|
|
36
43
|
# Changes the lock manager used to prevent concurrent aggregate modification
|
37
44
|
#
|
45
|
+
# @see Repository::LockManager
|
38
46
|
# @param [Symbol] lock_manager
|
39
47
|
# @return [undefined]
|
40
48
|
def use_lock_manager(lock_manager)
|
@@ -43,6 +51,7 @@ module Synapse
|
|
43
51
|
|
44
52
|
# Changes the provider used to get the current unit of work
|
45
53
|
#
|
54
|
+
# @see UnitOfWork::UnitOfWorkProvider
|
46
55
|
# @param [Symbol] unit_provider
|
47
56
|
# @return [undefined]
|
48
57
|
def use_unit_provider(unit_provider)
|
@@ -58,7 +67,7 @@ module Synapse
|
|
58
67
|
use_unit_provider :unit_provider
|
59
68
|
end
|
60
69
|
|
61
|
-
# @raise [RuntimeError] If no
|
70
|
+
# @raise [RuntimeError] If no lock manager was configured
|
62
71
|
# @return [LockManager]
|
63
72
|
def build_lock_manager
|
64
73
|
if @lock_manager
|
@@ -21,6 +21,7 @@ module Synapse
|
|
21
21
|
class ConverterFactoryDefinitionBuilder < DefinitionBuilder
|
22
22
|
# Changes the tag to use to automatically register converters
|
23
23
|
#
|
24
|
+
# @see Serialization::Converter
|
24
25
|
# @param [Symbol] converter_tag
|
25
26
|
# @return [undefined]
|
26
27
|
def use_converter_tag(converter_tag)
|
@@ -37,7 +38,7 @@ module Synapse
|
|
37
38
|
|
38
39
|
use_factory do
|
39
40
|
converter_factory = Serialization::ConverterFactory.new
|
40
|
-
|
41
|
+
|
41
42
|
with_tagged @converter_tag do |converter|
|
42
43
|
converter_factory.register converter
|
43
44
|
end
|
@@ -12,24 +12,32 @@ module Synapse
|
|
12
12
|
# end
|
13
13
|
class SerializerDefinitionBuilder < DefinitionBuilder
|
14
14
|
# Selects a serializer that uses attributes (ActiveModel, Virtus, etc.)
|
15
|
+
#
|
16
|
+
# @see Serialization::AttributeSerializer
|
15
17
|
# @return [undefined]
|
16
18
|
def use_attribute
|
17
19
|
@serializer_type = Serialization::AttributeSerializer
|
18
20
|
end
|
19
21
|
|
20
22
|
# Selects a serializer that uses the Ruby marshaling library
|
23
|
+
#
|
24
|
+
# @see Serialization::MarshalSerializer
|
21
25
|
# @return [undefined]
|
22
26
|
def use_marshal
|
23
27
|
@serializer_type = Serialization::MarshalSerializer
|
24
28
|
end
|
25
29
|
|
26
30
|
# Selects a serializer that uses the Optimized JSON (Oj) serialization library
|
31
|
+
#
|
32
|
+
# @see Serialization::OjSerializer
|
27
33
|
# @return [undefined]
|
28
34
|
def use_oj
|
29
35
|
@serializer_type = Serialization::OjSerializer
|
30
36
|
end
|
31
37
|
|
32
38
|
# Selects a serializer that uses the Optimized XML (Ox) serialization library
|
39
|
+
#
|
40
|
+
# @see Serialization::OxSerializer
|
33
41
|
# @return [undefined]
|
34
42
|
def use_ox
|
35
43
|
@serializer_type = Serialization::OxSerializer
|
@@ -37,6 +45,7 @@ module Synapse
|
|
37
45
|
|
38
46
|
# Changes the converter factory
|
39
47
|
#
|
48
|
+
# @see Serialization::ConverterFactory
|
40
49
|
# @param [Symbol] converter_factory
|
41
50
|
# @return [undefined]
|
42
51
|
def use_converter_factory(converter_factory)
|
@@ -87,4 +96,4 @@ module Synapse
|
|
87
96
|
end
|
88
97
|
end # SerializerDefinitionBuilder
|
89
98
|
end # Configuration
|
90
|
-
end
|
99
|
+
end
|
@@ -13,6 +13,7 @@ module Synapse
|
|
13
13
|
class UnitOfWorkFactoryDefinitionBuilder < DefinitionBuilder
|
14
14
|
# Changes the transaction manager to use when creating units of work
|
15
15
|
#
|
16
|
+
# @see UnitOfWork::TransactionManager
|
16
17
|
# @param [Symbol] tx_manager
|
17
18
|
# @return [undefined]
|
18
19
|
def use_transaction_manager(tx_manager)
|
@@ -21,6 +22,7 @@ module Synapse
|
|
21
22
|
|
22
23
|
# Changes the unit of work provider to use when creating units of work
|
23
24
|
#
|
25
|
+
# @see UnitOfWork::UnitOfWorkProvider
|
24
26
|
# @param [Symbol] unit_provider
|
25
27
|
# @return [undefined]
|
26
28
|
def use_unit_provider(unit_provider)
|
@@ -42,7 +44,7 @@ module Synapse
|
|
42
44
|
|
43
45
|
unit_factory = UnitOfWork::UnitOfWorkFactory.new unit_provider
|
44
46
|
unit_factory.transaction_manager = tx_manager
|
45
|
-
|
47
|
+
|
46
48
|
unit_factory
|
47
49
|
end
|
48
50
|
end
|
@@ -21,6 +21,7 @@ module Synapse
|
|
21
21
|
class UpcasterChainDefinitionBuilder < DefinitionBuilder
|
22
22
|
# Changes the converter factory
|
23
23
|
#
|
24
|
+
# @see Serialization::ConverterFactory
|
24
25
|
# @param [Symbol] converter_factory
|
25
26
|
# @return [undefined]
|
26
27
|
def use_converter_factory(converter_factory)
|
@@ -29,6 +30,7 @@ module Synapse
|
|
29
30
|
|
30
31
|
# Changes the tag to use to automatically register upcasters
|
31
32
|
#
|
33
|
+
# @see Upcasting::Upcaster
|
32
34
|
# @param [Symbol] upcaster_tag
|
33
35
|
# @return [undefined]
|
34
36
|
def use_upcaster_tag(upcaster_tag)
|
@@ -48,7 +50,7 @@ module Synapse
|
|
48
50
|
converter_factory = resolve @converter_factory
|
49
51
|
|
50
52
|
upcaster_chain = Upcasting::UpcasterChain.new converter_factory
|
51
|
-
|
53
|
+
|
52
54
|
with_tagged @upcaster_tag do |upcaster|
|
53
55
|
upcaster_chain.push upcaster
|
54
56
|
end
|
@@ -17,6 +17,9 @@ module Synapse
|
|
17
17
|
|
18
18
|
dependencies = object.class.dependencies
|
19
19
|
dependencies.each_pair do |id, attribute|
|
20
|
+
# Don't replace existing attributes
|
21
|
+
next if object.public_send attribute
|
22
|
+
|
20
23
|
resolved = resolve id
|
21
24
|
object.public_send "#{attribute}=", resolved
|
22
25
|
end
|
@@ -75,6 +78,18 @@ module Synapse
|
|
75
78
|
def registered?(id)
|
76
79
|
@definitions.has_key? id
|
77
80
|
end
|
78
|
-
|
79
|
-
|
81
|
+
|
82
|
+
# @return [String]
|
83
|
+
def inspect
|
84
|
+
result = "#<#{self.class}\n"
|
85
|
+
@definitions.keys.sort.each do |key|
|
86
|
+
definition = @definitions[key]
|
87
|
+
result << "\t#{key} => #{definition.tags.inspect}\n"
|
88
|
+
end
|
89
|
+
result << ">"
|
90
|
+
|
91
|
+
result
|
92
|
+
end
|
93
|
+
end # Container
|
94
|
+
end # Configuration
|
80
95
|
end
|
@@ -44,6 +44,20 @@ module Synapse
|
|
44
44
|
identified_by SecureRandom.hex 8
|
45
45
|
end
|
46
46
|
|
47
|
+
# @api public
|
48
|
+
# @return [undefined]
|
49
|
+
def clear_tags
|
50
|
+
@tags = Set.new
|
51
|
+
end
|
52
|
+
|
53
|
+
# @api public
|
54
|
+
# @param [Symbol...] tags
|
55
|
+
# @return [undefined]
|
56
|
+
def replace_tags(*tags)
|
57
|
+
clear_tags
|
58
|
+
tag *tags
|
59
|
+
end
|
60
|
+
|
47
61
|
# @api public
|
48
62
|
# @param [Symbol...] tags
|
49
63
|
# @return [undefined]
|
@@ -10,6 +10,7 @@ require 'synapse/configuration/component/event_bus'
|
|
10
10
|
# Has to be loaded before event sourcing
|
11
11
|
require 'synapse/configuration/component/repository'
|
12
12
|
require 'synapse/configuration/component/event_sourcing'
|
13
|
+
require 'synapse/configuration/component/process_manager'
|
13
14
|
require 'synapse/configuration/component/serialization'
|
14
15
|
require 'synapse/configuration/component/uow'
|
15
16
|
require 'synapse/configuration/component/upcasting'
|
@@ -5,6 +5,15 @@ module Synapse
|
|
5
5
|
class ProcessManager
|
6
6
|
include EventBus::EventListener
|
7
7
|
|
8
|
+
# @return [LockManager]
|
9
|
+
attr_reader :lock_manager
|
10
|
+
|
11
|
+
# @return [ProcessFactory]
|
12
|
+
attr_reader :factory
|
13
|
+
|
14
|
+
# @return [ProcessRepository]
|
15
|
+
attr_reader :repository
|
16
|
+
|
8
17
|
# @return [Boolean] Returns true if exceptions will be logged silently
|
9
18
|
attr_accessor :suppress_exceptions
|
10
19
|
|
@@ -5,6 +5,8 @@ module Synapse
|
|
5
5
|
# Note that this serializer is not necessarily the fastest serializer available, nor is it
|
6
6
|
# flexible. Output is binary and difficult to modify, which means upcasting is not possible
|
7
7
|
# when using this serializer.
|
8
|
+
#
|
9
|
+
# This serializer wraps the binary output of Marshal in Base64 encoding.
|
8
10
|
class MarshalSerializer < Serializer
|
9
11
|
# This serializer doesn't provide any configuration options
|
10
12
|
|
@@ -13,14 +15,14 @@ module Synapse
|
|
13
15
|
# @param [Object] content
|
14
16
|
# @return [Object]
|
15
17
|
def perform_serialize(content)
|
16
|
-
Marshal.dump
|
18
|
+
Base64.encode64(Marshal.dump(content))
|
17
19
|
end
|
18
20
|
|
19
21
|
# @param [Object] content
|
20
22
|
# @param [Class] type
|
21
23
|
# @return [Object]
|
22
24
|
def perform_deserialize(content, type)
|
23
|
-
Marshal.load
|
25
|
+
Marshal.load(Base64.decode64(content))
|
24
26
|
end
|
25
27
|
|
26
28
|
# @return [Class]
|
data/lib/synapse/version.rb
CHANGED
data/lib/synapse.rb
CHANGED
@@ -18,7 +18,7 @@ module Synapse
|
|
18
18
|
|
19
19
|
class CorrelationDataProviderTest < Test::Unit::TestCase
|
20
20
|
should 'provide the identifier of a command for auditing' do
|
21
|
-
provider = CorrelationDataProvider.new
|
21
|
+
provider = CorrelationDataProvider.new :command_id
|
22
22
|
command = Command::CommandMessage.build
|
23
23
|
|
24
24
|
expected = { :command_id => command.id }
|
@@ -57,7 +57,7 @@ module Synapse
|
|
57
57
|
loggers = [logger]
|
58
58
|
event = Object.new
|
59
59
|
|
60
|
-
mock(logger).
|
60
|
+
mock(logger).on_failure(command, exception, [event])
|
61
61
|
|
62
62
|
listener = AuditingUnitOfWorkListener.new command, data_providers, loggers
|
63
63
|
listener.recorded_events.push event
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Synapse
|
4
|
+
module Configuration
|
5
|
+
class ContainerResourceInjectorDefinitionBuilderTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@container = Container.new
|
9
|
+
@builder = ContainerBuilder.new @container
|
10
|
+
end
|
11
|
+
|
12
|
+
should 'build a resource injector' do
|
13
|
+
@builder.container_resource_injector
|
14
|
+
|
15
|
+
resource_injector = @container.resolve :resource_injector
|
16
|
+
assert_instance_of ProcessManager::ContainerResourceInjector, resource_injector
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'process_manager/mapping/fixtures'
|
3
|
+
|
4
|
+
module Synapse
|
5
|
+
module Configuration
|
6
|
+
class MappingProcessManagerDefinitionBuilderTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@container = Container.new
|
10
|
+
@builder = ContainerBuilder.new @container
|
11
|
+
end
|
12
|
+
|
13
|
+
should 'build with sensible defaults' do
|
14
|
+
@builder.factory :process_repository do
|
15
|
+
ProcessManager::InMemoryProcessRepository.new
|
16
|
+
end
|
17
|
+
|
18
|
+
@builder.process_factory
|
19
|
+
@builder.process_manager do
|
20
|
+
use_process_types ProcessManager::OrderProcess
|
21
|
+
end
|
22
|
+
|
23
|
+
process_manager = @container.resolve :process_manager
|
24
|
+
|
25
|
+
assert_equal [process_manager], @container.resolve_tagged(:event_listener)
|
26
|
+
|
27
|
+
factory = @container.resolve :process_factory
|
28
|
+
repository = @container.resolve :process_repository
|
29
|
+
|
30
|
+
assert_same factory, process_manager.factory
|
31
|
+
assert_same repository, process_manager.repository
|
32
|
+
assert_instance_of ProcessManager::PessimisticLockManager, process_manager.lock_manager
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -33,6 +33,30 @@ module Synapse
|
|
33
33
|
container.inject_into object
|
34
34
|
end
|
35
35
|
|
36
|
+
should 'not overwrite existing attributes when injecting into a Dependent object' do
|
37
|
+
container = Container.new
|
38
|
+
|
39
|
+
service_a = Object.new
|
40
|
+
service_b = Object.new
|
41
|
+
|
42
|
+
DefinitionBuilder.build container, :service_a do
|
43
|
+
use_instance service_a
|
44
|
+
end
|
45
|
+
|
46
|
+
DefinitionBuilder.build container, :service_b do
|
47
|
+
use_instance service_b
|
48
|
+
end
|
49
|
+
|
50
|
+
other_service_a = Object.new
|
51
|
+
|
52
|
+
dependent = ExampleDependent.new
|
53
|
+
dependent.service_a = other_service_a
|
54
|
+
container.inject_into dependent
|
55
|
+
|
56
|
+
assert_same other_service_a, dependent.service_a
|
57
|
+
assert_same service_b, dependent.some_service
|
58
|
+
end
|
59
|
+
|
36
60
|
should 'resolve a service from a definition by its identifier' do
|
37
61
|
reference = Object.new
|
38
62
|
container = Container.new
|
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: synapse-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.3
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Ian Unruh
|
@@ -13,6 +14,7 @@ dependencies:
|
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: activesupport
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
19
|
- - ~>
|
18
20
|
- !ruby/object:Gem::Version
|
@@ -20,6 +22,7 @@ dependencies:
|
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
27
|
- - ~>
|
25
28
|
- !ruby/object:Gem::Version
|
@@ -27,6 +30,7 @@ dependencies:
|
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: atomic
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
35
|
- - ~>
|
32
36
|
- !ruby/object:Gem::Version
|
@@ -34,6 +38,7 @@ dependencies:
|
|
34
38
|
type: :runtime
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
43
|
- - ~>
|
39
44
|
- !ruby/object:Gem::Version
|
@@ -41,6 +46,7 @@ dependencies:
|
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
47
|
name: logging
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
44
50
|
requirements:
|
45
51
|
- - ~>
|
46
52
|
- !ruby/object:Gem::Version
|
@@ -48,6 +54,7 @@ dependencies:
|
|
48
54
|
type: :runtime
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
51
58
|
requirements:
|
52
59
|
- - ~>
|
53
60
|
- !ruby/object:Gem::Version
|
@@ -55,15 +62,17 @@ dependencies:
|
|
55
62
|
- !ruby/object:Gem::Dependency
|
56
63
|
name: thread
|
57
64
|
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
58
66
|
requirements:
|
59
|
-
- - '>='
|
67
|
+
- - ! '>='
|
60
68
|
- !ruby/object:Gem::Version
|
61
69
|
version: '0'
|
62
70
|
type: :runtime
|
63
71
|
prerelease: false
|
64
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
65
74
|
requirements:
|
66
|
-
- - '>='
|
75
|
+
- - ! '>='
|
67
76
|
- !ruby/object:Gem::Version
|
68
77
|
version: '0'
|
69
78
|
description: A versatile CQRS and event sourcing framework
|
@@ -143,6 +152,10 @@ files:
|
|
143
152
|
- lib/synapse/configuration/component/event_sourcing/repository.rb
|
144
153
|
- lib/synapse/configuration/component/event_sourcing/interval_snapshot_policy.rb
|
145
154
|
- lib/synapse/configuration/component/upcasting/upcaster_chain.rb
|
155
|
+
- lib/synapse/configuration/component/process_manager.rb
|
156
|
+
- lib/synapse/configuration/component/process_manager/mapping_process_manager.rb
|
157
|
+
- lib/synapse/configuration/component/process_manager/generic_process_factory.rb
|
158
|
+
- lib/synapse/configuration/component/process_manager/container_resource_injector.rb
|
146
159
|
- lib/synapse/configuration/component/upcasting.rb
|
147
160
|
- lib/synapse/configuration/component/serialization.rb
|
148
161
|
- lib/synapse/configuration/component/uow.rb
|
@@ -178,7 +191,9 @@ files:
|
|
178
191
|
- lib/synapse/event_store/errors.rb
|
179
192
|
- lib/synapse/event_store/in_memory.rb
|
180
193
|
- lib/synapse/configuration.rb
|
194
|
+
- lib/synapse/auditing/correlation_data_provider.rb
|
181
195
|
- lib/synapse/auditing/audit_logger.rb
|
196
|
+
- lib/synapse/auditing/command_metadata_provider.rb
|
182
197
|
- lib/synapse/auditing/data_provider.rb
|
183
198
|
- lib/synapse/auditing/dispatch_interceptor.rb
|
184
199
|
- lib/synapse/auditing/unit_listener.rb
|
@@ -275,6 +290,8 @@ files:
|
|
275
290
|
- test/configuration/component/repository/simple_repository_test.rb
|
276
291
|
- test/configuration/component/event_sourcing/repository_test.rb
|
277
292
|
- test/configuration/component/upcasting/upcaster_chain_test.rb
|
293
|
+
- test/configuration/component/process_manager/container_resource_injector_test.rb
|
294
|
+
- test/configuration/component/process_manager/mapping_process_manager_test.rb
|
278
295
|
- test/configuration/component/event_bus/simple_event_bus_test.rb
|
279
296
|
- test/configuration/component/serialization/serializer_test.rb
|
280
297
|
- test/configuration/component/serialization/converter_factory_test.rb
|
@@ -324,26 +341,32 @@ files:
|
|
324
341
|
homepage: https://github.com/ianunruh/synapse
|
325
342
|
licenses:
|
326
343
|
- Apache 2.0
|
327
|
-
metadata: {}
|
328
344
|
post_install_message:
|
329
345
|
rdoc_options: []
|
330
346
|
require_paths:
|
331
347
|
- lib
|
332
348
|
required_ruby_version: !ruby/object:Gem::Requirement
|
349
|
+
none: false
|
333
350
|
requirements:
|
334
|
-
- - '>='
|
351
|
+
- - ! '>='
|
335
352
|
- !ruby/object:Gem::Version
|
336
353
|
version: '0'
|
354
|
+
segments:
|
355
|
+
- 0
|
356
|
+
hash: -4187832660438552395
|
337
357
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
358
|
+
none: false
|
338
359
|
requirements:
|
339
|
-
- - '>='
|
360
|
+
- - ! '>='
|
340
361
|
- !ruby/object:Gem::Version
|
341
362
|
version: '0'
|
363
|
+
segments:
|
364
|
+
- 0
|
365
|
+
hash: -4187832660438552395
|
342
366
|
requirements: []
|
343
367
|
rubyforge_project:
|
344
|
-
rubygems_version:
|
368
|
+
rubygems_version: 1.8.25
|
345
369
|
signing_key:
|
346
|
-
specification_version:
|
370
|
+
specification_version: 3
|
347
371
|
summary: A versatile CQRS and event sourcing framework
|
348
372
|
test_files: []
|
349
|
-
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: baa532559d58992e62cae2cc5b843a9485bd10af
|
4
|
-
data.tar.gz: 5d63dd14c2598d92034db8fb45d7e37958a45f98
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 5264e9b6b99b0da204d4c0dc9d28f4b1624c1ac28e6ae9e47b5f89d441a4b2a41fe2a4fcde4e25801d7f2aa676b615728881fb4656132f7ed2d5e9f42edcc7e7
|
7
|
-
data.tar.gz: fe5bc48121cacff34fb1ef50a43159902de2d5bf93b34ee5504e440e5a0dd76ea5caa66b5a441d55f154259a271feea30cbe523d8d180f67f7983d1889cdff18
|