synapse-core 0.2.0 → 0.4.0
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 +3 -0
- data/lib/synapse/command/simple_command_bus.rb +2 -2
- data/lib/synapse/common/concurrency/identifier_lock.rb +71 -0
- data/lib/synapse/common/concurrency/public_lock.rb +96 -0
- data/lib/synapse/event_bus/simple_event_bus.rb +1 -1
- data/lib/synapse/event_bus/wiring.rb +0 -4
- data/lib/synapse/event_sourcing/member.rb +0 -4
- data/lib/synapse/event_sourcing/snapshot/count_trigger.rb +2 -2
- data/lib/synapse/event_store.rb +1 -9
- data/lib/synapse/partitioning.rb +0 -2
- data/lib/synapse/process_manager.rb +12 -0
- data/lib/synapse/process_manager/lock_manager.rb +22 -0
- data/lib/synapse/process_manager/pessimistic_lock_manager.rb +23 -0
- data/lib/synapse/process_manager/process.rb +2 -0
- data/lib/synapse/process_manager/process_factory.rb +52 -0
- data/lib/synapse/process_manager/process_manager.rb +170 -0
- data/lib/synapse/process_manager/process_repository.rb +53 -0
- data/lib/synapse/process_manager/repository/in_memory.rb +63 -0
- data/lib/synapse/process_manager/resource_injector.rb +12 -0
- data/lib/synapse/process_manager/simple_process_manager.rb +48 -0
- data/lib/synapse/process_manager/wiring/process.rb +27 -0
- data/lib/synapse/process_manager/wiring/process_manager.rb +72 -0
- data/lib/synapse/repository.rb +1 -0
- data/lib/synapse/repository/locking.rb +1 -1
- data/lib/synapse/repository/optimistic_lock_manager.rb +128 -0
- data/lib/synapse/repository/pessimistic_lock_manager.rb +4 -37
- data/lib/synapse/serialization.rb +1 -1
- data/lib/synapse/serialization/{converter/factory.rb → converter_factory.rb} +0 -0
- data/lib/synapse/serialization/serializer.rb +5 -3
- data/lib/synapse/uow/listener_collection.rb +59 -1
- data/lib/synapse/version.rb +1 -1
- data/lib/synapse/wiring/message_wiring.rb +7 -3
- data/lib/synapse/wiring/wire.rb +7 -2
- data/test/common/concurrency/identifier_lock_test.rb +36 -0
- data/test/common/concurrency/public_lock_test.rb +83 -0
- data/test/partitioning/packing/json_test.rb +2 -1
- data/test/process_manager/in_memory_test.rb +57 -0
- data/test/process_manager/process_factory_test.rb +31 -0
- data/test/process_manager/simple_process_manager_test.rb +130 -0
- data/test/process_manager/wiring/fixtures.rb +42 -0
- data/test/process_manager/wiring/process_manager_test.rb +73 -0
- data/test/process_manager/wiring/process_test.rb +35 -0
- data/test/repository/optimistic_test.rb +41 -0
- data/test/repository/pessimistic_test.rb +20 -0
- data/test/serialization/converter/chain_test.rb +31 -0
- data/test/serialization/lazy_object_test.rb +1 -1
- data/test/serialization/message/serialization_aware_message_test.rb +4 -2
- data/test/serialization/message/serialized_message_builder_test.rb +1 -1
- data/test/serialization/message/serialized_message_test.rb +3 -2
- data/test/serialization/serializer/marshal_test.rb +1 -1
- data/test/serialization/serializer/oj_test.rb +1 -1
- data/test/serialization/serializer/ox_test.rb +1 -1
- data/test/serialization/serializer_test.rb +1 -1
- data/test/test_ext.rb +5 -2
- data/test/wiring/wire_registry_test.rb +10 -10
- data/test/wiring/wire_test.rb +5 -5
- metadata +29 -16
- data/lib/synapse/event_store/mongo.rb +0 -8
- data/lib/synapse/event_store/mongo/cursor_event_stream.rb +0 -63
- data/lib/synapse/event_store/mongo/event_store.rb +0 -86
- data/lib/synapse/event_store/mongo/per_commit_strategy.rb +0 -253
- data/lib/synapse/event_store/mongo/per_event_strategy.rb +0 -143
- data/lib/synapse/event_store/mongo/storage_strategy.rb +0 -113
- data/lib/synapse/event_store/mongo/template.rb +0 -73
- data/lib/synapse/partitioning/amqp.rb +0 -3
- data/lib/synapse/partitioning/amqp/amqp_queue_reader.rb +0 -50
- data/lib/synapse/partitioning/amqp/amqp_queue_writer.rb +0 -31
- data/lib/synapse/partitioning/amqp/key_resolver.rb +0 -26
- data/lib/synapse/serialization/converter/bson.rb +0 -28
| @@ -1,8 +0,0 @@ | |
| 1 | 
            -
            require 'synapse/event_store/mongo/cursor_event_stream'
         | 
