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