def to_cps_subscribe_message(source: SequencedMessage) -> PubsubMessage:
    source_pb = source._pb
    out_pb = _to_cps_publish_message_proto(source_pb.message)
    out_pb.publish_time.CopyFrom(source_pb.publish_time)
    out = PubsubMessage()
    out._pb = out_pb
    return out
 def callback(message: PubsubMessage):
     message_data = message.data.decode("utf-8")
     metadata = MessageMetadata.decode(message.message_id)
     print(
         f"Received {message_data} of ordering key {message.ordering_key} with id {metadata}."
     )
     message.ack()
def test_messages_received(subscriber: SubscriberImpl, async_subscriber,
                           message_callback, close_callback):
    message1 = Message(PubsubMessage(message_id="1")._pb, "", 0, None)
    message2 = Message(PubsubMessage(message_id="2")._pb, "", 0, None)

    counter = Box[int]()
    counter.val = 0

    async def on_read() -> Message:
        counter.val += 1
        if counter.val == 1:
            return message1
        if counter.val == 2:
            return message2
        await sleep_forever()

    async_subscriber.read.side_effect = on_read

    results = Queue()
    message_callback.side_effect = lambda m: results.put(m.message_id)

    subscriber.add_close_callback(close_callback)
    subscriber.__enter__()
    assert results.get() == "1"
    assert results.get() == "2"
    subscriber.close()
async def test_iterator(
    default_subscriber,
    subscriber_factory,
    multiplexed_client: AsyncSubscriberClientInterface,
):
    read_queues = wire_queues(default_subscriber.read)
    subscription = SubscriptionPath(1, CloudZone.parse("us-central1-a"), "abc")
    message = Message(PubsubMessage(message_id="1")._pb, "", 0, None)
    async with multiplexed_client:
        iterator = await multiplexed_client.subscribe(
            subscription, DISABLED_FLOW_CONTROL
        )
        subscriber_factory.assert_has_calls(
            [call(subscription, None, DISABLED_FLOW_CONTROL)]
        )
        read_fut_1 = asyncio.ensure_future(iterator.__anext__())
        assert not read_fut_1.done()
        await read_queues.called.get()
        default_subscriber.read.assert_has_calls([call()])
        await read_queues.results.put(message)
        assert await read_fut_1 is message
        read_fut_2 = asyncio.ensure_future(iterator.__anext__())
        assert not read_fut_2.done()
        await read_queues.called.get()
        default_subscriber.read.assert_has_calls([call(), call()])
        await read_queues.results.put(FailedPrecondition(""))
        with pytest.raises(FailedPrecondition):
            await read_fut_2
        default_subscriber.__aexit__.assert_called_once()
def test_subscribe_transform_correct():
    expected = PubsubMessage(
        data=b"xyz",
        ordering_key="def",
        attributes={
            "x": "abc",
            "y": "abc",
            PUBSUB_LITE_EVENT_TIME: encode_attribute_event_time(
                Timestamp(seconds=55).ToDatetime()
            ),
        },
        publish_time=Timestamp(seconds=10),
    )
    result = to_cps_subscribe_message(
        SequencedMessage(
            message=PubSubMessage(
                data=b"xyz",
                key=b"def",
                event_time=Timestamp(seconds=55),
                attributes={
                    "x": AttributeValues(values=[b"abc"]),
                    "y": AttributeValues(values=[b"abc"]),
                },
            ),
            publish_time=Timestamp(seconds=10),
            cursor=Cursor(offset=10),
            size_bytes=10,
        )
    )
    assert result == expected
def test_publish_invalid_event_time():
    with pytest.raises(InvalidArgument):
        from_cps_publish_message(
            PubsubMessage(
                attributes={PUBSUB_LITE_EVENT_TIME: "probably not an encoded proto"}
            )
        )
def test_wrapped_successful():
    wrapped = add_id_to_cps_subscribe_transformer(
        Partition(1), MessageTransformer.of_callable(to_cps_subscribe_message)
    )
    expected = PubsubMessage(
        data=b"xyz",
        ordering_key="def",
        attributes={
            "x": "abc",
            "y": "abc",
            PUBSUB_LITE_EVENT_TIME: encode_attribute_event_time(
                Timestamp(seconds=55).ToDatetime()
            ),
        },
        message_id=MessageMetadata(Partition(1), Cursor(offset=10)).encode(),
        publish_time=Timestamp(seconds=10),
    )
    result = wrapped.transform(
        SequencedMessage(
            message=PubSubMessage(
                data=b"xyz",
                key=b"def",
                event_time=Timestamp(seconds=55),
                attributes={
                    "x": AttributeValues(values=[b"abc"]),
                    "y": AttributeValues(values=[b"abc"]),
                },
            ),
            publish_time=Timestamp(seconds=10),
            cursor=Cursor(offset=10),
            size_bytes=10,
        )
    )
    assert result == expected
Example #8
0
 async def publish(self,
                   data: bytes,
                   ordering_key: str = "",
                   **attrs: Mapping[str, str]) -> str:
     cps_message = PubsubMessage(data=data,
                                 ordering_key=ordering_key,
                                 attributes=attrs)
     psl_message = from_cps_publish_message(cps_message)
     return (await self._publisher.publish(psl_message)).encode()