| 2 | 
            -
            require 'synapse/event_store/mongo/event_store'
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            require 'synapse/event_store/mongo/storage_strategy'
         | 
| 5 | 
            -
            require 'synapse/event_store/mongo/per_commit_strategy'
         | 
| 6 | 
            -
            require 'synapse/event_store/mongo/per_event_strategy'
         | 
| 7 | 
            -
             | 
| 8 | 
            -
            require 'synapse/event_store/mongo/template'
         | 
| @@ -1,63 +0,0 @@ | |
| 1 | 
            -
            module Synapse
         | 
| 2 | 
            -
              module EventStore
         | 
| 3 | 
            -
                module Mongo
         | 
| 4 | 
            -
                  # TODO Document me
         | 
| 5 | 
            -
                  class CursorDomainEventStream < Domain::DomainEventStream
         | 
| 6 | 
            -
                    # @param [StorageStrategy] storage_strategy
         | 
| 7 | 
            -
                    # @param [Mongo::Cursor] cursor
         | 
| 8 | 
            -
                    # @param [Array] last_snapshot_commit
         | 
| 9 | 
            -
                    # @param [Object] aggregate_id
         | 
| 10 | 
            -
                    # @return [undefined]
         | 
| 11 | 
            -
                    def initialize(storage_strategy, cursor, last_snapshot_commit, aggregate_id)
         | 
| 12 | 
            -
                      @storage_strategy = storage_strategy
         | 
| 13 | 
            -
                      @cursor = cursor
         | 
| 14 | 
            -
                      @aggregate_id = aggregate_id
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                      if last_snapshot_commit
         | 
| 17 | 
            -
                        # Current batch is an enumerator
         | 
| 18 | 
            -
                        @current_batch = last_snapshot_commit.each
         | 
| 19 | 
            -
                      else
         | 
| 20 | 
            -
                        @current_batch = [].each
         | 
| 21 | 
            -
                      end
         | 
| 22 | 
            -
             | 
| 23 | 
            -
                      initialize_next_event
         | 
| 24 | 
            -
                    end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                    # @return [Boolean]
         | 
| 27 | 
            -
                    def end?
         | 
| 28 | 
            -
                      @next.nil?
         | 
| 29 | 
            -
                    end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                    # @return [DomainEventMessage]
         | 
| 32 | 
            -
                    def next_event
         | 
| 33 | 
            -
                      @next.tap do
         | 
| 34 | 
            -
                        initialize_next_event
         | 
| 35 | 
            -
                      end
         | 
| 36 | 
            -
                    end
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                    # @return [DomainEventMessage]
         | 
| 39 | 
            -
                    def peek
         | 
| 40 | 
            -
                      @next
         | 
| 41 | 
            -
                    end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
                  private
         | 
| 44 | 
            -
             | 
| 45 | 
            -
                    # @return [undefined]
         | 
| 46 | 
            -
                    def initialize_next_event
         | 
| 47 | 
            -
                      begin
         | 
| 48 | 
            -
                        @next = @current_batch.next
         | 
| 49 | 
            -
                      rescue StopIteration
         | 
| 50 | 
            -
                        if @cursor.has_next?
         | 
| 51 | 
            -
                          document = @cursor.next
         | 
| 52 | 
            -
                          @current_batch = @storage_strategy.extract_events(document, @aggregate_id).each
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                          retry
         | 
| 55 | 
            -
                        else
         | 
| 56 | 
            -
                          @next = nil
         | 
| 57 | 
            -
                        end
         | 
| 58 | 
            -
                      end
         | 
| 59 | 
            -
                    end
         | 
| 60 | 
            -
                  end # CursorDomainEventStream
         | 
| 61 | 
            -
                end
         | 
| 62 | 
            -
              end
         | 
| 63 | 
            -
            end
         | 
| @@ -1,86 +0,0 @@ | |
| 1 | 
            -
            module Synapse
         | 
| 2 | 
            -
              module EventStore
         | 
| 3 | 
            -
                module Mongo
         | 
| 4 | 
            -
                  # Implementation of an event store backed by a Mongo database
         | 
| 5 | 
            -
                  class MongoEventStore < SnapshotEventStore
         | 
| 6 | 
            -
                    # @param [MongoTemplate] template
         | 
| 7 | 
            -
                    # @param [StorageStrategy] storage_strategy
         | 
| 8 | 
            -
                    # @return [undefined]
         | 
| 9 | 
            -
                    def initialize(template, storage_strategy)
         | 
| 10 | 
            -
                      @storage_strategy = storage_strategy
         | 
| 11 | 
            -
                      @template = template
         | 
| 12 | 
            -
                    end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                    # @return [undefined]
         | 
| 15 | 
            -
                    def ensure_indexes
         | 
| 16 | 
            -
                      @storage_strategy.ensure_indexes
         | 
