Skip to content

Commit 90190a5

Browse files
[ServiceBus] Replace get_*_deadletter_receiver functions with a sub_queue parameter (#13552)
* Remove get_*_deadletter_receiver functions and add a sub_queue parameter to get_*_receiver functions taking enum SubQueue to specify the target subqueue. Adjusts tests, docs accordingly. Co-authored-by: Adam Ling (MSFT) <[email protected]>
1 parent f5d7cc4 commit 90190a5

15 files changed

+148
-308
lines changed

sdk/servicebus/azure-servicebus/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* Remove `is_anonymous_accessible` from management entities.
1717
* Remove `support_ordering` from `create_queue` and `QueueProperties`
1818
* Remove `enable_subscription_partitioning` from `create_topic` and `TopicProperties`
19+
* `get_dead_letter_[queue,subscription]_receiver()` has been removed. To connect to a dead letter queue, utilize the `sub_queue` parameter of `get_[queue,subscription]_receiver()` provided with a value from the `SubQueue` enum
1920

2021
## 7.0.0b5 (2020-08-10)
2122

sdk/servicebus/azure-servicebus/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ with ServiceBusClient.from_connection_string(connstr) as client:
282282

283283
#### [DeadLetter][deadletter_reference]
284284

285-
Transfer the message from the primary queue into a special "dead-letter sub-queue" where it can be accessed using the `ServiceBusClient.get_<queue|subscription>_deadletter_receiver` function and consumed from like any other receiver. (see sample [here](./samples/sync_samples/receive_deadlettered_messages.py))
285+
Transfer the message from the primary queue into a special "dead-letter sub-queue" where it can be accessed using the `ServiceBusClient.get_<queue|subscription>_receiver` function with parameter `sub_queue=SubQueue.DeadLetter` and consumed from like any other receiver. (see sample [here](./samples/sync_samples/receive_deadlettered_messages.py))
286286

287287
```Python
288288
from azure.servicebus import ServiceBusClient

sdk/servicebus/azure-servicebus/azure/servicebus/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from ._servicebus_session import ServiceBusSession
1616
from ._base_handler import ServiceBusSharedKeyCredential
1717
from ._common.message import Message, BatchMessage, PeekMessage, ReceivedMessage
18-
from ._common.constants import ReceiveSettleMode, NEXT_AVAILABLE
18+
from ._common.constants import ReceiveSettleMode, SubQueue
1919
from ._common.auto_lock_renewer import AutoLockRenew
2020

2121
TransportType = constants.TransportType
@@ -26,7 +26,7 @@
2626
'PeekMessage',
2727
'ReceivedMessage',
2828
'ReceiveSettleMode',
29-
'NEXT_AVAILABLE',
29+
'SubQueue',
3030
'ServiceBusClient',
3131
'ServiceBusReceiver',
3232
'ServiceBusSessionReceiver',

sdk/servicebus/azure-servicebus/azure/servicebus/_common/constants.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ class SessionFilter(Enum):
115115
NextAvailable = 0
116116

117117

118+
class SubQueue(Enum):
119+
DeadLetter = 1
120+
TransferDeadLetter = 2
121+
122+
118123
ANNOTATION_SYMBOL_PARTITION_KEY = types.AMQPSymbol(_X_OPT_PARTITION_KEY)
119124
ANNOTATION_SYMBOL_VIA_PARTITION_KEY = types.AMQPSymbol(_X_OPT_VIA_PARTITION_KEY)
120125
ANNOTATION_SYMBOL_SCHEDULED_ENQUEUE_TIME = types.AMQPSymbol(_X_OPT_SCHEDULED_ENQUEUE_TIME)

sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py

Lines changed: 45 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from ._servicebus_session_receiver import ServiceBusSessionReceiver
1414
from ._common._configuration import Configuration
1515
from ._common.utils import create_authentication, generate_dead_letter_entity_name
16+
from ._common.constants import SubQueue
1617

1718
if TYPE_CHECKING:
1819
from azure.core.credentials import TokenCredential
@@ -192,6 +193,9 @@ def get_queue_receiver(self, queue_name, **kwargs):
192193
"""Get ServiceBusReceiver for the specific queue.
193194
194195
:param str queue_name: The path of specific Service Bus Queue the client connects to.
196+
:keyword Optional[SubQueue] sub_queue: If specified, the subqueue this receiver will connect to.
197+
This includes the DeadLetter and TransferDeadLetter queues, holds messages that can't be delivered to any
198+
receiver or messages that can't be processed. The default is None, meaning connect to the primary queue.
195199
:keyword mode: The mode with which messages will be retrieved from the entity. The two options
196200
are PeekLock and ReceiveAndDelete. Messages received with PeekLock must be settled within a given
197201
lock period before they will be removed from the queue. Messages received with ReceiveAndDelete
@@ -222,10 +226,16 @@ def get_queue_receiver(self, queue_name, **kwargs):
222226
223227
224228
"""
229+
sub_queue = kwargs.get('sub_queue', None)
230+
if sub_queue and sub_queue in SubQueue:
231+
queue_name = generate_dead_letter_entity_name(
232+
queue_name=queue_name,
233+
transfer_deadletter=(sub_queue == SubQueue.TransferDeadLetter)
234+
)
225235
# pylint: disable=protected-access
226236
handler = ServiceBusReceiver(
227237
fully_qualified_namespace=self.fully_qualified_namespace,
228-
queue_name=queue_name,
238+
entity_name=queue_name,
229239
credential=self._credential,
230240
logging_enable=self._config.logging_enable,
231241
transport_type=self._config.transport_type,
@@ -237,69 +247,6 @@ def get_queue_receiver(self, queue_name, **kwargs):
237247
self._handlers.append(handler)
238248
return handler
239249

240-
def get_queue_deadletter_receiver(self, queue_name, **kwargs):
241-
# type: (str, Any) -> ServiceBusReceiver
242-
"""Get ServiceBusReceiver for the dead-letter queue which is the secondary subqueue provided by
243-
the specific Queue, it holds messages that can't be delivered to any receiver or messages that can't
244-
be processed.
245-
246-
:param str queue_name: The path of specific Service Bus Queue the client connects to.
247-
:keyword mode: The mode with which messages will be retrieved from the entity. The two options
248-
are PeekLock and ReceiveAndDelete. Messages received with PeekLock must be settled within a given
249-
lock period before they will be removed from the queue. Messages received with ReceiveAndDelete
250-
will be immediately removed from the queue, and cannot be subsequently rejected or re-received if
251-
the client fails to process the message. The default mode is PeekLock.
252-
:paramtype mode: ~azure.servicebus.ReceiveSettleMode
253-
:keyword float max_wait_time: The timeout in seconds between received messages after which the receiver will
254-
automatically stop receiving. The default value is 0, meaning no timeout.
255-
:keyword int retry_total: The total number of attempts to redo a failed operation when an error occurs.
256-
Default value is 3.
257-
:keyword float retry_backoff_factor: Delta back-off internal in the unit of second between retries.
258-
Default value is 0.8.
259-
:keyword float retry_backoff_max: Maximum back-off interval in the unit of second. Default value is 120.
260-
:keyword bool transfer_deadletter: Whether to connect to the transfer dead-letter queue, or the standard
261-
dead-letter queue. The transfer dead-letter queue holds messages that have failed to be transferred in
262-
ForwardTo or SendVia scenarios. Default is False, using the standard dead-letter endpoint.
263-
:keyword int prefetch: The maximum number of messages to cache with each request to the service.
264-
This setting is only for advanced performance tuning. Increasing this value will improve message throughput
265-
performance but increase the chance that messages will expire while they are cached if they're not
266-
processed fast enough.
267-
The default value is 0, meaning messages will be received from the service and processed one at a time.
268-
In the case of prefetch being 0, `ServiceBusReceiver.receive` would try to cache `max_batch_size` (if provided)
269-
within its request to the service.
270-
:rtype: ~azure.servicebus.ServiceBusReceiver
271-
272-
.. admonition:: Example:
273-
274-
.. literalinclude:: ../samples/sync_samples/sample_code_servicebus.py
275-
:start-after: [START create_queue_deadletter_receiver_from_sb_client_sync]
276-
:end-before: [END create_queue_deadletter_receiver_from_sb_client_sync]
277-
:language: python
278-
:dedent: 4
279-
:caption: Create a new instance of the ServiceBusReceiver for Dead Letter Queue from ServiceBusClient.
280-
281-
282-
"""
283-
# pylint: disable=protected-access
284-
entity_name = generate_dead_letter_entity_name(
285-
queue_name=queue_name,
286-
transfer_deadletter=kwargs.get('transfer_deadletter', False)
287-
)
288-
handler = ServiceBusReceiver(
289-
fully_qualified_namespace=self.fully_qualified_namespace,
290-
entity_name=entity_name,
291-
credential=self._credential,
292-
logging_enable=self._config.logging_enable,
293-
transport_type=self._config.transport_type,
294-
http_proxy=self._config.http_proxy,
295-
connection=self._connection,
296-
is_dead_letter_receiver=True,
297-
user_agent=self._config.user_agent,
298-
**kwargs
299-
)
300-
self._handlers.append(handler)
301-
return handler
302-
303250
def get_topic_sender(self, topic_name, **kwargs):
304251
# type: (str, Any) -> ServiceBusSender
305252
"""Get ServiceBusSender for the specific topic.
@@ -343,6 +290,9 @@ def get_subscription_receiver(self, topic_name, subscription_name, **kwargs):
343290
:param str topic_name: The name of specific Service Bus Topic the client connects to.
344291
:param str subscription_name: The name of specific Service Bus Subscription
345292
under the given Service Bus Topic.
293+
:keyword Optional[SubQueue] sub_queue: If specified, the subqueue this receiver will connect to.
294+
This includes the DeadLetter and TransferDeadLetter queues, holds messages that can't be delivered to any
295+
receiver or messages that can't be processed. The default is None, meaning connect to the primary queue.
346296
:keyword mode: The mode with which messages will be retrieved from the entity. The two options
347297
are PeekLock and ReceiveAndDelete. Messages received with PeekLock must be settled within a given
348298
lock period before they will be removed from the subscription. Messages received with ReceiveAndDelete
@@ -377,83 +327,37 @@ def get_subscription_receiver(self, topic_name, subscription_name, **kwargs):
377327
378328
"""
379329
# pylint: disable=protected-access
380-
handler = ServiceBusReceiver(
381-
fully_qualified_namespace=self.fully_qualified_namespace,
382-
topic_name=topic_name,
383-
subscription_name=subscription_name,
384-
credential=self._credential,
385-
logging_enable=self._config.logging_enable,
386-
transport_type=self._config.transport_type,
387-
http_proxy=self._config.http_proxy,
388-
connection=self._connection,
389-
user_agent=self._config.user_agent,
390-
**kwargs
391-
)
392-
self._handlers.append(handler)
393-
return handler
394-
395-
def get_subscription_deadletter_receiver(self, topic_name, subscription_name, **kwargs):
396-
# type: (str, str, Any) -> ServiceBusReceiver
397-
"""Get ServiceBusReceiver for the dead-letter queue which is the secondary subqueue provided by
398-
the specific topic subscription, it holds messages that can't be delivered to any receiver or messages that
399-
can't be processed.
400-
401-
:param str topic_name: The name of specific Service Bus Topic the client connects to.
402-
:param str subscription_name: The name of specific Service Bus Subscription
403-
under the given Service Bus Topic.
404-
:keyword mode: The mode with which messages will be retrieved from the entity. The two options
405-
are PeekLock and ReceiveAndDelete. Messages received with PeekLock must be settled within a given
406-
lock period before they will be removed from the subscription. Messages received with ReceiveAndDelete
407-
will be immediately removed from the subscription, and cannot be subsequently rejected or re-received if
408-
the client fails to process the message. The default mode is PeekLock.
409-
:paramtype mode: ~azure.servicebus.ReceiveSettleMode
410-
:keyword float max_wait_time: The timeout in seconds between received messages after which the receiver will
411-
automatically stop receiving. The default value is 0, meaning no timeout.
412-
:keyword int retry_total: The total number of attempts to redo a failed operation when an error occurs.
413-
Default value is 3.
414-
:keyword float retry_backoff_factor: Delta back-off internal in the unit of second between retries.
415-
Default value is 0.8.
416-
:keyword float retry_backoff_max: Maximum back-off interval in the unit of second. Default value is 120.
417-
:keyword bool transfer_deadletter: Whether to connect to the transfer dead-letter queue, or the standard
418-
dead-letter queue. The transfer dead letter queue holds messages that have failed to be transferred in
419-
ForwardTo or SendVia scenarios. Default is False, using the standard dead-letter endpoint.
420-
:keyword int prefetch: The maximum number of messages to cache with each request to the service.
421-
This setting is only for advanced performance tuning. Increasing this value will improve message throughput
422-
performance but increase the chance that messages will expire while they are cached if they're not
423-
processed fast enough.
424-
The default value is 0, meaning messages will be received from the service and processed one at a time.
425-
In the case of prefetch being 0, `ServiceBusReceiver.receive` would try to cache `max_batch_size` (if provided)
426-
within its request to the service.
427-
:rtype: ~azure.servicebus.ServiceBusReceiver
428-
429-
.. admonition:: Example:
430-
431-
.. literalinclude:: ../samples/sync_samples/sample_code_servicebus.py
432-
:start-after: [START create_subscription_deadletter_receiver_from_sb_client_sync]
433-
:end-before: [END create_subscription_deadletter_receiver_from_sb_client_sync]
434-
:language: python
435-
:dedent: 4
436-
:caption: Create a new instance of the ServiceBusReceiver for Dead Letter Queue from ServiceBusClient.
437-
438-
439-
"""
440-
entity_name = generate_dead_letter_entity_name(
441-
topic_name=topic_name,
442-
subscription_name=subscription_name,
443-
transfer_deadletter=kwargs.get('transfer_deadletter', False)
444-
)
445-
handler = ServiceBusReceiver(
446-
fully_qualified_namespace=self.fully_qualified_namespace,
447-
entity_name=entity_name,
448-
credential=self._credential,
449-
logging_enable=self._config.logging_enable,
450-
transport_type=self._config.transport_type,
451-
http_proxy=self._config.http_proxy,
452-
connection=self._connection,
453-
is_dead_letter_receiver=True,
454-
user_agent=self._config.user_agent,
455-
**kwargs
456-
)
330+
sub_queue = kwargs.get('sub_queue', None)
331+
if sub_queue and sub_queue in SubQueue:
332+
entity_name = generate_dead_letter_entity_name(
333+
topic_name=topic_name,
334+
subscription_name=subscription_name,
335+
transfer_deadletter=(sub_queue == SubQueue.TransferDeadLetter)
336+
)
337+
handler = ServiceBusReceiver(
338+
fully_qualified_namespace=self.fully_qualified_namespace,
339+
entity_name=entity_name,
340+
credential=self._credential,
341+
logging_enable=self._config.logging_enable,
342+
transport_type=self._config.transport_type,
343+
http_proxy=self._config.http_proxy,
344+
connection=self._connection,
345+
user_agent=self._config.user_agent,
346+
**kwargs
347+
)
348+
else:
349+
handler = ServiceBusReceiver(
350+
fully_qualified_namespace=self.fully_qualified_namespace,
351+
topic_name=topic_name,
352+
subscription_name=subscription_name,
353+
credential=self._credential,
354+
logging_enable=self._config.logging_enable,
355+
transport_type=self._config.transport_type,
356+
http_proxy=self._config.http_proxy,
357+
connection=self._connection,
358+
user_agent=self._config.user_agent,
359+
**kwargs
360+
)
457361
self._handlers.append(handler)
458362
return handler
459363

0 commit comments

Comments
 (0)