def test_should_publish_reject_and_requeue_from_dead_letter_exchange( given_any_petisco, make_user_created_event, given_random_organization, given_random_service, given_random_topic, given_a_short_message_ttl, ): event = make_user_created_event() tracked_events_spy = TrackedEventsSpy() tracked_requeue_events_dead_letter_spy = TrackedEventsSpy() publisher = RabbitMQEventPublisher( connector=RabbitMqConnector(), organization=given_random_organization, service=given_random_service, topic=given_random_topic, ) @subscriber_handler() def main_handler(event: Event): tracked_events_spy.append(event) return isFailure @subscriber_handler() def requeue_from_dead_letter(event: Event): tracked_requeue_events_dead_letter_spy.append(event) publisher.publish(event) return isSuccess publisher.publish(event) subscriber = RabbitMQEventSubscriber( connector=RabbitMqConnector(), subscribers={ "auth": ConfigEventSubscriber( organization=given_random_organization, service=given_random_service, topic=given_random_topic, handler=main_handler, ), "dead-letter": ConfigEventSubscriber( organization=given_random_organization, service=given_random_service, topic=given_random_topic, handler=requeue_from_dead_letter, dead_letter=True, ), }, ) subscriber.start() await_for_events() tracked_events_spy.assert_number_events(1) tracked_requeue_events_dead_letter_spy.assert_number_events(1) subscriber.stop()
def test_should_get_an_open_connection(): connector = RabbitMqConnector() connection = connector.get_connection("test") assert connection.is_open connection.close()
def test_should_recover_from_connection_closed(): connector = RabbitMqConnector() connection = connector.get_connection("test") connection.close() connection = connector.get_connection("test") assert connection.is_open connection.close()
def rabbitmq_event_publisher_provider() -> RabbitMQEventPublisher: return RabbitMQEventPublisher( connector=RabbitMqConnector(), organization="acme", service="taskmanager", topic="taskmanager-events", )
def subscribe_to_dead_letter(): subscriber = RabbitMQEventSubscriber( connector=RabbitMqConnector(), subscribers={ "dead-letter": ConfigEventSubscriber( organization="acme", service="taskmanager", topic="taskmanager-events", handler=requeue_from_dead_letter, dead_letter=True, ) }, connection_name="dead-letter-subscriber", ) subscriber.start() scheduler = BackgroundScheduler() def shutdown(): subscriber.start() scheduler.shutdown() scheduler.add_job(func=shutdown, trigger="interval", seconds=TEN_MINUTES) scheduler.start()
def with_service(service: str, connector: RabbitMqConnector = None): connector = RabbitMqConnector() if not connector else connector return RabbitMqEventConfigurer( connector, DEFAULT_ORGANIZATION, service, QueueConfig.default(default_retry_ttl=10), )
def with_ttl_1s(connector: RabbitMqConnector = None): connector = RabbitMqConnector() if not connector else connector return RabbitMqEventConfigurer( connector, DEFAULT_ORGANIZATION, DEFAULT_SERVICE, QueueConfig.default(default_retry_ttl=1000), )
def test_should_work_successfully_a_happy_path_pub_sub( given_any_petisco, make_user_created_event, given_random_organization, given_random_service, given_random_topic, ): event_1 = make_user_created_event() event_2 = make_user_created_event() tracked_events_spy = TrackedEventsSpy() @subscriber_handler() def main_handler(event: Event): tracked_events_spy.append(event) return isSuccess publisher = RabbitMQEventPublisher( connector=RabbitMqConnector(), organization=given_random_organization, service=given_random_service, topic=given_random_topic, ) publisher.publish_events([event_1, event_2]) subscriber = RabbitMQEventSubscriber( connector=RabbitMqConnector(), subscribers={ "auth": ConfigEventSubscriber( organization=given_random_organization, service=given_random_service, topic=given_random_topic, handler=main_handler, ) }, ) subscriber.start() await_for_events() tracked_events_spy.assert_number_events(2) subscriber.stop()
def with_service(service: str, connector: RabbitMqConnector = None): connector = RabbitMqConnector() if not connector else connector return RabbitMqEventConsumer( connector, DEFAULT_ORGANIZATION, service, DEFAULT_MAX_RETRIES, DEFAULT_VERBOSE, )
def default(connector: RabbitMqConnector = None): connector = RabbitMqConnector() if not connector else connector return RabbitMqEventConsumer( connector, DEFAULT_ORGANIZATION, DEFAULT_SERVICE, DEFAULT_MAX_RETRIES, DEFAULT_VERBOSE, )
def with_max_retries(max_retries: int, connector: RabbitMqConnector = None): connector = RabbitMqConnector() if not connector else connector return RabbitMqEventConsumer( connector, DEFAULT_ORGANIZATION, DEFAULT_SERVICE, max_retries, DEFAULT_VERBOSE, )
def _given_any_publisher( given_random_organization, given_random_service, given_random_topic ): publisher = RabbitMQEventPublisher( connector=RabbitMqConnector(), organization=given_random_organization, service=given_random_service, topic=given_random_topic, ) return publisher
def test_should_recover_from_connection_error_when_publish_an_event( make_user_created_event, ): connector = RabbitMqConnector() original_wait_seconds_retry = connector.wait_seconds_retry connector.wait_seconds_retry = 0.1 configurer = RabbitMqEventConfigurerMother.default(connector) event = make_user_created_event() configurer.configure_event(event) bus = RabbitMqEventBusMother.default(connector) connection = connector.get_connection(DEFAULT_EXCHANGE_NAME) connection.close() bus.publish(event) connector.wait_seconds_retry = original_wait_seconds_retry configurer.clear()
def default(main_handler: Callable, connector: RabbitMqConnector = None): connector = RabbitMqConnector() if not connector else connector return RabbitMQEventSubscriber( connector=connector, subscribers={ "auth": ConfigEventSubscriber( organization=DEFAULT_ORGANIZATION, service=DEFAULT_SERVICE, topic=f"{DEFAULT_SERVICE}-event", handler=main_handler, ) }, connection_name="subscriber", )
def with_chaos( chaos: IEventChaos, max_retries: int, logger: ILogger = NotImplementedLogger(), connector: RabbitMqConnector = None, ): connector = RabbitMqConnector() if not connector else connector return RabbitMqEventConsumer( connector, DEFAULT_ORGANIZATION, DEFAULT_SERVICE, max_retries, DEFAULT_VERBOSE, chaos, logger, )
def _given_any_subscriber( given_random_organization, given_random_service, given_random_topic, subscriber_handler: Callable, ): subscriber = RabbitMQEventSubscriber( connector=RabbitMqConnector(), subscribers={ "petisco": ConfigEventSubscriber( organization=given_random_organization, service=given_random_service, topic=given_random_topic, handler=subscriber_handler, ) }, ) return subscriber
def test_should_throw_a_connection_error_exception_when_input_envvars_are_not_valid( ): connector = RabbitMqConnector() original_host = connector.host connector.host = "invalid" with pytest.raises( ConnectionError, match="RabbitMQConnector: Impossible to connect to host*"): connector.get_connection("test") connector.host = original_host
def test_should_throw_a_connection_error_exception_when_retries_and_is_not_possible_to_obtain_an_open_connection( ): connector = RabbitMqConnector() original_wait_seconds_retry = connector.wait_seconds_retry connector.wait_seconds_retry = 0.1 connection = connector.get_connection("test") connection.close() with mock.patch.object(BlockingConnection, "is_open", new_callable=PropertyMock) as mocker_is_open: mocker_is_open.return_value = False with pytest.raises( ConnectionError, match= "RabbitMQConnector: Impossible to obtain a open connection with host*", ): connector.get_connection("test") connector.wait_seconds_retry = original_wait_seconds_retry
#!/usr/bin/env python from meiga import isSuccess from petisco import ( Event, RabbitMQEventSubscriber, RabbitMQEventPublisher, ConfigEventSubscriber, subscriber_handler, RabbitMqConnector, ) a_publisher = RabbitMQEventPublisher( connector=RabbitMqConnector(), organization="acme", service="a", topic=f"a-events" ) b_publisher = RabbitMQEventPublisher( connector=RabbitMqConnector(), organization="acme", service="b", topic=f"b-events" ) @subscriber_handler() def a_requeue(event: Event): print(f"requeue > {event}") a_publisher.publish(event) return isSuccess @subscriber_handler(delay_after=1) def b_requeue(event: Event): print(f"requeue > {event}")
def default(connector: RabbitMqConnector = None): connector = RabbitMqConnector() if not connector else connector return RabbitMQEventPublisher(connector, DEFAULT_ORGANIZATION, DEFAULT_SERVICE, f"{DEFAULT_SERVICE}-event")
ORGANIZATION, SERVICE, MAX_RETRIES, subscribers, event_store, ) from petisco import RabbitMqConnector, RabbitMqEventConsumer, LoggingBasedLogger def get_logger(): def logging_config(): logging.getLogger("pika").setLevel(logging.WARNING) logger = LoggingBasedLogger("example", config=logging_config) return logger connector = RabbitMqConnector() consumer = RabbitMqEventConsumer(connector, ORGANIZATION, SERVICE, MAX_RETRIES, logger=get_logger()) consumer.add_subscribers(subscribers) consumer.add_handler_on_store(event_store) for subscriber in subscribers: print(subscriber) consumer.start()
def default(connector: RabbitMqConnector = None): connector = RabbitMqConnector() if not connector else connector return RabbitMqEventConfigurer(connector, DEFAULT_ORGANIZATION, DEFAULT_SERVICE)
def with_queue_config(queue_config: QueueConfig, connector: RabbitMqConnector = None): connector = RabbitMqConnector() if not connector else connector return RabbitMqEventConfigurer(connector, DEFAULT_ORGANIZATION, DEFAULT_SERVICE, queue_config)
def default(connector: RabbitMqConnector = None): connector = RabbitMqConnector() if not connector else connector return RabbitMqDeclarer( connector=connector, channel_name=f"{DEFAULT_ORGANIZATION}.{DEFAULT_SERVICE}", )
def given_rabbitmq_connector(): return RabbitMqConnector()
def with_info_id(connector: RabbitMqConnector = None): connector = RabbitMqConnector() if not connector else connector return RabbitMqEventBus(connector, DEFAULT_ORGANIZATION, DEFAULT_SERVICE).with_info_id( InfoIdMother.random())
def with_service(service: str, connector: RabbitMqConnector = None): connector = RabbitMqConnector() if not connector else connector return RabbitMqEventBus(connector, DEFAULT_ORGANIZATION, service)
def rabbitmq_event_subscriber_provider() -> RabbitMQEventSubscriber: return RabbitMQEventSubscriber(connector=RabbitMqConnector(), subscribers=subscribers)
def without_retry(connector: RabbitMqConnector = None): connector = RabbitMqConnector() if not connector else connector return RabbitMqEventConsumer(connector, DEFAULT_ORGANIZATION, DEFAULT_SERVICE, 0, DEFAULT_VERBOSE)