| 17 | 
            -
                    end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                    # @raise [EventStoreError] If an error occurs while reading the stream from the store
         | 
| 20 | 
            -
                    # @param [String] type_identifier Type descriptor of the aggregate to retrieve
         | 
| 21 | 
            -
                    # @param [Object] aggregate_id
         | 
| 22 | 
            -
                    # @return [DomainEventStream]
         | 
| 23 | 
            -
                    def read_events(type_identifier, aggregate_id)
         | 
| 24 | 
            -
                      first_sequence_number = -1
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                      last_snapshot_commit = load_last_snapshot type_identifier, aggregate_id
         | 
| 27 | 
            -
                      if last_snapshot_commit and last_snapshot_commit.size > 0
         | 
| 28 | 
            -
                        first_sequence_number = last_snapshot_commit[0].sequence_number
         | 
| 29 | 
            -
                      end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                      cursor = @storage_strategy.fetch_events type_identifier, aggregate_id, first_sequence_number
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                      unless last_snapshot_commit or cursor.has_next?
         | 
| 34 | 
            -
                        raise StreamNotFoundError.new type_identifier, aggregate_id
         | 
| 35 | 
            -
                      end
         | 
| 36 | 
            -
             | 
| 37 | 
            -
                      CursorDomainEventStream.new @storage_strategy, cursor, last_snapshot_commit, aggregate_id
         | 
| 38 | 
            -
                    end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
                    # @raise [EventStoreError] If an error occurs while appending the stream to the store
         | 
| 41 | 
            -
                    # @param [String] type_identifier Type descriptor of the aggregate to append to
         | 
| 42 | 
            -
                    # @param [DomainEventStream] stream
         | 
| 43 | 
            -
                    # @return [undefined]
         | 
| 44 | 
            -
                    def append_events(type_identifier, stream)
         | 
| 45 | 
            -
                      events = stream.to_a
         | 
| 46 | 
            -
                      documents = @storage_strategy.create_documents type_identifier, events
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                      begin
         | 
| 49 | 
            -
                        @template.event_collection.insert documents
         | 
| 50 | 
            -
                      rescue Mongo::OperationFailure => ex
         | 
| 51 | 
            -
                        if e.error_code == 11000
         | 
| 52 | 
            -
                          raise Repository::ConcurrencyException,
         | 
| 53 | 
            -
                            'Event for this aggregate and sequence number already present'
         | 
| 54 | 
            -
                        end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                        raise ex
         | 
| 57 | 
            -
                      end
         | 
| 58 | 
            -
                    end
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                    # @raise [EventStoreError] If an error occurs while appending the event to the store
         | 
| 61 | 
            -
                    # @param [String] type_identifier Type descriptor of the aggregate to append to
         | 
| 62 | 
            -
                    # @param [DomainEventMessage] snapshot_event
         | 
| 63 | 
            -
                    # @return [undefined]
         | 
| 64 | 
            -
                    def append_snapshot_event(type_identifier, snapshot_event)
         | 
| 65 | 
            -
                      documents = @storage_strategy.create_documents type_identifier, [snapshot_event]
         | 
| 66 | 
            -
                      @template.snapshot_collection.insert documents
         | 
| 67 | 
            -
                    end
         | 
| 68 | 
            -
             | 
| 69 | 
            -
                  private
         | 
| 70 | 
            -
             | 
| 71 | 
            -
                    # @param [String] type_identifier Type descriptor of the aggregate to retrieve
         | 
| 72 | 
            -
                    # @param [Object] aggregate_id
         | 
| 73 | 
            -
                    def load_last_snapshot(type_identifier, aggregate_id)
         | 
| 74 | 
            -
                      cursor = @storage_strategy.fetch_last_snapshot type_identifier, aggregate_id
         | 
| 75 | 
            -
             | 
| 76 | 
            -
                      unless cursor.has_next?
         | 
| 77 | 
            -
                        return
         | 
| 78 | 
            -
                      end
         | 
| 79 | 
            -
             | 
| 80 | 
            -
                      first = cursor.next_document
         | 
| 81 | 
            -
                      @storage_strategy.extract_events first, aggregate_id
         | 
| 82 | 
            -
                    end
         | 
| 83 | 
            -
                  end # MongoEventStore
         | 
| 84 | 
            -
                end # Mongo
         | 
| 85 | 
            -
              end # EventStore
         | 
| 86 | 
            -
            end # Synapse
         | 
| @@ -1,253 +0,0 @@ | |
| 1 | 
            -
            module Synapse
         | 
| 2 | 
            -
              module EventStore
         | 
| 3 | 
            -
                module Mongo
         | 
| 4 | 
            -
                  # Storage strategy that stores all events in a commit operation in a single document
         | 
| 5 | 
            -
                  #
         | 
| 6 | 
            -
                  # Since Mongo doesn't support transactions, this can be used as a substitute to guarantee
         | 
