Пример #1
0
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',
    )
Пример #2
0
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
Пример #3
0
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
Пример #4
0
 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)