class ExampleApplicationWithAlternativeSequencedItemType(object):
    def __init__(self, session):
        self.event_store = EventStore(
            active_record_strategy=SQLAlchemyActiveRecordStrategy(
                session=session,
                active_record_class=StoredEventRecord,
                sequenced_item_class=StoredEvent,
            ),
            sequenced_item_mapper=SequencedItemMapper(
                sequenced_item_class=StoredEvent,
                sequence_id_attr_name='originator_id',
                position_attr_name='originator_version',
            )
        )
        self.repository = ExampleRepository(
            event_store=self.event_store,
        )
        self.persistence_policy = PersistencePolicy(self.event_store)

    def close(self):
        self.persistence_policy.close()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
class ExampleApplicationWithTimeuuidSequencedItems(object):
    def __init__(self):
        self.event_store = EventStore(
            active_record_strategy=CassandraActiveRecordStrategy(
                active_record_class=CqlTimeuuidSequencedItem,
                sequenced_item_class=SequencedItem,
            ),
            sequenced_item_mapper=SequencedItemMapper(
                sequenced_item_class=SequencedItem,
                sequence_id_attr_name='originator_id',
                position_attr_name='event_id',
            )
        )
        self.repository = EventSourcedRepository(
            mutator=ExampleEntity._mutate,
            event_store=self.event_store,
        )
        self.persistence_policy = PersistencePolicy(self.event_store)

    def start_entity(self):
        return ExampleEntity.start()

    def close(self):
        self.persistence_policy.close()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
class TestPersistencePolicy(unittest.TestCase):
    def setUp(self):
        self.event_store = mock.Mock(spec=AbstractEventStore)
        self.persistence_policy = PersistencePolicy(
            event_store=self.event_store,
            event_type=VersionedEntity.Event
        )

    def tearDown(self):
        self.persistence_policy.close()

    def test_published_events_are_appended_to_event_store(self):
        # Check the event store's append method has NOT been called.
        assert isinstance(self.event_store, AbstractEventStore)
        self.assertEqual(0, self.event_store.append.call_count)

        # Publish a versioned entity event.
        entity_id = uuid4()
        domain_event1 = VersionedEntity.Event(originator_id=entity_id, originator_version=0)
        publish(domain_event1)

        # Check the append method has been called once with the domain event.
        self.event_store.append.assert_called_once_with(domain_event1)

        # Publish a timestamped entity event (should be ignored).
        domain_event2 = TimestampedEntity.Event(originator_id=entity_id)
        publish(domain_event2)

        # Check the append() has still only been called once with the first domain event.
        self.event_store.append.assert_called_once_with(domain_event1)
Exemplo n.º 4
0
    def setUp(self):
        super(WithPersistencePolicies, self).setUp()
        # Setup the persistence subscriber.
        self.entity_event_store = EventStore(
            active_record_strategy=self.entity_active_record_strategy,
            sequenced_item_mapper=SequencedItemMapper(
                sequenced_item_class=SequencedItem,
                sequence_id_attr_name='originator_id',
                position_attr_name='originator_version'
            )
        )
        self.log_event_store = EventStore(
            active_record_strategy=self.log_active_record_strategy,
            sequenced_item_mapper=SequencedItemMapper(
                sequenced_item_class=SequencedItem,
                sequence_id_attr_name='originator_id',
                position_attr_name='timestamp'
            )
        )
        self.snapshot_store = EventStore(
            active_record_strategy=self.snapshot_active_record_strategy,
            sequenced_item_mapper=SequencedItemMapper(
                sequenced_item_class=SequencedItem,
                sequence_id_attr_name='originator_id',
                position_attr_name='originator_version'
            )
        )

        self.integer_sequenced_event_policy = None
        if self.entity_event_store is not None:
            self.integer_sequenced_event_policy = PersistencePolicy(
                event_store=self.entity_event_store,
                event_type=VersionedEntity.Event,
            )

        self.timestamp_sequenced_event_policy = None
        if self.log_event_store is not None:
            self.timestamp_sequenced_event_policy = PersistencePolicy(
                event_store=self.log_event_store,
                event_type=Logged,
            )

        self.snapshot_policy = None
        if self.snapshot_store is not None:
            self.snapshot_policy = PersistencePolicy(
                event_store=self.snapshot_store,
                event_type=Snapshot,
            )
class ExampleDDDApplication(object):
    def __init__(self, datastore):
        event_store = EventStore(
            active_record_strategy=SQLAlchemyActiveRecordStrategy(
                session=datastore.session,
                active_record_class=IntegerSequencedItemRecord,
            ),
            sequenced_item_mapper=SequencedItemMapper(
                sequence_id_attr_name='originator_id',
                position_attr_name='originator_version',
            )
        )
        self.aggregate_repository = EventSourcedRepository(
            mutator=ExampleAggregateRoot._mutate,
            event_store=event_store,
        )
        self.persistence_policy = PersistencePolicy(
            event_type=ExampleAggregateRoot.Event,
            event_store=event_store,
        )

    def create_example_aggregate(self):
        """
        Factory method, creates and returns a new example aggregate root object.

        :rtype: ExampleAggregateRoot 
        """
        event = ExampleAggregateRoot.Created(originator_id=uuid.uuid4())
        aggregate = ExampleAggregateRoot._mutate(initial=None, event=event)
        aggregate._pending_events.append(event)
        return aggregate

    def close(self):
        self.persistence_policy.close()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