| 7 | 
            -
                  # atomic storage of events. The only downside is that it may be harder to query events
         | 
| 8 | 
            -
                  # from the event store.
         | 
| 9 | 
            -
                  #
         | 
| 10 | 
            -
                  # Performance also seems to be better using this strategy
         | 
| 11 | 
            -
                  class DocumentPerCommitStrategy < StorageStrategy
         | 
| 12 | 
            -
                    # @param [String] type_identifier Type identifier for the aggregate
         | 
| 13 | 
            -
                    # @param [Array] events Domain events to be committed
         | 
| 14 | 
            -
                    # @return [Array]
         | 
| 15 | 
            -
                    def create_documents(type_identifier, events)
         | 
| 16 | 
            -
                      document = CommitDocument.new
         | 
| 17 | 
            -
                      document.from_events(type_identifier, events, @serializer).to_hash
         | 
| 18 | 
            -
                    end
         | 
| 19 | 
            -
             | 
| 20 | 
            -
                    # @param [Hash] hash
         | 
| 21 | 
            -
                    # @param [Object] aggregate_id
         | 
| 22 | 
            -
                    # @return [Array]
         | 
| 23 | 
            -
                    def extract_events(hash, aggregate_id)
         | 
| 24 | 
            -
                      document = CommitDocument.new
         | 
| 25 | 
            -
                      document.from_hash(hash).to_events(aggregate_id, @serializer, @upcaster_chain)
         | 
| 26 | 
            -
                    end
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                    # Mongo document that represents a commit containing one or more events
         | 
| 29 | 
            -
                    class CommitDocument
         | 
| 30 | 
            -
                      # @return [Object]
         | 
| 31 | 
            -
                      attr_reader :aggregate_id
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                      # @param [String] type_identifier
         | 
| 34 | 
            -
                      # @param [Array] events
         | 
| 35 | 
            -
                      # @param [Serializer] serializer
         | 
| 36 | 
            -
                      # @return [CommitDocument]
         | 
| 37 | 
            -
                      def from_events(type_identifier, events, serializer)
         | 
| 38 | 
            -
                        first_event = events.first
         | 
| 39 | 
            -
                        last_event = events.last
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                        @aggregate_type = type_identifier
         | 
| 42 | 
            -
                        @aggregate_id = first_event.aggregate_id.to_s
         | 
| 43 | 
            -
                        @first_sequence_number = first_event.sequence_number
         | 
| 44 | 
            -
                        @last_sequence_number = last_event.sequence_number
         | 
| 45 | 
            -
                        @first_timestamp = first_event.timestamp
         | 
| 46 | 
            -
                        @last_timestamp = last_event.timestamp
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                        @events = Array.new
         | 
| 49 | 
            -
                        events.each do |event|
         | 
| 50 | 
            -
                          event_document = EventDocument.new
         | 
| 51 | 
            -
                          event_document.from_event event, serializer
         | 
| 52 | 
            -
             | 
| 53 | 
            -
                          @events.push event_document
         | 
| 54 | 
            -
                        end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                        self
         | 
| 57 | 
            -
                      end
         | 
| 58 | 
            -
             | 
| 59 | 
            -
                      # @param [Hash] hash
         | 
| 60 | 
            -
                      # @return [CommitDocument]
         | 
| 61 | 
            -
                      def from_hash(hash)
         | 
| 62 | 
            -
                        hash.symbolize_keys!
         | 
| 63 | 
            -
             | 
| 64 | 
            -
                        @aggregate_id = hash.fetch :aggregate_id
         | 
| 65 | 
            -
                        @aggregate_type = hash.fetch :aggregate_type
         | 
| 66 | 
            -
                        @first_sequence_number = hash.fetch :first_sequence_number
         | 
| 67 | 
            -
                        @last_sequence_number = hash.fetch :last_sequence_number
         | 
| 68 | 
            -
                        @first_timestamp = hash.fetch :first_timestamp
         | 
| 69 | 
            -
                        @last_timestamp = hash.fetch :last_timestamp
         | 
| 70 | 
            -
             | 
| 71 | 
            -
                        @events = Array.new
         | 
| 72 | 
            -
             | 
| 73 | 
            -
                        event_hashes = hash.fetch :events
         | 
| 74 | 
            -
                        event_hashes.each do |event_hash|
         | 
| 75 | 
            -
                          event_document = EventDocument.new
         | 
| 76 | 
            -
                          event_document.from_hash event_hash
         | 
| 77 | 
            -
             | 
| 78 | 
            -
                          @events.push event_document
         | 
| 79 | 
            -
                        end
         | 
| 80 | 
            -
             | 
| 81 | 
            -
                        self
         | 
| 82 | 
            -
                      end
         | 
| 83 | 
            -
             | 
| 84 | 
            -
                      # @return [Hash]
         | 
| 85 | 
            -
                      def to_hash
         | 
| 86 | 
            -
                        events = Array.new
         | 
