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.
Files changed (36) hide show
  1. data/lib/synapse/auditing/command_metadata_provider.rb +12 -0
  2. data/lib/synapse/auditing/correlation_data_provider.rb +19 -0
  3. data/lib/synapse/auditing/data_provider.rb +2 -30
  4. data/lib/synapse/auditing/dispatch_interceptor.rb +6 -5
  5. data/lib/synapse/auditing/unit_listener.rb +7 -6
  6. data/lib/synapse/auditing.rb +2 -0
  7. data/lib/synapse/configuration/component/command_bus/gateway.rb +1 -0
  8. data/lib/synapse/configuration/component/command_bus/simple_command_bus.rb +9 -1
  9. data/lib/synapse/configuration/component/event_bus/simple_event_bus.rb +1 -0
  10. data/lib/synapse/configuration/component/event_sourcing/aggregate_snapshot_taker.rb +7 -0
  11. data/lib/synapse/configuration/component/event_sourcing/interval_snapshot_policy.rb +1 -1
  12. data/lib/synapse/configuration/component/event_sourcing/repository.rb +8 -0
  13. data/lib/synapse/configuration/component/process_manager/container_resource_injector.rb +22 -0
  14. data/lib/synapse/configuration/component/process_manager/generic_process_factory.rb +43 -0
  15. data/lib/synapse/configuration/component/process_manager/mapping_process_manager.rb +102 -0
  16. data/lib/synapse/configuration/component/process_manager.rb +18 -0
  17. data/lib/synapse/configuration/component/repository/locking_repository.rb +10 -1
  18. data/lib/synapse/configuration/component/repository/simple_repository.rb +1 -0
  19. data/lib/synapse/configuration/component/serialization/converter_factory.rb +2 -1
  20. data/lib/synapse/configuration/component/serialization/serializer.rb +10 -1
  21. data/lib/synapse/configuration/component/uow/unit_factory.rb +3 -1
  22. data/lib/synapse/configuration/component/upcasting/upcaster_chain.rb +3 -1
  23. data/lib/synapse/configuration/container.rb +17 -2
  24. data/lib/synapse/configuration/definition_builder.rb +14 -0
  25. data/lib/synapse/configuration.rb +1 -0
  26. data/lib/synapse/process_manager/process_manager.rb +9 -0
  27. data/lib/synapse/serialization/serializer/marshal.rb +4 -2
  28. data/lib/synapse/version.rb +1 -1
  29. data/lib/synapse.rb +1 -0
  30. data/test/auditing/data_provider_test.rb +1 -1
  31. data/test/auditing/unit_listener_test.rb +1 -1
  32. data/test/configuration/component/process_manager/container_resource_injector_test.rb +21 -0
  33. data/test/configuration/component/process_manager/mapping_process_manager_test.rb +37 -0
  34. data/test/configuration/container_test.rb +24 -0
  35. metadata +32 -9
  36. 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(command).tap do |result|
24
- audit_listener.return_value = result
25
- end
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(audit_data).tap do |e|
31
- @recorded_events.push e
32
- end
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.on_success @command, cause, @recorded_events
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
@@ -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
- command_bus.rollback_policy = resolve @rollback_policy, true
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)
@@ -25,7 +25,7 @@ module Synapse
25
25
  use_threshold 30
26
26
 
27
27
  use_factory do
28
- EventSourcing::AggregateSnapshotTaker.new @threshold
28
+ EventSourcing::IntervalSnapshotPolicy.new @threshold
29
29
  end
30
30
  end
31
31
  end # IntervalSnapshotPolicyDefinitionBuilder
@@ -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 locking manager was configured
70
+ # @raise [RuntimeError] If no lock manager was configured
62
71
  # @return [LockManager]
63
72
  def build_lock_manager
64
73
  if @lock_manager
@@ -7,6 +7,7 @@ module Synapse
7
7
  # use_aggregate_type User
8
8
  # end
9
9
  class SimpleRepositoryDefinitionBuilder < LockingRepositoryDefinitionBuilder
10
+ # @see Domain::AggregateRoot
10
11
  # @param [Class] aggregate_type
11
12
  # @return [undefined]
12
13
  def use_aggregate_type(aggregate_type)
@@ -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
- end
79
- end
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 content
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 content
25
+ Marshal.load(Base64.decode64(content))
24
26
  end
25
27
 
26
28
  # @return [Class]
@@ -1,3 +1,3 @@
1
1
  module Synapse
2
- VERSION = '0.5.2'
2
+ VERSION = '0.5.3'
3
3
  end
data/lib/synapse.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'active_support'
2
2
  require 'active_support/core_ext'
3
+ require 'forwardable'
3
4
  require 'logging'
4
5
  require 'set'
5
6
 
@@ -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).on_success(command, exception, [event])
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.2
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: 2.0.3
368
+ rubygems_version: 1.8.25
345
369
  signing_key:
346
- specification_version: 4
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