class ExampleApplicationWithAlternativeSequencedItemType(object):
    def __init__(self):
        self.event_store = EventStore(
            active_record_strategy=CassandraActiveRecordStrategy(
                active_record_class=StoredEventRecord,
                sequenced_item_class=StoredEvent,
            ),
            sequenced_item_mapper=SequencedItemMapper(
                sequenced_item_class=StoredEvent,
                other_attr_names=(),
            )
        )
        self.repository = ExampleRepository(
            event_store=self.event_store,
        )
        self.persistence_policy = PersistencePolicy(self.event_store)

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.persistence_policy.close()
 def __init__(self):
     self.event_store = EventStore(
         active_record_strategy=CassandraActiveRecordStrategy(
             active_record_class=StoredEventRecord,
             sequenced_item_class=StoredEvent,
         ),
         sequenced_item_mapper=SequencedItemMapper(
             sequenced_item_class=StoredEvent,
             other_attr_names=(),
         )
     )
     self.repository = ExampleRepository(
         event_store=self.event_store,
     )
     self.persistence_policy = PersistencePolicy(self.event_store)
 def __init__(self, session):
     self.event_store = EventStore(
         active_record_strategy=SQLAlchemyActiveRecordStrategy(
             session=session,
             active_record_class=StoredEventRecord,
             sequenced_item_class=StoredEvent,
         ),
         sequenced_item_mapper=SequencedItemMapper(
             sequenced_item_class=StoredEvent,
             sequence_id_attr_name='originator_id',
             position_attr_name='originator_version',
         )
     )
     self.repository = ExampleRepository(
         event_store=self.event_store,
     )
     self.persistence_policy = PersistencePolicy(self.event_store)
 def __init__(self):
     self.event_store = EventStore(
         active_record_strategy=CassandraActiveRecordStrategy(
             active_record_class=CqlTimeuuidSequencedItem,
             sequenced_item_class=SequencedItem,
         ),
         sequenced_item_mapper=SequencedItemMapper(
             sequenced_item_class=SequencedItem,
             sequence_id_attr_name='originator_id',
             position_attr_name='event_id',
         )
     )
     self.repository = EventSourcedRepository(
         mutator=ExampleEntity._mutate,
         event_store=self.event_store,
     )
     self.persistence_policy = PersistencePolicy(self.event_store)
 def __init__(self, datastore):
     event_store = EventStore(
         active_record_strategy=SQLAlchemyActiveRecordStrategy(
             session=datastore.session,
             active_record_class=IntegerSequencedItemRecord,
         ),
         sequenced_item_mapper=SequencedItemMapper(
             sequence_id_attr_name='originator_id',
             position_attr_name='originator_version',
         )
     )
     self.aggregate_repository = EventSourcedRepository(
         mutator=ExampleAggregateRoot._mutate,
         event_store=event_store,
     )
     self.persistence_policy = PersistencePolicy(
         event_type=ExampleAggregateRoot.Event,
         event_store=event_store,
     )
 def setUp(self):
     self.event_store = mock.Mock(spec=AbstractEventStore)
     self.persistence_policy = PersistencePolicy(
         event_store=self.event_store,
         event_type=VersionedEntity.Event
     )
Exemplo n.º 12
0
class WithPersistencePolicies(WithActiveRecordStrategies):
    """
    Base class for test cases that need persistence policies.
    """

    def setUp(self):
        super(WithPersistencePolicies, self).setUp()
        # Setup the persistence subscriber.
        self.entity_event_store = EventStore(
            active_record_strategy=self.entity_active_record_strategy,
            sequenced_item_mapper=SequencedItemMapper(
                sequenced_item_class=SequencedItem,
                sequence_id_attr_name='originator_id',
                position_attr_name='originator_version'
            )
        )
        self.log_event_store = EventStore(
            active_record_strategy=self.log_active_record_strategy,
            sequenced_item_mapper=SequencedItemMapper(
                sequenced_item_class=SequencedItem,
                sequence_id_attr_name='originator_id',
                position_attr_name='timestamp'
            )
        )
        self.snapshot_store = EventStore(
            active_record_strategy=self.snapshot_active_record_strategy,
            sequenced_item_mapper=SequencedItemMapper(
                sequenced_item_class=SequencedItem,
                sequence_id_attr_name='originator_id',
                position_attr_name='originator_version'
            )
        )

        self.integer_sequenced_event_policy = None
        if self.entity_event_store is not None:
            self.integer_sequenced_event_policy = PersistencePolicy(
                event_store=self.entity_event_store,
                event_type=VersionedEntity.Event,
            )

        self.timestamp_sequenced_event_policy = None
        if self.log_event_store is not None:
            self.timestamp_sequenced_event_policy = PersistencePolicy(
                event_store=self.log_event_store,
                event_type=Logged,
            )

        self.snapshot_policy = None
        if self.snapshot_store is not None:
            self.snapshot_policy = PersistencePolicy(
                event_store=self.snapshot_store,
                event_type=Snapshot,
            )

    def tearDown(self):
        # Close the persistence subscriber.
        if self.snapshot_policy:
            self.snapshot_policy.close()
        if self.timestamp_sequenced_event_policy:
            self.timestamp_sequenced_event_policy.close()
        if self.entity_event_store:
            self.integer_sequenced_event_policy.close()
        super(WithPersistencePolicies, self).tearDown()