| 87 | 
            -
                        @events.each do |event|
         | 
| 88 | 
            -
                          events.push event.to_hash
         | 
| 89 | 
            -
                        end
         | 
| 90 | 
            -
             | 
| 91 | 
            -
                        { aggregate_id: @aggregate_id,
         | 
| 92 | 
            -
                          aggregate_type: @aggregate_type,
         | 
| 93 | 
            -
                          # Allows us to use the same query to filter events as DocumentPerEvent
         | 
| 94 | 
            -
                          sequence_number: @first_sequence_number,
         | 
| 95 | 
            -
                          first_sequence_number: @first_sequence_number,
         | 
| 96 | 
            -
                          last_sequence_number: @last_sequence_number,
         | 
| 97 | 
            -
                          # Allows us to use the same query to filter events as DocumentPerEvent
         | 
| 98 | 
            -
                          timestamp: @first_timestamp,
         | 
| 99 | 
            -
                          first_timestamp: @first_timestamp,
         | 
| 100 | 
            -
                          last_timestamp: @last_timestamp,
         | 
| 101 | 
            -
                          events: events }
         | 
| 102 | 
            -
                      end
         | 
| 103 | 
            -
             | 
| 104 | 
            -
                      # @param [Object] aggregate_id The actual aggregate identifier used to query the evnet store
         | 
| 105 | 
            -
                      # @param [Serializer] serializer
         | 
| 106 | 
            -
                      # @param [UpcasterChain] upcaster_chain
         | 
| 107 | 
            -
                      # @return [Array]
         | 
| 108 | 
            -
                      def to_events(aggregate_id, serializer, upcaster_chain)
         | 
| 109 | 
            -
                        events = Array.new
         | 
| 110 | 
            -
             | 
| 111 | 
            -
                        @events.each do |event_document|
         | 
| 112 | 
            -
                          event_data = DocumentDomainEventData.new aggregate_id, event_document
         | 
| 113 | 
            -
                          context = Upcasting::SerializedDomainEventUpcastingContext.new event_data, aggregate_id, serializer
         | 
| 114 | 
            -
             | 
| 115 | 
            -
                          upcast_objects = upcaster_chain.upcast event_document.payload, context
         | 
| 116 | 
            -
                          upcast_objects.each do |upcast_object|
         | 
| 117 | 
            -
                            upcast_data = Upcasting::UpcastSerializedDomainEventData.new event_data, aggregate_id, upcast_object
         | 
| 118 | 
            -
             | 
| 119 | 
            -
                            builder = Serialization::SerializedDomainEventMessageBuilder.new
         | 
| 120 | 
            -
             | 
| 121 | 
            -
                            # Prevent duplicate serialization of metadata if it was accessed during upcasting
         | 
| 122 | 
            -
                            metadata = context.serialized_metadata
         | 
| 123 | 
            -
                            if metadata.deserialized?
         | 
| 124 | 
            -
                              builder.metadata = Serialization::DeserializedObject.new metadata.deserialized
         | 
| 125 | 
            -
                            end
         | 
| 126 | 
            -
             | 
| 127 | 
            -
                            builder.from_data upcast_data, serializer
         | 
| 128 | 
            -
             | 
| 129 | 
            -
                            events.push builder.build
         | 
| 130 | 
            -
                          end
         | 
| 131 | 
            -
                        end
         | 
| 132 | 
            -
             | 
| 133 | 
            -
                        events
         | 
| 134 | 
            -
                      end
         | 
| 135 | 
            -
                    end # CommitDocument
         | 
| 136 | 
            -
             | 
| 137 | 
            -
                    # Mongo document that represents a single event as part of a commit document
         | 
| 138 | 
            -
                    class EventDocument
         | 
| 139 | 
            -
                      # @return [String]
         | 
| 140 | 
            -
                      attr_reader :id
         | 
| 141 | 
            -
             | 
| 142 | 
            -
                      # @return [Time]
         | 
| 143 | 
            -
                      attr_reader :timestamp
         | 
| 144 | 
            -
             | 
| 145 | 
            -
                      # @return [Integer]
         | 
| 146 | 
            -
                      attr_reader :sequence_number
         | 
| 147 | 
            -
             | 
| 148 | 
            -
                      # @return [SerializedObject]
         | 
| 149 | 
            -
                      def metadata
         | 
| 150 | 
            -
                        Serialization::SerializedMetadata.new @metadata, @metadata.class
         | 
| 151 | 
            -
                      end
         | 
| 152 | 
            -
             | 
| 153 | 
            -
                      # @return [SerializedObject]
         | 
| 154 | 
            -
                      def payload
         | 
| 155 | 
            -
                        Serialization::SerializedObject.new @payload, @payload.class,
         | 
| 156 | 
            -
                          Serialization::SerializedType.new(@payload_type, @payload_revision)
         | 
| 157 | 
            -
                      end
         | 
