-
Notifications
You must be signed in to change notification settings - Fork 204
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implementation of Simple Consumer for Python Client (#588)
* finish simple_consumer * fix style issues * delete private info * convert comments to English * add state enum & change_invisible_duration * extract example * add more tests * fix style issue
- Loading branch information
1 parent
20fd6fb
commit d450648
Showing
11 changed files
with
830 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# Licensed to the Apache Software Foundation (ASF) under one or more | ||
# contributor license agreements. See the NOTICE file distributed with | ||
# this work for additional information regarding copyright ownership. | ||
# The ASF licenses this file to You under the Apache License, Version 2.0 | ||
# (the "License"); you may not use this file except in compliance with | ||
# the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import asyncio | ||
|
||
from rocketmq.client_config import ClientConfig | ||
from rocketmq.filter_expression import FilterExpression | ||
from rocketmq.log import logger | ||
from rocketmq.protocol.definition_pb2 import Resource | ||
from rocketmq.rpc_client import Endpoints | ||
from rocketmq.session_credentials import (SessionCredentials, | ||
SessionCredentialsProvider) | ||
from rocketmq.simple_consumer import SimpleConsumer | ||
|
||
|
||
async def test(): | ||
credentials = SessionCredentials("username", "password") | ||
credentials_provider = SessionCredentialsProvider(credentials) | ||
client_config = ClientConfig( | ||
endpoints=Endpoints("endpoint"), | ||
session_credentials_provider=credentials_provider, | ||
ssl_enabled=True, | ||
) | ||
topic = Resource() | ||
topic.name = "normal_topic" | ||
|
||
consumer_group = "yourConsumerGroup" | ||
subscription = {topic.name: FilterExpression("*")} | ||
simple_consumer = (await SimpleConsumer.Builder() | ||
.set_client_config(client_config) | ||
.set_consumer_group(consumer_group) | ||
.set_await_duration(15) | ||
.set_subscription_expression(subscription) | ||
.build()) | ||
logger.info(simple_consumer) | ||
# while True: | ||
message_views = await simple_consumer.receive(16, 15) | ||
logger.info(message_views) | ||
for message in message_views: | ||
logger.info(message.body) | ||
logger.info(f"Received a message, topic={message.topic}, message-id={message.message_id}, body-size={len(message.body)}") | ||
await simple_consumer.ack(message) | ||
logger.info(f"Message is acknowledged successfully, message-id={message.message_id}") | ||
|
||
if __name__ == "__main__": | ||
asyncio.run(test()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# Licensed to the Apache Software Foundation (ASF) under one or more | ||
# contributor license agreements. See the NOTICE file distributed with | ||
# this work for additional information regarding copyright ownership. | ||
# The ASF licenses this file to You under the Apache License, Version 2.0 | ||
# (the "License"); you may not use this file except in compliance with | ||
# the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import re | ||
from typing import List | ||
|
||
from filter_expression import ExpressionType | ||
from google.protobuf.duration_pb2 import Duration | ||
from message import MessageView | ||
from rocketmq.client import Client | ||
from rocketmq.protocol.definition_pb2 import \ | ||
FilterExpression as ProtoFilterExpression | ||
from rocketmq.protocol.definition_pb2 import FilterType | ||
from rocketmq.protocol.definition_pb2 import Resource as ProtoResource | ||
from rocketmq.protocol.service_pb2 import \ | ||
ReceiveMessageRequest as ProtoReceiveMessageRequest | ||
|
||
|
||
class ReceiveMessageResult: | ||
def __init__(self, endpoints, messages: List['MessageView']): | ||
self.endpoints = endpoints | ||
self.messages = messages | ||
|
||
|
||
class Consumer(Client): | ||
CONSUMER_GROUP_REGEX = re.compile(r"^[%a-zA-Z0-9_-]+$") | ||
|
||
def __init__(self, client_config, consumer_group): | ||
super().__init__(client_config) | ||
self.consumer_group = consumer_group | ||
|
||
async def receive_message(self, request, mq, await_duration): | ||
tolerance = self.client_config.request_timeout | ||
timeout = tolerance + await_duration | ||
results = await self.client_manager.receive_message(mq.broker.endpoints, request, timeout) | ||
|
||
messages = [MessageView.from_protobuf(message, mq) for message in results] | ||
return ReceiveMessageResult(mq.broker.endpoints, messages) | ||
|
||
@staticmethod | ||
def _wrap_filter_expression(filter_expression): | ||
filter_type = FilterType.TAG | ||
if filter_expression.type == ExpressionType.Sql92: | ||
filter_type = FilterType.SQL | ||
return ProtoFilterExpression( | ||
type=filter_type, | ||
expression=filter_expression.expression | ||
) | ||
|
||
def wrap_receive_message_request(self, batch_size, mq, filter_expression, await_duration, invisible_duration): | ||
group = ProtoResource() | ||
group.name = self.consumer_group | ||
return ProtoReceiveMessageRequest( | ||
group=group, | ||
message_queue=mq.to_protobuf(), | ||
filter_expression=self._wrap_filter_expression(filter_expression), | ||
long_polling_timeout=Duration(seconds=await_duration), | ||
batch_size=batch_size, | ||
auto_renew=False, | ||
invisible_duration=Duration(seconds=invisible_duration) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# Licensed to the Apache Software Foundation (ASF) under one or more | ||
# contributor license agreements. See the NOTICE file distributed with | ||
# this work for additional information regarding copyright ownership. | ||
# The ASF licenses this file to You under the Apache License, Version 2.0 | ||
# (the "License"); you may not use this file except in compliance with | ||
# the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
from enum import Enum | ||
|
||
|
||
class ExpressionType(Enum): | ||
Tag = 1 | ||
Sql92 = 2 | ||
|
||
|
||
class FilterExpression: | ||
def __init__(self, expression, expression_type=ExpressionType.Tag): | ||
self._expression = expression | ||
self._type = expression_type | ||
|
||
@property | ||
def type(self): | ||
return self._type | ||
|
||
@property | ||
def expression(self): | ||
return self._expression |
Oops, something went wrong.