Exemplo n.º 13
0
    def test_take_snapshot(self):
        self.entity_persistence_policy = PersistencePolicy(
            event_store=self.entity_event_store,
            event_type=VersionedEntity.Event,
        )
        self.snapshot_persistence_policy = PersistencePolicy(
            event_store=self.snapshot_store,
            event_type=Snapshot,
        )
        snapshot_strategy = EventSourcedSnapshotStrategy(
            event_store=self.snapshot_store)
        event_player = EventPlayer(event_store=self.entity_event_store,
                                   mutator=Example._mutate,
                                   snapshot_strategy=snapshot_strategy)

        # Take a snapshot with a non-existent ID.
        unregistered_id = uuid4()
        # Check no snapshot is taken.
        self.assertIsNone(event_player.take_snapshot(unregistered_id))
        # Check no snapshot is available.
        self.assertIsNone(event_player.get_snapshot(unregistered_id))

        # Create a new entity.
        registered_example = create_new_example(a=123, b=234)

        # Take a snapshot of the new entity (no previous snapshots).
        snapshot1 = event_player.take_snapshot(registered_example.id,
                                               lt=registered_example.version)

        # Take another snapshot of the entity (should be the same event).
        sleep(0.0001)
        snapshot2 = event_player.take_snapshot(registered_example.id,
                                               lt=registered_example.version)
        self.assertEqual(snapshot1, snapshot2)

        # Check the snapshot is pegged to the last applied version.
        self.assertEqual(snapshot1.originator_version, 0)

        # Replay from this snapshot.
        entity_from_snapshot1 = entity_from_snapshot(snapshot1)
        retrieved_example = event_player.replay_entity(
            registered_example.id,
            initial_state=entity_from_snapshot1,
            gte=entity_from_snapshot1._version)

        # Check the attributes are correct.
        self.assertEqual(retrieved_example.a, 123)

        # Remember the version now.
        version1 = retrieved_example._version
        self.assertEqual(version1, 1)

        # Change attribute value.
        retrieved_example.a = 999

        # Remember the version now.
        version2 = retrieved_example._version
        self.assertEqual(version2, 2)

        # Change attribute value.
        retrieved_example.a = 9999

        # Remember the version now.
        version3 = retrieved_example._version
        self.assertEqual(version3, 3)

        # Check the event sourced entities are correct.
        retrieved_example = event_player.replay_entity(registered_example.id)
        self.assertEqual(retrieved_example.a, 9999)

        # Take another snapshot.
        snapshot3 = event_player.take_snapshot(retrieved_example.id,
                                               lt=retrieved_example.version)

        # Replay from this snapshot.
        initial_state = entity_from_snapshot(snapshot3)
        retrieved_example = event_player.replay_entity(
            registered_example.id,
            initial_state=initial_state,
            gte=initial_state._version,
        )
        # Check the attributes are correct.
        self.assertEqual(retrieved_example.a, 9999)

        # Check we can get historical state at version1.
        retrieved_example = event_player.replay_entity(registered_example.id,
                                                       lt=version1)
        self.assertEqual(retrieved_example.a, 123)

        # Check we can get historical state at version2.
        retrieved_example = event_player.replay_entity(registered_example.id,
                                                       lt=version2)
        self.assertEqual(retrieved_example.a, 999)

        # Check we can get historical state at version3.
        retrieved_example = event_player.replay_entity(registered_example.id,
                                                       lt=version3)
        self.assertEqual(retrieved_example.a, 9999)

        # Similarly, check we can get historical state using a snapshot
        initial_state = entity_from_snapshot(snapshot1)
        retrieved_example = event_player.replay_entity(
            registered_example.id,
            initial_state=initial_state,
            gte=initial_state._version,
            lt=version2,
        )
        self.assertEqual(retrieved_example.a, 999)

        # Discard the entity.
        registered_example = event_player.replay_entity(registered_example.id)
        registered_example.discard()

        # Take snapshot of discarded entity.
        snapshot4 = event_player.take_snapshot(registered_example.id)
        self.assertIsNone(snapshot4.state)
        self.assertIsNone(entity_from_snapshot(snapshot4))