| 158 | 
            -
             | 
| 159 | 
            -
                      # @param [EventMessage] event
         | 
| 160 | 
            -
                      # @param [Serializer] serializer
         | 
| 161 | 
            -
                      # @return [EventDocument]
         | 
| 162 | 
            -
                      def from_event(event, serializer)
         | 
| 163 | 
            -
                        serialization_target = String
         | 
| 164 | 
            -
                        if serializer.can_serialize_to? Hash
         | 
| 165 | 
            -
                          serialization_target = Hash
         | 
| 166 | 
            -
                        end
         | 
| 167 | 
            -
             | 
| 168 | 
            -
                        serialized_metadata = serializer.serialize_metadata event, serialization_target
         | 
| 169 | 
            -
                        serialized_payload = serializer.serialize_payload event, serialization_target
         | 
| 170 | 
            -
             | 
| 171 | 
            -
                        @id = event.id
         | 
| 172 | 
            -
                        @metadata = serialized_metadata.content
         | 
| 173 | 
            -
                        @payload = serialized_payload.content
         | 
| 174 | 
            -
                        @payload_type = serialized_payload.type.name
         | 
| 175 | 
            -
                        @payload_revision = serialized_payload.type.revision
         | 
| 176 | 
            -
                        @timestamp = event.timestamp
         | 
| 177 | 
            -
                        @sequence_number = event.sequence_number
         | 
| 178 | 
            -
             | 
| 179 | 
            -
                        self
         | 
| 180 | 
            -
                      end
         | 
| 181 | 
            -
             | 
| 182 | 
            -
                      # @param [Hash] hash
         | 
| 183 | 
            -
                      # @return [EventDocument]
         | 
| 184 | 
            -
                      def from_hash(hash)
         | 
| 185 | 
            -
                        hash.symbolize_keys!
         | 
| 186 | 
            -
             | 
| 187 | 
            -
                        @id = hash.fetch :id
         | 
| 188 | 
            -
                        @metadata = hash.fetch :metadata
         | 
| 189 | 
            -
                        @payload = hash.fetch :payload
         | 
| 190 | 
            -
                        @payload_type = hash.fetch :payload_type
         | 
| 191 | 
            -
                        @payload_revision = hash.fetch :payload_revision
         | 
| 192 | 
            -
                        @timestamp = hash.fetch :timestamp
         | 
| 193 | 
            -
                        @sequence_number = hash.fetch :sequence_number
         | 
| 194 | 
            -
             | 
| 195 | 
            -
                        self
         | 
| 196 | 
            -
                      end
         | 
| 197 | 
            -
             | 
| 198 | 
            -
                      # @return [Hash]
         | 
| 199 | 
            -
                      def to_hash
         | 
| 200 | 
            -
                        { id: @id,
         | 
| 201 | 
            -
                          metadata: @metadata,
         | 
| 202 | 
            -
                          payload: @payload,
         | 
| 203 | 
            -
                          payload_type: @payload_type,
         | 
| 204 | 
            -
                          payload_revision: @payload_revision,
         | 
| 205 | 
            -
                          timestamp: @timestamp,
         | 
| 206 | 
            -
                          sequence_number: @sequence_number }
         | 
| 207 | 
            -
                      end
         | 
| 208 | 
            -
                    end # EventDocument
         | 
| 209 | 
            -
             | 
| 210 | 
            -
                    # Serialized domain event data from an event document
         | 
| 211 | 
            -
                    class DocumentDomainEventData < Serialization::SerializedDomainEventData
         | 
| 212 | 
            -
                      # @param [Object] aggregate_id
         | 
| 213 | 
            -
                      # @param [EventDocument] event_document
         | 
| 214 | 
            -
                      # @return [undefined]
         | 
| 215 | 
            -
                      def initialize(aggregate_id, event_document)
         | 
| 216 | 
            -
                        @aggregate_id = aggregate_id
         | 
| 217 | 
            -
                        @event_document = event_document
         | 
| 218 | 
            -
                      end
         | 
| 219 | 
            -
             | 
| 220 | 
            -
                      # @return [String]
         | 
| 221 | 
            -
                      def id
         | 
| 222 | 
            -
                        @event_document.id
         | 
| 223 | 
            -
                      end
         | 
| 224 | 
            -
             | 
| 225 | 
            -
                      # @return [SerializedObject]
         | 
| 226 | 
            -
                      def metadata
         | 
| 227 | 
            -
                        @event_document.metadata
         | 
| 228 | 
            -
                      end
         | 
| 229 | 
            -
             | 
| 230 | 
            -
                      # @return [SerializedObject]
         | 
| 231 | 
            -
                      def payload
         | 
| 232 | 
            -
                        @event_document.payload
         | 
| 233 | 
            -
                      end
         | 
| 234 | 
            -
             | 
| 235 | 
            -
                      # @return [Time]
         | 
| 236 | 
            -
                      def timestamp
         | 
