1# ------------------------------------------------------------------------- 2# Copyright (c) Microsoft Corporation. All rights reserved. 3# Licensed under the MIT License. See License.txt in the project root for 4# license information. 5# -------------------------------------------------------------------------- 6from azure.common import ( 7 AzureConflictHttpError, 8 AzureHttpError, 9) 10 11from ..common._auth import ( 12 _StorageSASAuthentication, 13 _StorageSharedKeyAuthentication, 14) 15from ..common._common_conversion import ( 16 _int_to_str, 17 _to_str, 18) 19from ..common._connection import _ServiceParameters 20from ..common._constants import ( 21 SERVICE_HOST_BASE, 22 DEFAULT_PROTOCOL, 23) 24from ..common._deserialization import ( 25 _convert_xml_to_service_properties, 26 _convert_xml_to_signed_identifiers, 27 _convert_xml_to_service_stats, 28) 29from ..common._error import ( 30 _dont_fail_not_exist, 31 _dont_fail_on_exist, 32 _validate_not_none, 33 _ERROR_CONFLICT, 34 _ERROR_STORAGE_MISSING_INFO, 35 _validate_access_policies, 36 _validate_encryption_required, 37 _validate_decryption_required, 38) 39from ..common._http import ( 40 HTTPRequest, 41) 42from ..common._serialization import ( 43 _convert_signed_identifiers_to_xml, 44 _convert_service_properties_to_xml, 45) 46from ..common._serialization import ( 47 _get_request_body, 48 _add_metadata_headers, 49) 50from ..common.models import ( 51 Services, 52 ListGenerator, 53 _OperationContext, 54) 55from .sharedaccesssignature import ( 56 QueueSharedAccessSignature, 57) 58from ..common.storageclient import StorageClient 59from ._deserialization import ( 60 _convert_xml_to_queues, 61 _convert_xml_to_queue_messages, 62 _parse_queue_message_from_headers, 63 _parse_metadata_and_message_count, 64) 65from ._serialization import ( 66 _convert_queue_message_xml, 67 _get_path, 68) 69from .models import ( 70 QueueMessageFormat, 71) 72from ._constants import ( 73 X_MS_VERSION, 74 __version__ as package_version, 75) 76 77_HTTP_RESPONSE_NO_CONTENT = 204 78 79 80class QueueService(StorageClient): 81 ''' 82 This is the main class managing queue resources. 83 84 The Queue service stores messages. A queue can contain an unlimited number of 85 messages, each of which can be up to 64KB in size. Messages are generally added 86 to the end of the queue and retrieved from the front of the queue, although 87 first in, first out (FIFO) behavior is not guaranteed. 88 89 :ivar function(data) encode_function: 90 A function used to encode queue messages. Takes as 91 a parameter the data passed to the put_message API and returns the encoded 92 message. Defaults to take text and xml encode, but bytes and other 93 encodings can be used. For example, base64 may be preferable for developing 94 across multiple Azure Storage libraries in different languages. See the 95 :class:`~azure.storage.queue.models.QueueMessageFormat` for xml, base64 and 96 no encoding methods as well as binary equivalents. 97 :ivar function(data) decode_function: 98 A function used to encode decode messages. Takes as 99 a parameter the data returned by the get_messages and peek_messages APIs and 100 returns the decoded message. Defaults to return text and xml decode, but 101 bytes and other decodings can be used. For example, base64 may be preferable 102 for developing across multiple Azure Storage libraries in different languages. 103 See the :class:`~azure.storage.queue.models.QueueMessageFormat` for xml, base64 104 and no decoding methods as well as binary equivalents. 105 :ivar object key_encryption_key: 106 The key-encryption-key optionally provided by the user. If provided, will be used to 107 encrypt/decrypt in supported methods. 108 For methods requiring decryption, either the key_encryption_key OR the resolver must be provided. 109 If both are provided, the resolver will take precedence. 110 Must implement the following methods for APIs requiring encryption: 111 wrap_key(key)--wraps the specified key (bytes) using an algorithm of the user's choice. Returns the encrypted key as bytes. 112 get_key_wrap_algorithm()--returns the algorithm used to wrap the specified symmetric key. 113 get_kid()--returns a string key id for this key-encryption-key. 114 Must implement the following methods for APIs requiring decryption: 115 unwrap_key(key, algorithm)--returns the unwrapped form of the specified symmetric key using the string-specified algorithm. 116 get_kid()--returns a string key id for this key-encryption-key. 117 :ivar function key_resolver_function(kid): 118 A function to resolve keys optionally provided by the user. If provided, will be used to decrypt in supported methods. 119 For methods requiring decryption, either the key_encryption_key OR 120 the resolver must be provided. If both are provided, the resolver will take precedence. 121 It uses the kid string to return a key-encryption-key implementing the interface defined above. 122 :ivar bool require_encryption: 123 A flag that may be set to ensure that all messages successfully uploaded to the queue and all those downloaded and 124 successfully read from the queue are/were encrypted while on the server. If this flag is set, all required 125 parameters for encryption/decryption must be provided. See the above comments on the key_encryption_key and resolver. 126 ''' 127 128 def __init__(self, account_name=None, account_key=None, sas_token=None, is_emulated=False, 129 protocol=DEFAULT_PROTOCOL, endpoint_suffix=SERVICE_HOST_BASE, request_session=None, 130 connection_string=None, socket_timeout=None, token_credential=None): 131 ''' 132 :param str account_name: 133 The storage account name. This is used to authenticate requests 134 signed with an account key and to construct the storage endpoint. It 135 is required unless a connection string is given. 136 :param str account_key: 137 The storage account key. This is used for shared key authentication. 138 :param str sas_token: 139 A shared access signature token to use to authenticate requests 140 instead of the account key. If account key and sas token are both 141 specified, account key will be used to sign. 142 :param bool is_emulated: 143 Whether to use the emulator. Defaults to False. If specified, will 144 override all other parameters besides connection string and request 145 session. 146 :param str protocol: 147 The protocol to use for requests. Defaults to https. 148 :param str endpoint_suffix: 149 The host base component of the url, minus the account name. Defaults 150 to Azure (core.windows.net). Override this to use the China cloud 151 (core.chinacloudapi.cn). 152 :param requests.Session request_session: 153 The session object to use for http requests. 154 :param str connection_string: 155 If specified, this will override all other parameters besides 156 request session. See 157 http://azure.microsoft.com/en-us/documentation/articles/storage-configure-connection-string/ 158 for the connection string format. 159 :param int socket_timeout: 160 If specified, this will override the default socket timeout. The timeout specified is in seconds. 161 See DEFAULT_SOCKET_TIMEOUT in _constants.py for the default value. 162 :param token_credential: 163 A token credential used to authenticate HTTPS requests. The token value 164 should be updated before its expiration. 165 :type `~azure.storage.common.TokenCredential` 166 ''' 167 service_params = _ServiceParameters.get_service_parameters( 168 'queue', 169 account_name=account_name, 170 account_key=account_key, 171 sas_token=sas_token, 172 token_credential=token_credential, 173 is_emulated=is_emulated, 174 protocol=protocol, 175 endpoint_suffix=endpoint_suffix, 176 request_session=request_session, 177 connection_string=connection_string, 178 socket_timeout=socket_timeout) 179 180 super(QueueService, self).__init__(service_params) 181 182 if self.account_key: 183 self.authentication = _StorageSharedKeyAuthentication( 184 self.account_name, 185 self.account_key, 186 self.is_emulated 187 ) 188 elif self.sas_token: 189 self.authentication = _StorageSASAuthentication(self.sas_token) 190 elif self.token_credential: 191 self.authentication = self.token_credential 192 else: 193 raise ValueError(_ERROR_STORAGE_MISSING_INFO) 194 195 self.encode_function = QueueMessageFormat.text_xmlencode 196 self.decode_function = QueueMessageFormat.text_xmldecode 197 self.key_encryption_key = None 198 self.key_resolver_function = None 199 self.require_encryption = False 200 self._X_MS_VERSION = X_MS_VERSION 201 self._update_user_agent_string(package_version) 202 203 def generate_account_shared_access_signature(self, resource_types, permission, 204 expiry, start=None, ip=None, protocol=None): 205 ''' 206 Generates a shared access signature for the queue service. 207 Use the returned signature with the sas_token parameter of QueueService. 208 209 :param ResourceTypes resource_types: 210 Specifies the resource types that are accessible with the account SAS. 211 :param AccountPermissions permission: 212 The permissions associated with the shared access signature. The 213 user is restricted to operations allowed by the permissions. 214 Required unless an id is given referencing a stored access policy 215 which contains this field. This field must be omitted if it has been 216 specified in an associated stored access policy. 217 :param expiry: 218 The time at which the shared access signature becomes invalid. 219 Required unless an id is given referencing a stored access policy 220 which contains this field. This field must be omitted if it has 221 been specified in an associated stored access policy. Azure will always 222 convert values to UTC. If a date is passed in without timezone info, it 223 is assumed to be UTC. 224 :type expiry: datetime or str 225 :param start: 226 The time at which the shared access signature becomes valid. If 227 omitted, start time for this call is assumed to be the time when the 228 storage service receives the request. Azure will always convert values 229 to UTC. If a date is passed in without timezone info, it is assumed to 230 be UTC. 231 :type start: datetime or str 232 :param str ip: 233 Specifies an IP address or a range of IP addresses from which to accept requests. 234 If the IP address from which the request originates does not match the IP address 235 or address range specified on the SAS token, the request is not authenticated. 236 For example, specifying sip=168.1.5.65 or sip=168.1.5.60-168.1.5.70 on the SAS 237 restricts the request to those IP addresses. 238 :param str protocol: 239 Specifies the protocol permitted for a request made. The default value 240 is https,http. See :class:`~azure.storage.common.models.Protocol` for possible values. 241 :return: A Shared Access Signature (sas) token. 242 :rtype: str 243 ''' 244 _validate_not_none('self.account_name', self.account_name) 245 _validate_not_none('self.account_key', self.account_key) 246 247 sas = QueueSharedAccessSignature(self.account_name, self.account_key) 248 return sas.generate_account(Services.QUEUE, resource_types, permission, 249 expiry, start=start, ip=ip, protocol=protocol) 250 251 def generate_queue_shared_access_signature(self, queue_name, 252 permission=None, 253 expiry=None, 254 start=None, 255 id=None, 256 ip=None, protocol=None, ): 257 ''' 258 Generates a shared access signature for the queue. 259 Use the returned signature with the sas_token parameter of QueueService. 260 261 :param str queue_name: 262 The name of the queue to create a SAS token for. 263 :param QueuePermissions permission: 264 The permissions associated with the shared access signature. The 265 user is restricted to operations allowed by the permissions. 266 Required unless an id is given referencing a stored access policy 267 which contains this field. This field must be omitted if it has been 268 specified in an associated stored access policy. 269 :param expiry: 270 The time at which the shared access signature becomes invalid. 271 Required unless an id is given referencing a stored access policy 272 which contains this field. This field must be omitted if it has 273 been specified in an associated stored access policy. Azure will always 274 convert values to UTC. If a date is passed in without timezone info, it 275 is assumed to be UTC. 276 :type expiry: datetime or str 277 :param start: 278 The time at which the shared access signature becomes valid. If 279 omitted, start time for this call is assumed to be the time when the 280 storage service receives the request. Azure will always convert values 281 to UTC. If a date is passed in without timezone info, it is assumed to 282 be UTC. 283 :type start: datetime or str 284 :param str id: 285 A unique value up to 64 characters in length that correlates to a 286 stored access policy. To create a stored access policy, use :func:`~set_queue_acl`. 287 :param str ip: 288 Specifies an IP address or a range of IP addresses from which to accept requests. 289 If the IP address from which the request originates does not match the IP address 290 or address range specified on the SAS token, the request is not authenticated. 291 For example, specifying sip='168.1.5.65' or sip='168.1.5.60-168.1.5.70' on the SAS 292 restricts the request to those IP addresses. 293 :param str protocol: 294 Specifies the protocol permitted for a request made. The default value 295 is https,http. See :class:`~azure.storage.common.models.Protocol` for possible values. 296 :return: A Shared Access Signature (sas) token. 297 :rtype: str 298 ''' 299 _validate_not_none('queue_name', queue_name) 300 _validate_not_none('self.account_name', self.account_name) 301 _validate_not_none('self.account_key', self.account_key) 302 303 sas = QueueSharedAccessSignature(self.account_name, self.account_key) 304 return sas.generate_queue( 305 queue_name, 306 permission=permission, 307 expiry=expiry, 308 start=start, 309 id=id, 310 ip=ip, 311 protocol=protocol, 312 ) 313 314 def get_queue_service_stats(self, timeout=None): 315 ''' 316 Retrieves statistics related to replication for the Queue service. It is 317 only available when read-access geo-redundant replication is enabled for 318 the storage account. 319 320 With geo-redundant replication, Azure Storage maintains your data durable 321 in two locations. In both locations, Azure Storage constantly maintains 322 multiple healthy replicas of your data. The location where you read, 323 create, update, or delete data is the primary storage account location. 324 The primary location exists in the region you choose at the time you 325 create an account via the Azure Management Azure classic portal, for 326 example, North Central US. The location to which your data is replicated 327 is the secondary location. The secondary location is automatically 328 determined based on the location of the primary; it is in a second data 329 center that resides in the same region as the primary location. Read-only 330 access is available from the secondary location, if read-access geo-redundant 331 replication is enabled for your storage account. 332 333 :param int timeout: 334 The timeout parameter is expressed in seconds. 335 :return: The queue service stats. 336 :rtype: :class:`~azure.storage.common.models.ServiceStats` 337 ''' 338 request = HTTPRequest() 339 request.method = 'GET' 340 request.host_locations = self._get_host_locations(primary=False, secondary=True) 341 request.path = _get_path() 342 request.query = { 343 'restype': 'service', 344 'comp': 'stats', 345 'timeout': _int_to_str(timeout), 346 } 347 348 return self._perform_request(request, _convert_xml_to_service_stats) 349 350 def get_queue_service_properties(self, timeout=None): 351 ''' 352 Gets the properties of a storage account's Queue service, including 353 logging, analytics and CORS rules. 354 355 :param int timeout: 356 The server timeout, expressed in seconds. 357 :return: The queue service properties. 358 :rtype: :class:`~azure.storage.common.models.ServiceProperties` 359 ''' 360 request = HTTPRequest() 361 request.method = 'GET' 362 request.host_locations = self._get_host_locations(secondary=True) 363 request.path = _get_path() 364 request.query = { 365 'restype': 'service', 366 'comp': 'properties', 367 'timeout': _int_to_str(timeout), 368 } 369 370 return self._perform_request(request, _convert_xml_to_service_properties) 371 372 def set_queue_service_properties(self, logging=None, hour_metrics=None, 373 minute_metrics=None, cors=None, timeout=None): 374 ''' 375 Sets the properties of a storage account's Queue service, including 376 Azure Storage Analytics. If an element (ex Logging) is left as None, the 377 existing settings on the service for that functionality are preserved. 378 For more information on Azure Storage Analytics, see 379 https://msdn.microsoft.com/en-us/library/azure/hh343270.aspx. 380 381 :param Logging logging: 382 The logging settings provide request logs. 383 :param Metrics hour_metrics: 384 The hour metrics settings provide a summary of request 385 statistics grouped by API in hourly aggregates for queuess. 386 :param Metrics minute_metrics: 387 The minute metrics settings provide request statistics 388 for each minute for queues. 389 :param cors: 390 You can include up to five CorsRule elements in the 391 list. If an empty list is specified, all CORS rules will be deleted, 392 and CORS will be disabled for the service. For detailed information 393 about CORS rules and evaluation logic, see 394 https://msdn.microsoft.com/en-us/library/azure/dn535601.aspx. 395 :type cors: list(:class:`~azure.storage.common.models.CorsRule`) 396 :param int timeout: 397 The server timeout, expressed in seconds. 398 ''' 399 request = HTTPRequest() 400 request.method = 'PUT' 401 request.host_locations = self._get_host_locations() 402 request.path = _get_path() 403 request.query = { 404 'restype': 'service', 405 'comp': 'properties', 406 'timeout': _int_to_str(timeout), 407 } 408 request.body = _get_request_body( 409 _convert_service_properties_to_xml(logging, hour_metrics, minute_metrics, cors)) 410 self._perform_request(request) 411 412 def list_queues(self, prefix=None, num_results=None, include_metadata=False, 413 marker=None, timeout=None): 414 ''' 415 Returns a generator to list the queues. The generator will lazily follow 416 the continuation tokens returned by the service and stop when all queues 417 have been returned or num_results is reached. 418 419 If num_results is specified and the account has more than that number of 420 queues, the generator will have a populated next_marker field once it 421 finishes. This marker can be used to create a new generator if more 422 results are desired. 423 424 :param str prefix: 425 Filters the results to return only queues with names that begin 426 with the specified prefix. 427 :param int num_results: 428 The maximum number of queues to return. 429 :param bool include_metadata: 430 Specifies that container metadata be returned in the response. 431 :param str marker: 432 An opaque continuation token. This value can be retrieved from the 433 next_marker field of a previous generator object if num_results was 434 specified and that generator has finished enumerating results. If 435 specified, this generator will begin returning results from the point 436 where the previous generator stopped. 437 :param int timeout: 438 The server timeout, expressed in seconds. This function may make multiple 439 calls to the service in which case the timeout value specified will be 440 applied to each individual call. 441 ''' 442 include = 'metadata' if include_metadata else None 443 operation_context = _OperationContext(location_lock=True) 444 kwargs = {'prefix': prefix, 'max_results': num_results, 'include': include, 445 'marker': marker, 'timeout': timeout, '_context': operation_context} 446 resp = self._list_queues(**kwargs) 447 448 return ListGenerator(resp, self._list_queues, (), kwargs) 449 450 def _list_queues(self, prefix=None, marker=None, max_results=None, 451 include=None, timeout=None, _context=None): 452 ''' 453 Returns a list of queues under the specified account. Makes a single list 454 request to the service. Used internally by the list_queues method. 455 456 :param str prefix: 457 Filters the results to return only queues with names that begin 458 with the specified prefix. 459 :param str marker: 460 A token which identifies the portion of the query to be 461 returned with the next query operation. The operation returns a 462 next_marker element within the response body if the list returned 463 was not complete. This value may then be used as a query parameter 464 in a subsequent call to request the next portion of the list of 465 queues. The marker value is opaque to the client. 466 :param int max_results: 467 The maximum number of queues to return. A single list request may 468 return up to 1000 queues and potentially a continuation token which 469 should be followed to get additional resutls. 470 :param str include: 471 Include this parameter to specify that the container's 472 metadata be returned as part of the response body. 473 :param int timeout: 474 The server timeout, expressed in seconds. 475 ''' 476 request = HTTPRequest() 477 request.method = 'GET' 478 request.host_locations = self._get_host_locations(secondary=True) 479 request.path = _get_path() 480 request.query = { 481 'comp': 'list', 482 'prefix': _to_str(prefix), 483 'marker': _to_str(marker), 484 'maxresults': _int_to_str(max_results), 485 'include': _to_str(include), 486 'timeout': _int_to_str(timeout) 487 } 488 489 return self._perform_request(request, _convert_xml_to_queues, operation_context=_context) 490 491 def create_queue(self, queue_name, metadata=None, fail_on_exist=False, timeout=None): 492 ''' 493 Creates a queue under the given account. 494 495 :param str queue_name: 496 The name of the queue to create. A queue name must be from 3 through 497 63 characters long and may only contain lowercase letters, numbers, 498 and the dash (-) character. The first and last letters in the queue 499 must be alphanumeric. The dash (-) character cannot be the first or 500 last character. Consecutive dash characters are not permitted in the 501 queue name. 502 :param metadata: 503 A dict containing name-value pairs to associate with the queue as 504 metadata. Note that metadata names preserve the case with which they 505 were created, but are case-insensitive when set or read. 506 :type metadata: dict(str, str) 507 :param bool fail_on_exist: 508 Specifies whether to throw an exception if the queue already exists. 509 :param int timeout: 510 The server timeout, expressed in seconds. 511 :return: 512 A boolean indicating whether the queue was created. If fail_on_exist 513 was set to True, this will throw instead of returning false. 514 :rtype: bool 515 ''' 516 _validate_not_none('queue_name', queue_name) 517 request = HTTPRequest() 518 request.method = 'PUT' 519 request.host_locations = self._get_host_locations() 520 request.path = _get_path(queue_name) 521 request.query = {'timeout': _int_to_str(timeout)} 522 _add_metadata_headers(metadata, request) 523 524 def _return_request(request): 525 return request 526 527 if not fail_on_exist: 528 try: 529 response = self._perform_request(request, parser=_return_request) 530 if response.status == _HTTP_RESPONSE_NO_CONTENT: 531 return False 532 return True 533 except AzureHttpError as ex: 534 _dont_fail_on_exist(ex) 535 return False 536 else: 537 response = self._perform_request(request, parser=_return_request) 538 if response.status == _HTTP_RESPONSE_NO_CONTENT: 539 raise AzureConflictHttpError( 540 _ERROR_CONFLICT.format(response.message), response.status) 541 return True 542 543 def delete_queue(self, queue_name, fail_not_exist=False, timeout=None): 544 ''' 545 Deletes the specified queue and any messages it contains. 546 547 When a queue is successfully deleted, it is immediately marked for deletion 548 and is no longer accessible to clients. The queue is later removed from 549 the Queue service during garbage collection. 550 551 Note that deleting a queue is likely to take at least 40 seconds to complete. 552 If an operation is attempted against the queue while it was being deleted, 553 an :class:`AzureConflictHttpError` will be thrown. 554 555 :param str queue_name: 556 The name of the queue to delete. 557 :param bool fail_not_exist: 558 Specifies whether to throw an exception if the queue doesn't exist. 559 :param int timeout: 560 The server timeout, expressed in seconds. 561 :return: 562 A boolean indicating whether the queue was deleted. If fail_not_exist 563 was set to True, this will throw instead of returning false. 564 :rtype: bool 565 ''' 566 _validate_not_none('queue_name', queue_name) 567 request = HTTPRequest() 568 request.method = 'DELETE' 569 request.host_locations = self._get_host_locations() 570 request.path = _get_path(queue_name) 571 request.query = {'timeout': _int_to_str(timeout)} 572 if not fail_not_exist: 573 try: 574 self._perform_request(request) 575 return True 576 except AzureHttpError as ex: 577 _dont_fail_not_exist(ex) 578 return False 579 else: 580 self._perform_request(request) 581 return True 582 583 def get_queue_metadata(self, queue_name, timeout=None): 584 ''' 585 Retrieves user-defined metadata and queue properties on the specified 586 queue. Metadata is associated with the queue as name-value pairs. 587 588 :param str queue_name: 589 The name of an existing queue. 590 :param int timeout: 591 The server timeout, expressed in seconds. 592 :return: 593 A dictionary representing the queue metadata with an 594 approximate_message_count int property on the dict estimating the 595 number of messages in the queue. 596 :rtype: dict(str, str) 597 ''' 598 _validate_not_none('queue_name', queue_name) 599 request = HTTPRequest() 600 request.method = 'GET' 601 request.host_locations = self._get_host_locations(secondary=True) 602 request.path = _get_path(queue_name) 603 request.query = { 604 'comp': 'metadata', 605 'timeout': _int_to_str(timeout), 606 } 607 608 return self._perform_request(request, _parse_metadata_and_message_count) 609 610 def set_queue_metadata(self, queue_name, metadata=None, timeout=None): 611 ''' 612 Sets user-defined metadata on the specified queue. Metadata is 613 associated with the queue as name-value pairs. 614 615 :param str queue_name: 616 The name of an existing queue. 617 :param dict metadata: 618 A dict containing name-value pairs to associate with the 619 queue as metadata. 620 :param int timeout: 621 The server timeout, expressed in seconds. 622 ''' 623 _validate_not_none('queue_name', queue_name) 624 request = HTTPRequest() 625 request.method = 'PUT' 626 request.host_locations = self._get_host_locations() 627 request.path = _get_path(queue_name) 628 request.query = { 629 'comp': 'metadata', 630 'timeout': _int_to_str(timeout), 631 } 632 _add_metadata_headers(metadata, request) 633 634 self._perform_request(request) 635 636 def exists(self, queue_name, timeout=None): 637 ''' 638 Returns a boolean indicating whether the queue exists. 639 640 :param str queue_name: 641 The name of queue to check for existence. 642 :param int timeout: 643 The server timeout, expressed in seconds. 644 :return: A boolean indicating whether the queue exists. 645 :rtype: bool 646 ''' 647 try: 648 self.get_queue_metadata(queue_name, timeout=timeout) 649 return True 650 except AzureHttpError as ex: 651 _dont_fail_not_exist(ex) 652 return False 653 654 def get_queue_acl(self, queue_name, timeout=None): 655 ''' 656 Returns details about any stored access policies specified on the 657 queue that may be used with Shared Access Signatures. 658 659 :param str queue_name: 660 The name of an existing queue. 661 :param int timeout: 662 The server timeout, expressed in seconds. 663 :return: A dictionary of access policies associated with the queue. 664 :rtype: dict(str, :class:`~azure.storage.common.models.AccessPolicy`) 665 ''' 666 _validate_not_none('queue_name', queue_name) 667 request = HTTPRequest() 668 request.method = 'GET' 669 request.host_locations = self._get_host_locations(secondary=True) 670 request.path = _get_path(queue_name) 671 request.query = { 672 'comp': 'acl', 673 'timeout': _int_to_str(timeout), 674 } 675 676 return self._perform_request(request, _convert_xml_to_signed_identifiers) 677 678 def set_queue_acl(self, queue_name, signed_identifiers=None, timeout=None): 679 ''' 680 Sets stored access policies for the queue that may be used with Shared 681 Access Signatures. 682 683 When you set permissions for a queue, the existing permissions are replaced. 684 To update the queue's permissions, call :func:`~get_queue_acl` to fetch 685 all access policies associated with the queue, modify the access policy 686 that you wish to change, and then call this function with the complete 687 set of data to perform the update. 688 689 When you establish a stored access policy on a queue, it may take up to 690 30 seconds to take effect. During this interval, a shared access signature 691 that is associated with the stored access policy will throw an 692 :class:`AzureHttpError` until the access policy becomes active. 693 694 :param str queue_name: 695 The name of an existing queue. 696 :param signed_identifiers: 697 A dictionary of access policies to associate with the queue. The 698 dictionary may contain up to 5 elements. An empty dictionary 699 will clear the access policies set on the service. 700 :type signed_identifiers: dict(str, :class:`~azure.storage.common.models.AccessPolicy`) 701 :param int timeout: 702 The server timeout, expressed in seconds. 703 ''' 704 _validate_not_none('queue_name', queue_name) 705 _validate_access_policies(signed_identifiers) 706 request = HTTPRequest() 707 request.method = 'PUT' 708 request.host_locations = self._get_host_locations() 709 request.path = _get_path(queue_name) 710 request.query = { 711 'comp': 'acl', 712 'timeout': _int_to_str(timeout), 713 } 714 request.body = _get_request_body( 715 _convert_signed_identifiers_to_xml(signed_identifiers)) 716 self._perform_request(request) 717 718 def put_message(self, queue_name, content, visibility_timeout=None, 719 time_to_live=None, timeout=None): 720 ''' 721 Adds a new message to the back of the message queue. 722 723 The visibility timeout specifies the time that the message will be 724 invisible. After the timeout expires, the message will become visible. 725 If a visibility timeout is not specified, the default value of 0 is used. 726 727 The message time-to-live specifies how long a message will remain in the 728 queue. The message will be deleted from the queue when the time-to-live 729 period expires. 730 731 If the key-encryption-key field is set on the local service object, this method will 732 encrypt the content before uploading. 733 734 :param str queue_name: 735 The name of the queue to put the message into. 736 :param obj content: 737 Message content. Allowed type is determined by the encode_function 738 set on the service. Default is str. The encoded message can be up to 739 64KB in size. 740 :param int visibility_timeout: 741 If not specified, the default value is 0. Specifies the 742 new visibility timeout value, in seconds, relative to server time. 743 The value must be larger than or equal to 0, and cannot be 744 larger than 7 days. The visibility timeout of a message cannot be 745 set to a value later than the expiry time. visibility_timeout 746 should be set to a value smaller than the time-to-live value. 747 :param int time_to_live: 748 Specifies the time-to-live interval for the message, in 749 seconds. The time-to-live may be any positive number or -1 for infinity. If this 750 parameter is omitted, the default time-to-live is 7 days. 751 :param int timeout: 752 The server timeout, expressed in seconds. 753 :return: 754 A :class:`~azure.storage.queue.models.QueueMessage` object. 755 This object is also populated with the content although it is not 756 returned from the service. 757 :rtype: :class:`~azure.storage.queue.models.QueueMessage` 758 ''' 759 760 _validate_encryption_required(self.require_encryption, self.key_encryption_key) 761 762 _validate_not_none('queue_name', queue_name) 763 _validate_not_none('content', content) 764 request = HTTPRequest() 765 request.method = 'POST' 766 request.host_locations = self._get_host_locations() 767 request.path = _get_path(queue_name, True) 768 request.query = { 769 'visibilitytimeout': _to_str(visibility_timeout), 770 'messagettl': _to_str(time_to_live), 771 'timeout': _int_to_str(timeout) 772 } 773 774 request.body = _get_request_body(_convert_queue_message_xml(content, self.encode_function, 775 self.key_encryption_key)) 776 777 message_list = self._perform_request(request, _convert_xml_to_queue_messages, 778 [self.decode_function, False, 779 None, None, content]) 780 return message_list[0] 781 782 def get_messages(self, queue_name, num_messages=None, 783 visibility_timeout=None, timeout=None): 784 ''' 785 Retrieves one or more messages from the front of the queue. 786 787 When a message is retrieved from the queue, the response includes the message 788 content and a pop_receipt value, which is required to delete the message. 789 The message is not automatically deleted from the queue, but after it has 790 been retrieved, it is not visible to other clients for the time interval 791 specified by the visibility_timeout parameter. 792 793 If the key-encryption-key or resolver field is set on the local service object, the messages will be 794 decrypted before being returned. 795 796 :param str queue_name: 797 The name of the queue to get messages from. 798 :param int num_messages: 799 A nonzero integer value that specifies the number of 800 messages to retrieve from the queue, up to a maximum of 32. If 801 fewer are visible, the visible messages are returned. By default, 802 a single message is retrieved from the queue with this operation. 803 :param int visibility_timeout: 804 Specifies the new visibility timeout value, in seconds, relative 805 to server time. The new value must be larger than or equal to 1 806 second, and cannot be larger than 7 days. The visibility timeout of 807 a message can be set to a value later than the expiry time. 808 :param int timeout: 809 The server timeout, expressed in seconds. 810 :return: A :class:`~azure.storage.queue.models.QueueMessage` object representing the information passed. 811 :rtype: list(:class:`~azure.storage.queue.models.QueueMessage`) 812 ''' 813 _validate_decryption_required(self.require_encryption, self.key_encryption_key, 814 self.key_resolver_function) 815 816 _validate_not_none('queue_name', queue_name) 817 request = HTTPRequest() 818 request.method = 'GET' 819 request.host_locations = self._get_host_locations() 820 request.path = _get_path(queue_name, True) 821 request.query = { 822 'numofmessages': _to_str(num_messages), 823 'visibilitytimeout': _to_str(visibility_timeout), 824 'timeout': _int_to_str(timeout) 825 } 826 827 return self._perform_request(request, _convert_xml_to_queue_messages, 828 [self.decode_function, self.require_encryption, 829 self.key_encryption_key, self.key_resolver_function]) 830 831 def peek_messages(self, queue_name, num_messages=None, timeout=None): 832 ''' 833 Retrieves one or more messages from the front of the queue, but does 834 not alter the visibility of the message. 835 836 Only messages that are visible may be retrieved. When a message is retrieved 837 for the first time with a call to get_messages, its dequeue_count property 838 is set to 1. If it is not deleted and is subsequently retrieved again, the 839 dequeue_count property is incremented. The client may use this value to 840 determine how many times a message has been retrieved. Note that a call 841 to peek_messages does not increment the value of DequeueCount, but returns 842 this value for the client to read. 843 844 If the key-encryption-key or resolver field is set on the local service object, the messages will be 845 decrypted before being returned. 846 847 :param str queue_name: 848 The name of the queue to peek messages from. 849 :param int num_messages: 850 A nonzero integer value that specifies the number of 851 messages to peek from the queue, up to a maximum of 32. By default, 852 a single message is peeked from the queue with this operation. 853 :param int timeout: 854 The server timeout, expressed in seconds. 855 :return: 856 A list of :class:`~azure.storage.queue.models.QueueMessage` objects. Note that 857 time_next_visible and pop_receipt will not be populated as peek does 858 not pop the message and can only retrieve already visible messages. 859 :rtype: list(:class:`~azure.storage.queue.models.QueueMessage`) 860 ''' 861 862 _validate_decryption_required(self.require_encryption, self.key_encryption_key, 863 self.key_resolver_function) 864 865 _validate_not_none('queue_name', queue_name) 866 request = HTTPRequest() 867 request.method = 'GET' 868 request.host_locations = self._get_host_locations(secondary=True) 869 request.path = _get_path(queue_name, True) 870 request.query = { 871 'peekonly': 'true', 872 'numofmessages': _to_str(num_messages), 873 'timeout': _int_to_str(timeout) 874 } 875 876 return self._perform_request(request, _convert_xml_to_queue_messages, 877 [self.decode_function, self.require_encryption, 878 self.key_encryption_key, self.key_resolver_function]) 879 880 def delete_message(self, queue_name, message_id, pop_receipt, timeout=None): 881 ''' 882 Deletes the specified message. 883 884 Normally after a client retrieves a message with the get_messages operation, 885 the client is expected to process and delete the message. To delete the 886 message, you must have two items of data: id and pop_receipt. The 887 id is returned from the previous get_messages operation. The 888 pop_receipt is returned from the most recent :func:`~get_messages` or 889 :func:`~update_message` operation. In order for the delete_message operation 890 to succeed, the pop_receipt specified on the request must match the 891 pop_receipt returned from the :func:`~get_messages` or :func:`~update_message` 892 operation. 893 894 :param str queue_name: 895 The name of the queue from which to delete the message. 896 :param str message_id: 897 The message id identifying the message to delete. 898 :param str pop_receipt: 899 A valid pop receipt value returned from an earlier call 900 to the :func:`~get_messages` or :func:`~update_message`. 901 :param int timeout: 902 The server timeout, expressed in seconds. 903 ''' 904 _validate_not_none('queue_name', queue_name) 905 _validate_not_none('message_id', message_id) 906 _validate_not_none('pop_receipt', pop_receipt) 907 request = HTTPRequest() 908 request.method = 'DELETE' 909 request.host_locations = self._get_host_locations() 910 request.path = _get_path(queue_name, True, message_id) 911 request.query = { 912 'popreceipt': _to_str(pop_receipt), 913 'timeout': _int_to_str(timeout) 914 } 915 self._perform_request(request) 916 917 def clear_messages(self, queue_name, timeout=None): 918 ''' 919 Deletes all messages from the specified queue. 920 921 :param str queue_name: 922 The name of the queue whose messages to clear. 923 :param int timeout: 924 The server timeout, expressed in seconds. 925 ''' 926 _validate_not_none('queue_name', queue_name) 927 request = HTTPRequest() 928 request.method = 'DELETE' 929 request.host_locations = self._get_host_locations() 930 request.path = _get_path(queue_name, True) 931 request.query = {'timeout': _int_to_str(timeout)} 932 self._perform_request(request) 933 934 def update_message(self, queue_name, message_id, pop_receipt, visibility_timeout, 935 content=None, timeout=None): 936 ''' 937 Updates the visibility timeout of a message. You can also use this 938 operation to update the contents of a message. 939 940 This operation can be used to continually extend the invisibility of a 941 queue message. This functionality can be useful if you want a worker role 942 to "lease" a queue message. For example, if a worker role calls get_messages 943 and recognizes that it needs more time to process a message, it can 944 continually extend the message's invisibility until it is processed. If 945 the worker role were to fail during processing, eventually the message 946 would become visible again and another worker role could process it. 947 948 If the key-encryption-key field is set on the local service object, this method will 949 encrypt the content before uploading. 950 951 :param str queue_name: 952 The name of the queue containing the message to update. 953 :param str message_id: 954 The message id identifying the message to update. 955 :param str pop_receipt: 956 A valid pop receipt value returned from an earlier call 957 to the :func:`~get_messages` or :func:`~update_message` operation. 958 :param int visibility_timeout: 959 Specifies the new visibility timeout value, in seconds, 960 relative to server time. The new value must be larger than or equal 961 to 0, and cannot be larger than 7 days. The visibility timeout of a 962 message cannot be set to a value later than the expiry time. A 963 message can be updated until it has been deleted or has expired. 964 :param obj content: 965 Message content. Allowed type is determined by the encode_function 966 set on the service. Default is str. 967 :param int timeout: 968 The server timeout, expressed in seconds. 969 :return: 970 A list of :class:`~azure.storage.queue.models.QueueMessage` objects. For convenience, 971 this object is also populated with the content, although it is not returned by the service. 972 :rtype: list(:class:`~azure.storage.queue.models.QueueMessage`) 973 ''' 974 975 _validate_encryption_required(self.require_encryption, self.key_encryption_key) 976 977 _validate_not_none('queue_name', queue_name) 978 _validate_not_none('message_id', message_id) 979 _validate_not_none('pop_receipt', pop_receipt) 980 _validate_not_none('visibility_timeout', visibility_timeout) 981 request = HTTPRequest() 982 request.method = 'PUT' 983 request.host_locations = self._get_host_locations() 984 request.path = _get_path(queue_name, True, message_id) 985 request.query = { 986 'popreceipt': _to_str(pop_receipt), 987 'visibilitytimeout': _int_to_str(visibility_timeout), 988 'timeout': _int_to_str(timeout) 989 } 990 991 if content is not None: 992 request.body = _get_request_body(_convert_queue_message_xml(content, self.encode_function, 993 self.key_encryption_key)) 994 995 return self._perform_request(request, _parse_queue_message_from_headers) 996