def test_construct_sqlalchemy_eventstore(self):
        # Construct the infrastructure.
        datastore = SQLAlchemyDatastore(settings=SQLAlchemySettings())
        datastore.setup_connection()

        event_store = construct_sqlalchemy_eventstore(
            session=datastore.session,
            contiguous_record_ids=True,
            application_name=uuid4().hex,
        )
        datastore.setup_table(event_store.record_manager.record_class)

        self.assertIsInstance(event_store, EventStore)

        # Store an event.
        aggregate_id = uuid4()
        aggregate_version = 0
        domain_event = DomainEvent(
            a=1,
            originator_id=aggregate_id,
            originator_version=aggregate_version,
        )
        event_store.append(domain_event)

        # Get the domain events.
        events = event_store.get_domain_events(originator_id=aggregate_id)
        self.assertEqual(len(events), 1)
        self.assertEqual(events[0], domain_event)

        # Test the while clause of all_sequence_ids() is filtering on application_name.
        self.assertEqual(event_store.record_manager.record_class,
                         StoredEventRecord)
        sequence_ids = event_store.record_manager.list_sequence_ids()
        self.assertEqual([aggregate_id], sequence_ids)

        # - check the aggregate ID isn't listed by another application
        event_store = construct_sqlalchemy_eventstore(
            session=datastore.session,
            contiguous_record_ids=True,
            application_name=uuid4().hex,
        )
        sequence_ids = event_store.record_manager.list_sequence_ids()
        self.assertEqual([], sequence_ids)
Example #2
0
    def test_construct_sqlalchemy_eventstore(self):

        datastore = SQLAlchemyDatastore(settings=SQLAlchemySettings())
        datastore.setup_connection()

        event_store = construct_sqlalchemy_eventstore(datastore.session)
        datastore.setup_table(event_store.record_manager.record_class)

        self.assertIsInstance(event_store, EventStore)

        aggregate_id = uuid4()
        aggregate_version = 0
        domain_event = DomainEvent(
            a=1,
            originator_id=aggregate_id,
            originator_version=aggregate_version,
        )
        event_store.append(domain_event)
        events = event_store.get_domain_events(originator_id=aggregate_id)
        self.assertEqual(len(events), 1)
        self.assertEqual(events[0], domain_event)
Example #3
0
class SimpleApplication(object):
    persist_event_type = None

    def __init__(self,
                 name='',
                 persistence_policy=None,
                 persist_event_type=None,
                 uri=None,
                 pool_size=5,
                 session=None,
                 cipher_key=None,
                 sequenced_item_class=None,
                 stored_event_record_class=None,
                 setup_table=True,
                 contiguous_record_ids=True,
                 pipeline_id=-1,
                 notification_log_section_size=None):

        self.notification_log_section_size = notification_log_section_size
        self.name = name or type(self).__name__.lower()

        # Setup cipher (optional).
        self.setup_cipher(cipher_key)

        # Setup connection to database.
        self.setup_datastore(session, uri, pool_size)

        # Setup the event store.
        self.sequenced_item_class = sequenced_item_class
        self.stored_event_record_class = stored_event_record_class
        self.contiguous_record_ids = contiguous_record_ids
        self.application_id = uuid_from_application_name(self.name)
        self.pipeline_id = pipeline_id
        self.setup_event_store()

        # Setup notifications.
        self.notification_log = RecordManagerNotificationLog(
            self.event_store.record_manager,
            section_size=self.notification_log_section_size)

        # Setup an event sourced repository.
        self.setup_repository()

        # Setup a persistence policy.
        self.persistence_policy = persistence_policy
        if self.persistence_policy is None:
            self.setup_persistence_policy(persist_event_type
                                          or type(self).persist_event_type)

        # Setup table in database.
        if setup_table and not session:
            self.setup_table()

    def change_pipeline(self, pipeline_id):
        self.pipeline_id = pipeline_id
        self.event_store.record_manager.pipeline_id = pipeline_id

    @property
    def session(self):
        return self.datastore.session

    def setup_cipher(self, cipher_key):
        cipher_key = decode_random_bytes(cipher_key
                                         or os.getenv('CIPHER_KEY', ''))
        self.cipher = AESCipher(cipher_key) if cipher_key else None

    def setup_datastore(self, session, uri, pool_size=5):
        self.datastore = SQLAlchemyDatastore(
            settings=SQLAlchemySettings(uri=uri, pool_size=pool_size),
            session=session,
        )

    def setup_event_store(self):
        # Construct event store.
        self.event_store = self.construct_event_store(self.application_id,
                                                      self.pipeline_id)

    def construct_event_store(self, application_id, pipeline_id):
        return construct_sqlalchemy_eventstore(
            sequenced_item_class=self.sequenced_item_class,
            session=self.datastore.session,
            cipher=self.cipher,
            record_class=self.stored_event_record_class,
            contiguous_record_ids=self.contiguous_record_ids,
            application_id=application_id,
            pipeline_id=pipeline_id,
        )

    def setup_repository(self, **kwargs):
        event_store = self.event_store
        self.repository = self.construct_repository(event_store, **kwargs)

    def construct_repository(self, event_store, **kwargs):
        return EventSourcedRepository(event_store=event_store, **kwargs)

    def setup_persistence_policy(self, persist_event_type):
        self.persistence_policy = PersistencePolicy(
            event_store=self.event_store, event_type=persist_event_type)

    def setup_table(self):
        # Setup the database table using event store's record class.
        self.datastore.setup_table(
            self.event_store.record_manager.record_class)

    def drop_table(self):
        # Setup the database table using event store's record class.
        self.datastore.drop_table(self.event_store.record_manager.record_class)

    def close(self):
        # Close the persistence policy.
        if self.persistence_policy:
            self.persistence_policy.close()

        # Close database connection.
        self.datastore.close_connection()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