| 237 | 
            -
                        @event_document.timestamp
         | 
| 238 | 
            -
                      end
         | 
| 239 | 
            -
             | 
| 240 | 
            -
                      # @return [Object]
         | 
| 241 | 
            -
                      def aggregate_id
         | 
| 242 | 
            -
                        @aggregate_id
         | 
| 243 | 
            -
                      end
         | 
| 244 | 
            -
             | 
| 245 | 
            -
                      # @return [Integer]
         | 
| 246 | 
            -
                      def sequence_number
         | 
| 247 | 
            -
                        @event_document.sequence_number
         | 
| 248 | 
            -
                      end
         | 
| 249 | 
            -
                    end # DocumentDomainEventData
         | 
| 250 | 
            -
                  end # DocumentPerCommitStrategy
         | 
| 251 | 
            -
                end # Mongo
         | 
| 252 | 
            -
              end # EventStore
         | 
| 253 | 
            -
            end # Synapse
         | 
| @@ -1,143 +0,0 @@ | |
| 1 | 
            -
            module Synapse
         | 
| 2 | 
            -
              module EventStore
         | 
| 3 | 
            -
                module Mongo
         | 
| 4 | 
            -
                  # Storage strategy that stores each event as its own document
         | 
| 5 | 
            -
                  class DocumentPerEventStrategy < StorageStrategy
         | 
| 6 | 
            -
                    # @param [String] type_identifier Type identifier for the aggregate
         | 
| 7 | 
            -
                    # @param [Array] events Domain events to be committed
         | 
| 8 | 
            -
                    # @return [Array]
         | 
| 9 | 
            -
                    def create_documents(type_identifier, events)
         | 
| 10 | 
            -
                      documents = Array.new
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                      events.each do |event|
         | 
| 13 | 
            -
                        document = EventDocument.new
         | 
| 14 | 
            -
                        document.from_event event, type_identifier, @serializer
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                        documents.push document.to_hash
         | 
| 17 | 
            -
                      end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                      documents
         | 
| 20 | 
            -
                    end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                    # @param [Hash] hash
         | 
| 23 | 
            -
                    # @param [Object] aggregate_id
         | 
| 24 | 
            -
                    # @return [Array]
         | 
| 25 | 
            -
                    def extract_events(hash, aggregate_id)
         | 
| 26 | 
            -
                      document = EventDocument.new
         | 
| 27 | 
            -
                      document.from_hash(hash).to_events(aggregate_id, @serializer, @upcaster_chain)
         | 
| 28 | 
            -
                    end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                    # Mongo document that represents a single domain event
         | 
| 31 | 
            -
                    class EventDocument < Serialization::SerializedDomainEventData
         | 
| 32 | 
            -
                      # @return [String]
         | 
| 33 | 
            -
                      attr_reader :id
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                      # @return [Time]
         | 
| 36 | 
            -
                      attr_reader :timestamp
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                      # @return [Object]
         | 
| 39 | 
            -
                      attr_reader :aggregate_id
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                      # @return [Integer]
         | 
| 42 | 
            -
                      attr_reader :sequence_number
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                      # @param [SerializedObject]
         | 
| 45 | 
            -
                      def metadata
         | 
| 46 | 
            -
                        Serialization::SerializedMetadata.new @metadata, @metadata.class
         | 
| 47 | 
            -
                      end
         | 
| 48 | 
            -
             | 
| 49 | 
            -
                      # @param [SerializedObject]
         | 
| 50 | 
            -
                      def payload
         | 
| 51 | 
            -
                        Serialization::SerializedObject.new @payload, @payload.class,
         | 
| 52 | 
            -
                          Serialization::SerializedType.new(@payload_type, @payload_revision)
         | 
| 53 | 
            -
                      end
         | 
| 54 | 
            -
             | 
| 55 | 
            -
                      # @param [DomainEventMessage] event
         | 
| 56 | 
            -
                      # @param [String] type_identifier
         | 
| 57 | 
            -
                      # @param [Serializer] serializer
         | 
| 58 | 
            -
                      # @return [EventDocument]
         | 
| 59 | 
            -
                      def from_event(event, type_identifier, serializer)
         | 
| 60 | 
            -
                        serialization_target = String
         | 
| 61 | 
            -
                        if serializer.can_serialize_to? Hash
         | 
| 62 | 
            -
                          serialization_target = Hash
         | 
| 63 | 
            -
                        end
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                        serialized_metadata = serializer.serialize_metadata event, serialization_target
         | 
| 66 | 
            -
                        serialized_payload = serializer.serialize_payload event, serialization_target
         | 
| 67 | 
            -
             | 
| 68 | 
            -
                        @id = event.id
         | 
| 69 | 
            -
                        @metadata = serialized_metadata.content
         | 
| 70 | 
            -
                        @payload = serialized_payload.content
         | 
| 71 | 
            -
                        @payload_type = serialized_payload.type.name
         | 
