synapse-core 0.1.2
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.rb +351 -0
- data/lib/synapse/command/command_bus.rb +45 -0
- data/lib/synapse/command/command_callback.rb +18 -0
- data/lib/synapse/command/command_filter.rb +17 -0
- data/lib/synapse/command/command_handler.rb +13 -0
- data/lib/synapse/command/dispatch_interceptor.rb +16 -0
- data/lib/synapse/command/duplication.rb +43 -0
- data/lib/synapse/command/errors.rb +27 -0
- data/lib/synapse/command/filters/validation.rb +32 -0
- data/lib/synapse/command/gateway.rb +34 -0
- data/lib/synapse/command/interceptor_chain.rb +31 -0
- data/lib/synapse/command/interceptors/serialization.rb +35 -0
- data/lib/synapse/command/message.rb +19 -0
- data/lib/synapse/command/rollback_policy.rb +22 -0
- data/lib/synapse/command/simple_command_bus.rb +138 -0
- data/lib/synapse/command/wiring.rb +47 -0
- data/lib/synapse/domain/aggregate_root.rb +121 -0
- data/lib/synapse/domain/event_container.rb +127 -0
- data/lib/synapse/domain/message.rb +82 -0
- data/lib/synapse/domain/message_builder.rb +34 -0
- data/lib/synapse/domain/stream.rb +108 -0
- data/lib/synapse/duplication.rb +60 -0
- data/lib/synapse/errors.rb +13 -0
- data/lib/synapse/event_bus/event_bus.rb +40 -0
- data/lib/synapse/event_bus/event_listener.rb +16 -0
- data/lib/synapse/event_bus/event_listener_proxy.rb +12 -0
- data/lib/synapse/event_bus/simple_event_bus.rb +69 -0
- data/lib/synapse/event_bus/wiring.rb +23 -0
- data/lib/synapse/event_sourcing/aggregate_factory.rb +69 -0
- data/lib/synapse/event_sourcing/aggregate_root.rb +104 -0
- data/lib/synapse/event_sourcing/conflict_resolver.rb +80 -0
- data/lib/synapse/event_sourcing/entity.rb +64 -0
- data/lib/synapse/event_sourcing/member.rb +72 -0
- data/lib/synapse/event_sourcing/repository.rb +119 -0
- data/lib/synapse/event_sourcing/snapshot/count_stream.rb +86 -0
- data/lib/synapse/event_sourcing/snapshot/count_trigger.rb +91 -0
- data/lib/synapse/event_sourcing/snapshot/taker.rb +73 -0
- data/lib/synapse/event_sourcing/storage_listener.rb +34 -0
- data/lib/synapse/event_sourcing/stream_decorator.rb +25 -0
- data/lib/synapse/event_store/errors.rb +16 -0
- data/lib/synapse/event_store/event_store.rb +43 -0
- data/lib/synapse/event_store/in_memory.rb +59 -0
- data/lib/synapse/event_store/mongo/cursor_event_stream.rb +63 -0
- data/lib/synapse/event_store/mongo/event_store.rb +86 -0
- data/lib/synapse/event_store/mongo/per_commit_strategy.rb +253 -0
- data/lib/synapse/event_store/mongo/per_event_strategy.rb +143 -0
- data/lib/synapse/event_store/mongo/storage_strategy.rb +113 -0
- data/lib/synapse/event_store/mongo/template.rb +73 -0
- data/lib/synapse/identifier.rb +23 -0
- data/lib/synapse/message.rb +101 -0
- data/lib/synapse/message_builder.rb +38 -0
- data/lib/synapse/process_manager/correlation.rb +32 -0
- data/lib/synapse/process_manager/correlation_resolver.rb +14 -0
- data/lib/synapse/process_manager/correlation_set.rb +58 -0
- data/lib/synapse/process_manager/process.rb +71 -0
- data/lib/synapse/repository/errors.rb +26 -0
- data/lib/synapse/repository/lock_manager.rb +40 -0
- data/lib/synapse/repository/locking.rb +97 -0
- data/lib/synapse/repository/pessimistic_lock_manager.rb +61 -0
- data/lib/synapse/repository/repository.rb +109 -0
- data/lib/synapse/serialization/converter.rb +39 -0
- data/lib/synapse/serialization/converter/chain.rb +45 -0
- data/lib/synapse/serialization/converter/factory.rb +68 -0
- data/lib/synapse/serialization/converter/identity.rb +29 -0
- data/lib/synapse/serialization/converter/json.rb +31 -0
- data/lib/synapse/serialization/converter/ox.rb +31 -0
- data/lib/synapse/serialization/errors.rb +12 -0
- data/lib/synapse/serialization/lazy_object.rb +61 -0
- data/lib/synapse/serialization/message/data.rb +25 -0
- data/lib/synapse/serialization/message/metadata.rb +13 -0
- data/lib/synapse/serialization/message/serialization_aware.rb +17 -0
- data/lib/synapse/serialization/message/serialization_aware_message.rb +66 -0
- data/lib/synapse/serialization/message/serialized_message.rb +201 -0
- data/lib/synapse/serialization/message/serialized_message_builder.rb +64 -0
- data/lib/synapse/serialization/message/serialized_object_cache.rb +50 -0
- data/lib/synapse/serialization/message/serializer.rb +47 -0
- data/lib/synapse/serialization/revision_resolver.rb +30 -0
- data/lib/synapse/serialization/serialized_object.rb +37 -0
- data/lib/synapse/serialization/serialized_type.rb +31 -0
- data/lib/synapse/serialization/serializer.rb +98 -0
- data/lib/synapse/serialization/serializer/marshal.rb +32 -0
- data/lib/synapse/serialization/serializer/oj.rb +34 -0
- data/lib/synapse/serialization/serializer/ox.rb +31 -0
- data/lib/synapse/uow/factory.rb +28 -0
- data/lib/synapse/uow/listener.rb +79 -0
- data/lib/synapse/uow/listener_collection.rb +93 -0
- data/lib/synapse/uow/nesting.rb +262 -0
- data/lib/synapse/uow/provider.rb +71 -0
- data/lib/synapse/uow/storage_listener.rb +14 -0
- data/lib/synapse/uow/transaction_manager.rb +27 -0
- data/lib/synapse/uow/uow.rb +178 -0
- data/lib/synapse/upcasting/chain.rb +78 -0
- data/lib/synapse/upcasting/context.rb +58 -0
- data/lib/synapse/upcasting/data.rb +30 -0
- data/lib/synapse/upcasting/single_upcaster.rb +57 -0
- data/lib/synapse/upcasting/upcaster.rb +55 -0
- data/lib/synapse/version.rb +3 -0
- data/lib/synapse/wiring/message_wiring.rb +41 -0
- data/lib/synapse/wiring/wire.rb +55 -0
- data/lib/synapse/wiring/wire_registry.rb +61 -0
- data/test/command/duplication_test.rb +54 -0
- data/test/command/gateway_test.rb +25 -0
- data/test/command/interceptor_chain_test.rb +26 -0
- data/test/command/serialization_test.rb +37 -0
- data/test/command/simple_command_bus_test.rb +141 -0
- data/test/command/validation_test.rb +42 -0
- data/test/command/wiring_test.rb +73 -0
- data/test/domain/aggregate_root_test.rb +57 -0
- data/test/domain/fixtures.rb +31 -0
- data/test/domain/message_test.rb +61 -0
- data/test/domain/stream_test.rb +35 -0
- data/test/duplication_test.rb +40 -0
- data/test/event_bus/wiring_test.rb +46 -0
- data/test/event_sourcing/aggregate_factory_test.rb +28 -0
- data/test/event_sourcing/aggregate_root_test.rb +76 -0
- data/test/event_sourcing/entity_test.rb +34 -0
- data/test/event_sourcing/fixtures.rb +85 -0
- data/test/event_sourcing/repository_test.rb +102 -0
- data/test/event_sourcing/snapshot/aggregate_taker_test.rb +39 -0
- data/test/event_sourcing/snapshot/deferred_taker_test.rb +19 -0
- data/test/event_sourcing/snapshot/integration_test.rb +65 -0
- data/test/event_sourcing/storage_listener_test.rb +77 -0
- data/test/event_store/in_memory_test.rb +47 -0
- data/test/process_manager/correlation_set_test.rb +49 -0
- data/test/process_manager/correlation_test.rb +24 -0
- data/test/process_manager/process_test.rb +52 -0
- data/test/repository/locking_test.rb +101 -0
- data/test/serialization/converter/factory_test.rb +33 -0
- data/test/serialization/converter/identity_test.rb +17 -0
- data/test/serialization/converter/json_test.rb +31 -0
- data/test/serialization/converter/ox_test.rb +40 -0
- data/test/serialization/fixtures.rb +17 -0
- data/test/serialization/lazy_object_test.rb +32 -0
- data/test/serialization/message/metadata_test.rb +19 -0
- data/test/serialization/message/serialization_aware_message_test.rb +88 -0
- data/test/serialization/message/serialized_message_builder_test.rb +41 -0
- data/test/serialization/message/serialized_message_test.rb +140 -0
- data/test/serialization/message/serializer_test.rb +50 -0
- data/test/serialization/revision_resolver_test.rb +12 -0
- data/test/serialization/serialized_object_test.rb +36 -0
- data/test/serialization/serialized_type_test.rb +27 -0
- data/test/serialization/serializer/marshal_test.rb +22 -0
- data/test/serialization/serializer/oj_test.rb +24 -0
- data/test/serialization/serializer/ox_test.rb +36 -0
- data/test/serialization/serializer_test.rb +20 -0
- data/test/test_helper.rb +19 -0
- data/test/uow/factory_test.rb +23 -0
- data/test/uow/outer_commit_listener_test.rb +50 -0
- data/test/uow/provider_test.rb +70 -0
- data/test/uow/uow_test.rb +337 -0
- data/test/upcasting/chain_test.rb +29 -0
- data/test/upcasting/fixtures.rb +66 -0
- data/test/wiring/wire_registry_test.rb +60 -0
- data/test/wiring/wire_test.rb +51 -0
- metadata +263 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Repository
|
|
3
|
+
# Represents a mechanism for loading and storing aggregates
|
|
4
|
+
# @abstract
|
|
5
|
+
class Repository
|
|
6
|
+
# @return [EventBus]
|
|
7
|
+
attr_accessor :event_bus
|
|
8
|
+
|
|
9
|
+
# @return [UnitOfWorkProvider]
|
|
10
|
+
attr_accessor :unit_provider
|
|
11
|
+
|
|
12
|
+
# Loads an aggregate with the given aggregate identifier
|
|
13
|
+
#
|
|
14
|
+
# If an expected version is specified and the aggregate's actual version doesn't equal the
|
|
15
|
+
# expected version, the implementation can choose to do one of the following:
|
|
16
|
+
#
|
|
17
|
+
# - Raise an exception immediately
|
|
18
|
+
# - Raise an exception at any other time while the aggregate is registered with the current
|
|
19
|
+
# unit of work.
|
|
20
|
+
#
|
|
21
|
+
# @abstract
|
|
22
|
+
# @raise [AggregateNotFoundError]
|
|
23
|
+
# If the aggregate with the given identifier could not be found
|
|
24
|
+
# @raise [ConflictingModificationError]
|
|
25
|
+
# If the expected version doesn't match the aggregate's actual version
|
|
26
|
+
# @param [Object] aggregate_id
|
|
27
|
+
# @param [Integer] expected_version If this is nil, no version validation is performed
|
|
28
|
+
# @return [AggregateRoot]
|
|
29
|
+
def load(aggregate_id, expected_version = nil); end
|
|
30
|
+
|
|
31
|
+
# Adds a new, unmanaged aggregate to the repository
|
|
32
|
+
#
|
|
33
|
+
# This method will not force the repository to save the aggregate immediately. Instead, it is
|
|
34
|
+
# registered with the current unit of work. To force storage of an aggregate, commit the
|
|
35
|
+
# current unit of work.
|
|
36
|
+
#
|
|
37
|
+
# @abstract
|
|
38
|
+
# @raise [ArgumentError] If the version of the aggregate is not null
|
|
39
|
+
# @param [AggregateRoot] aggregate
|
|
40
|
+
# @return [undefined]
|
|
41
|
+
def add(aggregate); end
|
|
42
|
+
|
|
43
|
+
protected
|
|
44
|
+
|
|
45
|
+
# Returns the type of aggregate that this repository handles
|
|
46
|
+
#
|
|
47
|
+
# @abstract
|
|
48
|
+
# @return [Class]
|
|
49
|
+
def aggregate_type; end
|
|
50
|
+
|
|
51
|
+
# Returns the listener that handles aggregate storage
|
|
52
|
+
#
|
|
53
|
+
# @abstract
|
|
54
|
+
# @return [StorageListener]
|
|
55
|
+
def storage_listener; end
|
|
56
|
+
|
|
57
|
+
# Asserts that an aggregate being added is compatible with this repository and is newly
|
|
58
|
+
# created
|
|
59
|
+
#
|
|
60
|
+
# @raise [ArgumentError] If aggregate is not of the correct type
|
|
61
|
+
# @raise [ArgumentError] If aggregate has a version number
|
|
62
|
+
# @param [AggregateRoot] aggregate
|
|
63
|
+
# @return [undefined]
|
|
64
|
+
def assert_compatible(aggregate)
|
|
65
|
+
unless aggregate.is_a? aggregate_type
|
|
66
|
+
raise ArgumentError, 'Incompatible aggregate type'
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
if aggregate.version
|
|
70
|
+
raise ArgumentError, 'Only newly created aggregates may be added'
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Asserts that a loaded aggregate has the expected version
|
|
75
|
+
#
|
|
76
|
+
# @raise [ConflictingAggregateVersionError]
|
|
77
|
+
# If aggregate version is later than the expected version
|
|
78
|
+
# @param [AggregateRoot] aggregate
|
|
79
|
+
# @param [Integer] expected_version
|
|
80
|
+
# @return [undefined]
|
|
81
|
+
def assert_version_expected(aggregate, expected_version)
|
|
82
|
+
if expected_version and aggregate.version and aggregate.version > expected_version
|
|
83
|
+
raise ConflictingAggregateVersionError.new aggregate, expected_version
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Registers the given aggregate with the current unit of work
|
|
88
|
+
#
|
|
89
|
+
# @param [AggregateRoot] aggregate
|
|
90
|
+
# @return [undefined]
|
|
91
|
+
def register_aggregate(aggregate)
|
|
92
|
+
current_unit.register_aggregate aggregate, @event_bus, storage_listener
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Registers the given unit of work listener with the current unit of work
|
|
96
|
+
#
|
|
97
|
+
# @param [UnitOfWorkListener] listener
|
|
98
|
+
# @return [undefined]
|
|
99
|
+
def register_listener(listener)
|
|
100
|
+
current_unit.register_listener listener
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# @return [UnitOfWork]
|
|
104
|
+
def current_unit
|
|
105
|
+
@unit_provider.current
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Serialization
|
|
3
|
+
# Represents a mechanism for converting content of one type to another type for the purposes
|
|
4
|
+
# of serialization, deserialization and upcasting.
|
|
5
|
+
module Converter
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
class_attribute :source_type
|
|
10
|
+
class_attribute :target_type
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module ClassMethods
|
|
14
|
+
# @param [Class] source_type
|
|
15
|
+
# @param [Class] target_type
|
|
16
|
+
# @return [undefined]
|
|
17
|
+
def converts(source_type, target_type)
|
|
18
|
+
self.source_type = source_type
|
|
19
|
+
self.target_type = target_type
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def initialize(options = {})
|
|
24
|
+
@options = options
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @param [SerializedObject] original
|
|
28
|
+
# @return [SerializedObject]
|
|
29
|
+
def convert(original)
|
|
30
|
+
SerializedObject.new(convert_content(original.content), target_type, original.type)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @abstract
|
|
34
|
+
# @param [Object] original
|
|
35
|
+
# @return [Object]
|
|
36
|
+
def convert_content(original); end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Serialization
|
|
3
|
+
# Converter implementation that chains together two or more converters
|
|
4
|
+
class ConverterChain
|
|
5
|
+
include Converter
|
|
6
|
+
|
|
7
|
+
# @return [Array<Converter>]
|
|
8
|
+
attr_reader :delegates
|
|
9
|
+
|
|
10
|
+
# @return [Class]
|
|
11
|
+
attr_reader :source_type
|
|
12
|
+
|
|
13
|
+
# @return [Class]
|
|
14
|
+
attr_reader :target_type
|
|
15
|
+
|
|
16
|
+
# @param [Array<Converter>] delegates
|
|
17
|
+
# @return [undefined]
|
|
18
|
+
def initialize(delegates)
|
|
19
|
+
@delegates = delegates
|
|
20
|
+
@source_type = delegates.first.source_type
|
|
21
|
+
@target_type = delegates.last.target_type
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @param [SerializedObject] original
|
|
25
|
+
# @return [SerializedObject]
|
|
26
|
+
def convert(original)
|
|
27
|
+
intermediate = original
|
|
28
|
+
@delegates.each do |delegate|
|
|
29
|
+
intermediate = delegate.convert intermediate
|
|
30
|
+
end
|
|
31
|
+
intermediate
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @param [Object] original
|
|
35
|
+
# @return [Object]
|
|
36
|
+
def convert_content(original)
|
|
37
|
+
intermediate = original
|
|
38
|
+
@delegates.each do |delegate|
|
|
39
|
+
intermediate = delegate.convert_content intermediate
|
|
40
|
+
end
|
|
41
|
+
intermediate
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Serialization
|
|
3
|
+
# Represents a mechanism for storing and retrieving converters capable of converting content
|
|
4
|
+
# of one type to another type, for the purpose of serialization and upcasting.
|
|
5
|
+
class ConverterFactory
|
|
6
|
+
attr_reader :converters
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
@converters = Array.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Adds the given converter to this converter factory
|
|
13
|
+
#
|
|
14
|
+
# @param [Converter] converter
|
|
15
|
+
# @return [undefined]
|
|
16
|
+
def register(converter)
|
|
17
|
+
@converters.push converter
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Convenience method for converting a given serialized object to the given target type
|
|
21
|
+
#
|
|
22
|
+
# @param [SerializedObject] serialized_object
|
|
23
|
+
# @param [Class] target_type
|
|
24
|
+
# @return [SerializedObject]
|
|
25
|
+
def convert(serialized_object, target_type)
|
|
26
|
+
converter = converter serialized_object.content_type, target_type
|
|
27
|
+
converter.convert serialized_object
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Returns a converter that is capable of converting content of the given source type to
|
|
31
|
+
# the given target type, if one exists.
|
|
32
|
+
#
|
|
33
|
+
# @raise [ConversionError] If no converter is capable of performing the conversion
|
|
34
|
+
# @param [Class] source_type
|
|
35
|
+
# @param [Class] target_type
|
|
36
|
+
# @return [Converter]
|
|
37
|
+
def converter(source_type, target_type)
|
|
38
|
+
if source_type == target_type
|
|
39
|
+
return IdentityConverter.new source_type
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
@converters.each do |converter|
|
|
43
|
+
if converter.source_type == source_type && converter.target_type == target_type
|
|
44
|
+
return converter
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
raise ConversionError, 'No converter capable of [%s] -> [%s]' % [source_type, target_type]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Returns true if this factory contains a converter capable of converting content from the
|
|
52
|
+
# given source type to the given target type.
|
|
53
|
+
#
|
|
54
|
+
# @param [Class] source_type
|
|
55
|
+
# @param [Class] target_type
|
|
56
|
+
# @return [Boolean]
|
|
57
|
+
def has_converter?(source_type, target_type)
|
|
58
|
+
if source_type == target_type
|
|
59
|
+
return true
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
@converters.any? do |converter|
|
|
63
|
+
converter.source_type == source_type && converter.target_type == target_type
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Serialization
|
|
3
|
+
# Implementation of a converter that does no conversion
|
|
4
|
+
class IdentityConverter
|
|
5
|
+
include Converter
|
|
6
|
+
|
|
7
|
+
attr_reader :source_type
|
|
8
|
+
attr_reader :target_type
|
|
9
|
+
|
|
10
|
+
# @param [Class] type
|
|
11
|
+
# @return [undefined]
|
|
12
|
+
def initialize(type)
|
|
13
|
+
@source_type = @target_type = type
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @param [SerializedObject] original
|
|
17
|
+
# @return [SerializedObject]
|
|
18
|
+
def convert(original)
|
|
19
|
+
original
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @param [Object] original
|
|
23
|
+
# @return [Object]
|
|
24
|
+
def convert_content(original)
|
|
25
|
+
original
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
module Synapse
|
|
4
|
+
module Serialization
|
|
5
|
+
# Converter that converts a JSON string into a Ruby data structure
|
|
6
|
+
class JsonToObjectConverter
|
|
7
|
+
include Converter
|
|
8
|
+
|
|
9
|
+
converts String, Object
|
|
10
|
+
|
|
11
|
+
# @param [Object] original
|
|
12
|
+
# @return [Object]
|
|
13
|
+
def convert_content(original)
|
|
14
|
+
JSON.parse original, @options
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Converter that converts a Ruby data structure into a JSON string
|
|
19
|
+
class ObjectToJsonConverter
|
|
20
|
+
include Converter
|
|
21
|
+
|
|
22
|
+
converts Object, String
|
|
23
|
+
|
|
24
|
+
# @param [Object] original
|
|
25
|
+
# @return [Object]
|
|
26
|
+
def convert_content(original)
|
|
27
|
+
JSON.generate original, @options
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'ox'
|
|
2
|
+
|
|
3
|
+
module Synapse
|
|
4
|
+
module Serialization
|
|
5
|
+
# Converter that converts an Ox document into an XML string
|
|
6
|
+
class OxDocumentToXmlConverter
|
|
7
|
+
include Converter
|
|
8
|
+
|
|
9
|
+
converts Ox::Document, String
|
|
10
|
+
|
|
11
|
+
# @param [Object] original
|
|
12
|
+
# @return [Object]
|
|
13
|
+
def convert_content(original)
|
|
14
|
+
Ox.dump original, @options
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Converter that converts an XML string into an Ox document
|
|
19
|
+
class XmlToOxDocumentConverter
|
|
20
|
+
include Converter
|
|
21
|
+
|
|
22
|
+
converts String, Ox::Document
|
|
23
|
+
|
|
24
|
+
# @param [Object] original
|
|
25
|
+
# @return [Object]
|
|
26
|
+
def convert_content(original)
|
|
27
|
+
Ox.load original, @options
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Serialization
|
|
3
|
+
# Raised when conversion between two types is not supported
|
|
4
|
+
class ConversionError < NonTransientError; end
|
|
5
|
+
|
|
6
|
+
# Raised when an error occurs during serialization
|
|
7
|
+
class SerializationError < NonTransientError; end
|
|
8
|
+
|
|
9
|
+
# Raised when a serialized type can't be found in the current environment
|
|
10
|
+
class UnknownSerializedTypeError < SerializationError; end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Serialization
|
|
3
|
+
# Provides a generic lazy deserializing object
|
|
4
|
+
class LazyObject
|
|
5
|
+
# @return [SerializedObject]
|
|
6
|
+
attr_reader :serialized_object
|
|
7
|
+
|
|
8
|
+
# @return [Serializer]
|
|
9
|
+
attr_reader :serializer
|
|
10
|
+
|
|
11
|
+
# @return [Class]
|
|
12
|
+
attr_reader :type
|
|
13
|
+
|
|
14
|
+
# @param [SerializedObject] serialized_object
|
|
15
|
+
# @param [Serializer] serializer
|
|
16
|
+
# @return [undefined]
|
|
17
|
+
def initialize(serialized_object, serializer)
|
|
18
|
+
@serialized_object = serialized_object
|
|
19
|
+
@serializer = serializer
|
|
20
|
+
@type = serializer.class_for serialized_object.type
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Returns the deserialized version of the contained serialized object
|
|
24
|
+
# @return [Object]
|
|
25
|
+
def deserialized
|
|
26
|
+
@deserialized ||= @serializer.deserialize @serialized_object
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Returns true if this object has been deserialized already
|
|
30
|
+
# @return [Boolean]
|
|
31
|
+
def deserialized?
|
|
32
|
+
!!@deserialized
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Deserialized object that has (nearly) the same interface as a lazy object
|
|
37
|
+
class DeserializedObject
|
|
38
|
+
# @return [Object]
|
|
39
|
+
attr_reader :deserialized
|
|
40
|
+
|
|
41
|
+
# @return [Serializer] This will always be nil
|
|
42
|
+
attr_reader :serializer
|
|
43
|
+
|
|
44
|
+
# @return [Class]
|
|
45
|
+
attr_reader :type
|
|
46
|
+
|
|
47
|
+
# @param [Object] deserialized
|
|
48
|
+
# @return [undefined]
|
|
49
|
+
def initialize(deserialized)
|
|
50
|
+
@deserialized = deserialized
|
|
51
|
+
@type = deserialized.class
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Returns true if this object has been deserialized already; always true
|
|
55
|
+
# @return [Boolean]
|
|
56
|
+
def deserialized?
|
|
57
|
+
true
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Serialization
|
|
3
|
+
# Describes the properties that a serialized domain event should have
|
|
4
|
+
# @abstract
|
|
5
|
+
class SerializedDomainEventData
|
|
6
|
+
# @return [String] Identifier of the serialized event
|
|
7
|
+
def id; end
|
|
8
|
+
|
|
9
|
+
# @return [SerializedObject] Serialized metadata of the serialized event
|
|
10
|
+
def metadata; end
|
|
11
|
+
|
|
12
|
+
# @return [SerializedObject] Serialized payload of the serialized event
|
|
13
|
+
def payload; end
|
|
14
|
+
|
|
15
|
+
# @return [Time] Timestamp of the serialized event
|
|
16
|
+
def timestamp; end
|
|
17
|
+
|
|
18
|
+
# @return [Object] Identifier of the aggregate that the event was applied to
|
|
19
|
+
def aggregate_id; end
|
|
20
|
+
|
|
21
|
+
# @return [Integer] Sequence number of the event in the aggregate
|
|
22
|
+
def sequence_number; end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|