def message_patch(reference): """ --- patch: parameters: - in: path name: reference schema: type: string required: true requestBody: content: application/json: schema: MessageSchema responses: 200: description: Update a message content: application/json: schema: MessageSchema """ # TODO: auth json_payload = request.get_json(silent=True) if not json_payload or not isinstance(json_payload, dict): raise MessageDataEmptyError() status = json_payload.get(STATUS_KEY) if status and status not in FINAL_STATUSES: raise UnexpectedMessageStatusError(json_payload.get('status'), FINAL_STATUSES + [None]) repo = MessageLakeRepo(Config.MESSAGE_LAKE_CONN) publish_notifications_repo = NotificationsRepo( Config.PUBLISH_NOTIFICATIONS_REPO_CONN) use_case = PatchMessageMetadataUseCase(repo, publish_notifications_repo) try: message = use_case.execute(reference, json_payload) except UseCaseError as e: raise e except Exception as e: if e.__class__.__name__ == 'NoSuchKey': message = None else: # logging.exception(e) # we have a handler to catch this exception # but in future it will be easier to decide # what kind of info we want to put here raise InternalServerError(e) if not message: raise MessageNotFoundError(reference) return Response( json.dumps(message, cls=ser.MessageJSONEncoder), status=HTTPStatus.OK, mimetype='application/json', )
def test(): # testing predicate in url search delivery_outbox_repo = DeliveryOutboxRepo(DELIVERY_OUTBOX_REPO_CONF) notifications_repo = NotificationsRepo(NOTIFICATIONS_REPO_CONF) subscriptions_repo = SubscriptionsRepo(SUBSCRIPTIONS_REPO_CONF) delivery_outbox_repo._unsafe_clear_for_test() notifications_repo._unsafe_clear_for_test() subscriptions_repo._unsafe_clear_for_test() assert notifications_repo._unsafe_is_empty_for_test() assert delivery_outbox_repo._unsafe_is_empty_for_test() assert subscriptions_repo._unsafe_is_empty_for_test() processor = CallbacksSpreaderProcessor( notifications_repo_conf=NOTIFICATIONS_REPO_CONF, delivery_outbox_repo_conf=DELIVERY_OUTBOX_REPO_CONF, subscriptions_repo_conf=SUBSCRIPTIONS_REPO_CONF) # testing that iter returns processor assert iter(processor) is processor # assert processor has nothing to do assert next(processor) is None _fill_subscriptions_repo(subscriptions_repo, SUBSCRIPTIONS) for prefix, subscriptions in SUBSCRIPTIONS_WITH_COMMON_PREFIXES.items(): _fill_subscriptions_repo(subscriptions_repo, subscriptions) # testing that subscriptions repod doesn't have side effect on processor assert next(processor) is None # testing callbacks spreading for predicates without common prefixes for predicate, number_of_subscribers in SUBSCRIPTIONS.items(): # pushing notification message = _generate_msg_object(predicate=predicate) notifications_repo.post_job(message) # test proccessor received notification assert next(processor) is True # test processor created correct number of delivery jobs # each subscriptions group has unique topic/predicate for i in range(number_of_subscribers): job = delivery_outbox_repo.get_job() assert job, f"Call:{i+1}. Predicate:{predicate}" message_queue_id, payload = job # test that only direct subscribers received this message assert payload.get('payload', {}).get('predicate') == predicate # testing that only correct subscribers will receive notification url = payload.get('s', '') assert _is_predicate_in_url(url, predicate), { 'url': url, 'predicate': predicate } assert delivery_outbox_repo.delete(message_queue_id) # test queue is empty assert not delivery_outbox_repo.get_job() # processor completed the job assert next(processor) is None for prefix, subscriptions in SUBSCRIPTIONS_WITH_COMMON_PREFIXES.items(): # finding longest predicate in the group + total number of expected # delivery jobs expect_jobs = 0 longest_predicate = "" for predicate, number_of_subscribers in subscriptions.items(): if len(longest_predicate) < len(predicate): longest_predicate = predicate expect_jobs += number_of_subscribers # posting notification message = _generate_msg_object(predicate=longest_predicate) assert notifications_repo.post_job(message) assert next(processor) is True # testing processor created the correct number of delivery jobs for i in range(expect_jobs): job = delivery_outbox_repo.get_job() assert job message_queue_id, payload = job # test that only direct subscribers received this message assert payload.get('payload', {}).get('predicate') == longest_predicate # testing that only correct subscribers will receive notification url = payload.get('s', '') assert _is_predicate_in_url(url, prefix), { 'url': url, 'prefix': prefix } assert delivery_outbox_repo.delete(message_queue_id) assert next(processor) is None
def test(): # creating testing versions of all required repos message_lake_repo = MessageLakeRepo(MESSAGE_LAKE_REPO_CONF) object_acl_repo = ObjectACLRepo(OBJECT_ACL_REPO_CONF) bc_inbox_repo = BCInboxRepo(BC_INBOX_REPO_CONF) object_retrieval_repo = ObjectRetrievalRepo(OBJECT_RETRIEVAL_REPO_CONF) notifications_repo = NotificationsRepo(NOTIFICATIONS_REPO_CONF) blockchain_outbox_repo = ApiOutboxRepo(BLOCKCHAIN_OUTBOX_REPO_CONF) def clear(): # clearing repos message_lake_repo._unsafe_method__clear() object_acl_repo._unsafe_method__clear() bc_inbox_repo._unsafe_method__clear() object_retrieval_repo._unsafe_method__clear() notifications_repo._unsafe_method__clear() blockchain_outbox_repo._unsafe_method__clear() # test repos are empty assert message_lake_repo.is_empty() assert object_acl_repo.is_empty() assert bc_inbox_repo.is_empty() assert object_retrieval_repo.is_empty() assert notifications_repo.is_empty() assert blockchain_outbox_repo.is_empty() clear() processor = InboundMessageProcessor( bc_inbox_repo_conf=BC_INBOX_REPO_CONF, message_lake_repo_conf=MESSAGE_LAKE_REPO_CONF, object_acl_repo_conf=OBJECT_ACL_REPO_CONF, object_retrieval_repo_conf=OBJECT_RETRIEVAL_REPO_CONF, notifications_repo_conf=NOTIFICATIONS_REPO_CONF, blockchain_outbox_repo_conf=BLOCKCHAIN_OUTBOX_REPO_CONF) # test iter processor returns processor assert iter(processor) is processor # test processor has no jobs assert next(processor) is None sender_ref = "AU:xxxx-xxxx-xxxx" status = 'received' message = _generate_msg_object(sender_ref=sender_ref, status=status) message.sender = "CN" assert bc_inbox_repo.post(message) # testing normal execution received message with sender ref assert next(processor) is True assert next(processor) is None # testing that message is deleted assert bc_inbox_repo.is_empty() # testing message posted to related repos assert not message_lake_repo.is_empty() assert not object_acl_repo.is_empty() # we can't say it's empty because worker gets values from there # assert not object_retrieval_repo.is_empty() # received status should not be posted to blockchain assert blockchain_outbox_repo.is_empty() clear() sender_ref = "AU:xxxx-xxxx-xxxx" # this one should go to blockchain outbox status = 'pending' message = _generate_msg_object(sender_ref=sender_ref, status=status) message.sender = OUR_JRD message.receiver = 'CN' assert bc_inbox_repo.post(message) # testing normal execution received message with sender ref assert next(processor) is True assert next(processor) is None # testing that message is deleted assert bc_inbox_repo.is_empty() # testing message posted to related repos assert not message_lake_repo.is_empty() assert not object_acl_repo.is_empty() clear() # message without sender ref should fail message = _generate_msg_object() assert bc_inbox_repo.post(message) assert next(processor) is False assert next(processor) is None
def _prepare_notifications_repo(self, conf): notifications_repo_conf = env_queue_config('PROC_OBJ_OUTBOX_REPO') if conf: notifications_repo_conf.update(conf) self.notifications_repo = NotificationsRepo(notifications_repo_conf)