| 72 | 
            -
                        @payload_revision = serialized_payload.type.revision
         | 
| 73 | 
            -
                        @timestamp = event.timestamp
         | 
| 74 | 
            -
                        @aggregate_id = event.aggregate_id
         | 
| 75 | 
            -
                        @aggregate_type = type_identifier
         | 
| 76 | 
            -
                        @sequence_number = event.sequence_number
         | 
| 77 | 
            -
             | 
| 78 | 
            -
                        self
         | 
| 79 | 
            -
                      end
         | 
| 80 | 
            -
             | 
| 81 | 
            -
                      # @param [Hash] hash
         | 
| 82 | 
            -
                      # @return [EventDocument]
         | 
| 83 | 
            -
                      def from_hash(hash)
         | 
| 84 | 
            -
                        hash.symbolize_keys!
         | 
| 85 | 
            -
             | 
| 86 | 
            -
                        @id = hash.fetch :_id
         | 
| 87 | 
            -
                        @metadata = hash.fetch :metadata
         | 
| 88 | 
            -
                        @payload = hash.fetch :payload
         | 
| 89 | 
            -
                        @payload_type = hash.fetch :payload_type
         | 
| 90 | 
            -
                        @payload_revision = hash.fetch :payload_revision
         | 
| 91 | 
            -
                        @timestamp = hash.fetch :timestamp
         | 
| 92 | 
            -
                        @aggregate_id = hash.fetch :aggregate_id
         | 
| 93 | 
            -
                        @aggregate_type = hash.fetch :aggregate_type
         | 
| 94 | 
            -
                        @sequence_number = hash.fetch :sequence_number
         | 
| 95 | 
            -
             | 
| 96 | 
            -
                        self
         | 
| 97 | 
            -
                      end
         | 
| 98 | 
            -
             | 
| 99 | 
            -
                      # @return [Hash]
         | 
| 100 | 
            -
                      def to_hash
         | 
| 101 | 
            -
                        { _id: @id,
         | 
| 102 | 
            -
                          metadata: @metadata,
         | 
| 103 | 
            -
                          payload: @payload,
         | 
| 104 | 
            -
                          payload_type: @payload_type,
         | 
| 105 | 
            -
                          payload_revision: @payload_revision,
         | 
| 106 | 
            -
                          timestamp: @timestamp,
         | 
| 107 | 
            -
                          aggregate_id: @aggregate_id,
         | 
| 108 | 
            -
                          aggregate_type: @aggregate_type,
         | 
| 109 | 
            -
                          sequence_number: @sequence_number }
         | 
| 110 | 
            -
                      end
         | 
| 111 | 
            -
             | 
| 112 | 
            -
                      # @param [Object] aggregate_id
         | 
| 113 | 
            -
                      # @param [Serializer] serializer
         | 
| 114 | 
            -
                      # @param [UpcasterChain] upcaster_chain
         | 
| 115 | 
            -
                      # @return [Array]
         | 
| 116 | 
            -
                      def to_events(aggregate_id, serializer, upcaster_chain)
         | 
| 117 | 
            -
                        events = Array.new
         | 
| 118 | 
            -
             | 
| 119 | 
            -
                        context = Upcasting::SerializedDomainEventUpcastingContext.new self, aggregate_id, serializer
         | 
| 120 | 
            -
                        upcast_objects = upcaster_chain.upcast payload, context
         | 
| 121 | 
            -
                        upcast_objects.each do |upcast_object|
         | 
| 122 | 
            -
                          upcast_data = Upcasting::UpcastSerializedDomainEventData.new self, aggregate_id, upcast_object
         | 
| 123 | 
            -
             | 
| 124 | 
            -
                          builder = Serialization::SerializedDomainEventMessageBuilder.new
         | 
| 125 | 
            -
             | 
| 126 | 
            -
                          # Prevent duplicate serialization of metadata if it was accessed during upcasting
         | 
| 127 | 
            -
                          metadata = context.serialized_metadata
         | 
| 128 | 
            -
                          if metadata.deserialized?
         | 
| 129 | 
            -
                            builder.metadata = Serialization::DeserializedObject.new metadata.deserialized
         | 
| 130 | 
            -
                          end
         | 
| 131 | 
            -
             | 
| 132 | 
            -
                          builder.from_data upcast_data, serializer
         | 
| 133 | 
            -
             | 
| 134 | 
            -
                          events.push builder.build
         | 
| 135 | 
            -
                        end
         | 
| 136 | 
            -
             | 
| 137 | 
            -
                        events
         | 
| 138 | 
            -
                      end
         | 
| 139 | 
            -
                    end # EventDocument
         | 
| 140 | 
            -
                  end # DocumentPerEventStrategy
         | 
| 141 | 
            -
                end # Mongo
         | 
| 142 | 
            -
              end # EventStore
         | 
| 143 | 
            -
            end # Synapse
         |