Example #9
0
async def test_delivery_from_multiple(subscriber, assigner,
                                      subscriber_factory):
    assign_queues = wire_queues(assigner.get_assignment)
    async with subscriber:
        await assign_queues.called.get()
        sub1 = mock_async_context_manager(
            MagicMock(spec=AsyncSingleSubscriber))
        sub2 = mock_async_context_manager(
            MagicMock(spec=AsyncSingleSubscriber))
        sub1_queues = wire_queues(sub1.read)
        sub2_queues = wire_queues(sub2.read)
        subscriber_factory.side_effect = (
            lambda partition: sub1 if partition == Partition(1) else sub2)
        await assign_queues.results.put({Partition(1), Partition(2)})
        await sub1_queues.results.put(
            Message(PubsubMessage(message_id="1")._pb, "", 0, None))
        await sub2_queues.results.put(
            Message(PubsubMessage(message_id="2")._pb, "", 0, None))
        message_ids: Set[str] = set()
        message_ids.add((await subscriber.read()).message_id)
        message_ids.add((await subscriber.read()).message_id)
        assert message_ids == {"1", "2"}
def publish_message(publisher, topic_name, message):
    project_id = os.environ[GOOGLE_CLOUD_PROJECT]
    if not topic_name:
        raise Exception(
            f"env var TOPIC_DISPATCHER is badly set. It's current value is: {topic_name}"
        )
    if not project_id:
        raise Exception(
            f"env var GOOGLE_CLOUD_PROJECT is badly set. It's current value is: {project_id}"
        )
    topic_path = f"projects/{project_id}/topics/{topic_name}"

    message_json = json.dumps(message)
    encoded_message = message_json.encode("utf-8")
    message_obj = PubsubMessage(data=encoded_message)
    future = publisher.publish(topic=topic_path, messages=[message_obj])
    try:
        return future.result()
    except AttributeError as ae:
        print(f"AttributeError on future.result. future is {future}")
def test_wrapped_sets_id_error():
    wrapped = add_id_to_cps_subscribe_transformer(
        Partition(1),
        MessageTransformer.of_callable(lambda x: PubsubMessage(message_id="a")),
    )
    with pytest.raises(InvalidArgument):
        wrapped.transform(
            SequencedMessage(
                message=PubSubMessage(
                    data=b"xyz",
                    key=b"def",
                    event_time=Timestamp(seconds=55),
                    attributes={
                        "x": AttributeValues(values=[b"abc"]),
                        "y": AttributeValues(values=[b"abc"]),
                    },
                ),
                publish_time=Timestamp(seconds=10),
                cursor=Cursor(offset=10),
                size_bytes=10,
            )
        )
def test_publish_valid_transform():
    now = datetime.datetime.now()
    expected = PubSubMessage(
        data=b"xyz",
        key=b"def",
        event_time=now,
        attributes={
            "x": AttributeValues(values=[b"abc"]),
            "y": AttributeValues(values=[b"abc"]),
        },
    )
    result = from_cps_publish_message(
        PubsubMessage(
            data=b"xyz",
            ordering_key="def",
            attributes={
                "x": "abc",
                "y": "abc",
                PUBSUB_LITE_EVENT_TIME: encode_attribute_event_time(now),
            },
        )
    )
    assert result == expected
Example #13
0
def to_cps_publish_message(source: PubSubMessage) -> PubsubMessage:
    out = PubsubMessage()
    try:
        out.ordering_key = source.key.decode("utf-8")
    except UnicodeError:
        raise InvalidArgument(
            "Received an unparseable message with a non-utf8 key.")
    if PUBSUB_LITE_EVENT_TIME in source.attributes:
        raise InvalidArgument(
            "Special timestamp attribute exists in wire message. Unable to parse message."
        )
    out.data = source.data
    for key, values in source.attributes.items():
        out.attributes[key] = _parse_attributes(values)
    if "event_time" in source:
        out.attributes[PUBSUB_LITE_EVENT_TIME] = encode_attribute_event_time(
            source.event_time)
    return out
def create_fake_message(
        message_data,
        ack_id="ACK_ID",
        message_id="MESSAGE_ID",
        timestamp_epoch_seconds=int(time.time())
) -> ReceivedMessage:
    publish_time_timestamp = Timestamp()
    publish_time_timestamp.seconds = timestamp_epoch_seconds

    pubsub_message = PubsubMessage()
    pubsub_message.data = message_data.encode("UTF-8")
    pubsub_message.message_id = message_id
    pubsub_message.publish_time = publish_time_timestamp
    pubsub_message.ordering_key = ""

    received_message = ReceivedMessage()
    received_message.ack_id = ack_id
    received_message.message = pubsub_message
    received_message.delivery_attempt = 0

    return received_message
Example #15
0
def transformer():
    result = MagicMock(spec=MessageTransformer)
    result.transform.side_effect = lambda source: PubsubMessage(message_id=str(
        source.cursor.offset))
    return result
def to_cps_publish_message(source: PubSubMessage) -> PubsubMessage:
    out = PubsubMessage()
    out._pb = _to_cps_publish_message_proto(source._pb)
    return out