Example #4
0
class SimpleApplication(object):
    def __init__(self, persist_event_type=None, uri=None, session=None, cipher_key=None,
                 stored_event_record_class=None, setup_table=True, contiguous_record_ids=True):

        # Setup cipher (optional).
        self.setup_cipher(cipher_key)

        # Setup connection to database.
        self.setup_datastore(session, uri)

        # Setup the event store.
        self.stored_event_record_class = stored_event_record_class
        self.contiguous_record_ids = contiguous_record_ids
        self.setup_event_store()

        # Setup notifications.
        self.notification_log = RecordManagerNotificationLog(
            self.event_store.record_manager,
            section_size=20,
        )

        # Setup an event sourced repository.
        self.setup_repository()

        # Setup a persistence policy.
        self.setup_persistence_policy(persist_event_type)

        # Setup table in database.
        if setup_table:
            self.setup_table()

    def setup_cipher(self, cipher_key):
        cipher_key = decode_random_bytes(cipher_key or os.getenv('CIPHER_KEY', ''))
        self.cipher = AESCipher(cipher_key) if cipher_key else None

    def setup_datastore(self, session, uri):
        self.datastore = SQLAlchemyDatastore(
            settings=SQLAlchemySettings(uri=uri),
            session=session,
        )

    def setup_event_store(self):
        # Construct event store.
        self.event_store = construct_sqlalchemy_eventstore(
            session=self.datastore.session,
            cipher=self.cipher,
            record_class=self.stored_event_record_class,
            contiguous_record_ids=self.contiguous_record_ids,
        )

    def setup_repository(self, **kwargs):
        self.repository = EventSourcedRepository(
            event_store=self.event_store,
            **kwargs
        )

    def setup_persistence_policy(self, persist_event_type):
        self.persistence_policy = PersistencePolicy(
            event_store=self.event_store,
            event_type=persist_event_type
        )

    def setup_table(self):
        # Setup the database table using event store's record class.
        self.datastore.setup_table(
            self.event_store.record_manager.record_class
        )

    def drop_table(self):
        # Setup the database table using event store's record class.
        self.datastore.drop_table(
            self.event_store.record_manager.record_class
        )

    def close(self):
        # Close the persistence policy.
        self.persistence_policy.close()

        # Close database connection.
        self.datastore.close_connection()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()