def __init__(self, service_namespace=None, account_key=None, issuer=None, x_ms_version='2011-06-01', host_base=SERVICE_BUS_HOST_BASE): #x_ms_version is not used, but the parameter is kept for backwards compatibility self.requestid = None self.service_namespace = service_namespace self.account_key = account_key self.issuer = issuer self.host_base = host_base #get service namespace, account key and issuer. If they are set when constructing, then use them. #else find them from environment variables. if not service_namespace: if os.environ.has_key(AZURE_SERVICEBUS_NAMESPACE): self.service_namespace = os.environ[AZURE_SERVICEBUS_NAMESPACE] if not account_key: if os.environ.has_key(AZURE_SERVICEBUS_ACCESS_KEY): self.account_key = os.environ[AZURE_SERVICEBUS_ACCESS_KEY] if not issuer: if os.environ.has_key(AZURE_SERVICEBUS_ISSUER): self.issuer = os.environ[AZURE_SERVICEBUS_ISSUER] if not self.service_namespace or not self.account_key or not self.issuer: raise WindowsAzureError( 'You need to provide servicebus namespace, access key and Issuer' ) self._httpclient = _HTTPClient(service_instance=self, service_namespace=service_namespace, account_key=account_key, issuer=issuer) self._filter = self._httpclient.perform_request
def __init__(self, account_name=None, account_key=None, protocol='https', host_base=QUEUE_SERVICE_HOST_BASE, dev_host=DEV_QUEUE_HOST, timeout=DEFAULT_HTTP_TIMEOUT, sas_token=None): ''' account_name: your storage account name, required for all operations. account_key: your storage account key, required for all operations. protocol: Optional. Protocol. Defaults to http. host_base: Optional. Live host base url. Defaults to Azure url. Override this for on-premise. dev_host: Optional. Dev host url. Defaults to localhost. timeout: Optional. Timeout for the http request, in seconds. sas_token: Optional. Token to use to authenticate with shared access signature. ''' super(QueueService, self).__init__( account_name, account_key, protocol, host_base, dev_host, timeout, sas_token) if self.account_key: self.authentication = StorageSharedKeyAuthentication( self.account_name, self.account_key, ) elif self.sas_token: self.authentication = StorageSASAuthentication(self.sas_token) else: raise WindowsAzureError(_ERROR_STORAGE_MISSING_INFO)
def __init__(self, subscription_id=None, cert_file=None, host=MANAGEMENT_HOST): self.requestid = None self.subscription_id = subscription_id self.cert_file = cert_file self.host = host if not self.cert_file: if os.environ.has_key(AZURE_MANAGEMENT_CERTFILE): self.cert_file = os.environ[AZURE_MANAGEMENT_CERTFILE] if not self.subscription_id: if os.environ.has_key(AZURE_MANAGEMENT_SUBSCRIPTIONID): self.subscription_id = os.environ[ AZURE_MANAGEMENT_SUBSCRIPTIONID] if not self.cert_file or not self.subscription_id: raise WindowsAzureError( 'You need to provide subscription id and certificate file') self._httpclient = _HTTPClient(service_instance=self, cert_file=self.cert_file) self._filter = self._httpclient.perform_request
def __init__(self, subscription_id=None, cert_file=None, host=MANAGEMENT_HOST, request_session=None, timeout=DEFAULT_HTTP_TIMEOUT): self.requestid = None self.subscription_id = subscription_id self.cert_file = cert_file self.host = host self.request_session = request_session self.x_ms_version = X_MS_VERSION self.content_type = 'application/atom+xml;type=entry;charset=utf-8' if not self.cert_file and not request_session: if AZURE_MANAGEMENT_CERTFILE in os.environ: self.cert_file = os.environ[AZURE_MANAGEMENT_CERTFILE] if not self.subscription_id: if AZURE_MANAGEMENT_SUBSCRIPTIONID in os.environ: self.subscription_id = os.environ[ AZURE_MANAGEMENT_SUBSCRIPTIONID] if not self.request_session: if not self.cert_file or not self.subscription_id: raise WindowsAzureError( 'You need to provide subscription id and certificate file') self._httpclient = _HTTPClient(service_instance=self, cert_file=self.cert_file, request_session=self.request_session, timeout=timeout) self._filter = self._httpclient.perform_request
def _storage_error_handler(http_error): ''' Simple error handler for storage service. Will add more specific cases ''' if http_error.status == 409: raise WindowsAzureConflictError(azure._ERROR_CONFLICT) elif http_error.status == 404: raise WindowsAzureMissingResourceError(azure._ERROR_NOT_FOUND) else: raise WindowsAzureError(azure._ERROR_UNKNOWN % http_error.message)
def unlock(self): ''' Unlocks itself if find queue name or topic name and subscription name. ''' if self._queue_name: self.service_bus_service.unlock_queue_message(self._queue_name, self.broker_properties['SequenceNumber'], self.broker_properties['LockToken']) elif self._topic_name and self._subscription_name: self.service_bus_service.unlock_subscription_message(self._topic_name, self._subscription_name, self.broker_properties['SequenceNumber'], self.broker_properties['LockToken']) else: raise WindowsAzureError(azure._ERROR_MESSAGE_NOT_PEEK_LOCKED_ON_UNLOCK)
def delete(self): ''' Deletes itself if find queue name or topic name and subscription name. ''' if self._queue_name: self.service_bus_service.delete_queue_message(self._queue_name, self.broker_properties['SequenceNumber'], self.broker_properties['LockToken']) elif self._topic_name and self._subscription_name: self.service_bus_service.delete_subscription_message(self._topic_name, self._subscription_name, self.broker_properties['SequenceNumber'], self.broker_properties['LockToken']) else: raise WindowsAzureError(_ERROR_MESSAGE_NOT_PEEK_LOCKED_ON_DELETE)
def __init__(self, account_name=None, account_key=None, protocol='https', host_base=TABLE_SERVICE_HOST_BASE, dev_host=DEV_TABLE_HOST, timeout=DEFAULT_HTTP_TIMEOUT, sas_token=None, connection_string=None, request_session=None): ''' account_name: your storage account name, required for all operations. account_key: your storage account key, required for all operations. protocol: Optional. Protocol. Defaults to http. host_base: Optional. Live host base url. Defaults to Azure url. Override this for on-premise. dev_host: Optional. Dev host url. Defaults to localhost. timeout: Optional. Timeout for the http request, in seconds. sas_token: Optional. Token to use to authenticate with shared access signature. connection_string: Optional. If specified, the first four parameters (account_name, account_key, protocol, host_base) may be overridden by values specified in the connection_string. The next three parameters (dev_host, timeout, sas_token) cannot be specified with a connection_string. See http://azure.microsoft.com/en-us/documentation/articles/storage-configure-connection-string/ for the connection string format. request_session: Optional. Session object to use for http requests. If this is specified, it replaces the default use of httplib. ''' if connection_string is not None: connection_params = StorageConnectionParameters(connection_string) account_name = connection_params.account_name account_key = connection_params.account_key protocol = connection_params.protocol.lower() host_base = connection_params.host_base_table super(TableService, self).__init__(account_name, account_key, protocol, host_base, dev_host, timeout, sas_token, request_session) if self.account_key: self.authentication = StorageTableSharedKeyAuthentication( self.account_name, self.account_key, ) elif self.sas_token: self.authentication = StorageSASAuthentication(self.sas_token) else: raise WindowsAzureError(_ERROR_STORAGE_MISSING_INFO)
def convert_entity_to_xml(source): ''' Converts an entity object to xml to send. The entity format is: <entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom"> <title /> <updated>2008-09-18T23:46:19.3857256Z</updated> <author> <name /> </author> <id /> <content type="application/xml"> <m:properties> <d:Address>Mountain View</d:Address> <d:Age m:type="Edm.Int32">23</d:Age> <d:AmountDue m:type="Edm.Double">200.23</d:AmountDue> <d:BinaryData m:type="Edm.Binary" m:null="true" /> <d:CustomerCode m:type="Edm.Guid">c9da6455-213d-42c9-9a79-3e9149a57833</d:CustomerCode> <d:CustomerSince m:type="Edm.DateTime">2008-07-10T00:00:00</d:CustomerSince> <d:IsActive m:type="Edm.Boolean">true</d:IsActive> <d:NumOfOrders m:type="Edm.Int64">255</d:NumOfOrders> <d:PartitionKey>mypartitionkey</d:PartitionKey> <d:RowKey>myrowkey1</d:RowKey> <d:Timestamp m:type="Edm.DateTime">0001-01-01T00:00:00</d:Timestamp> </m:properties> </content> </entry> ''' #construct the entity body included in <m:properties> and </m:properties> entity_body = '<m:properties>{properties}</m:properties>' if isinstance(source, WindowsAzureData): source = vars(source) properties_str = '' #set properties type for types we know if value has no type info. #if value has type info, then set the type to value.type for name, value in source.iteritems(): mtype = '' conv = _PYTHON_TO_ENTITY_CONVERSIONS.get(type(value)) if conv is None: raise WindowsAzureError(_ERROR_CANNOT_SERIALIZE_VALUE_TO_ENTITY % type(value).__name__) mtype, value = conv(value) #form the property node properties_str += ''.join(['<d:', name]) if mtype: properties_str += ''.join([' m:type="', mtype, '"']) properties_str += ''.join(['>', xml_escape(value), '</d:', name, '>']) #generate the entity_body entity_body = entity_body.format(properties=properties_str) xmlstr = _create_entry(entity_body) return xmlstr
def __init__(self, account_name=None, account_key=None, protocol='http', host_base='', dev_host=''): if account_name is not None: self.account_name = account_name.encode('ascii', 'ignore') else: self.account_name = None if account_key is not None: self.account_key = account_key.encode('ascii', 'ignore') else: self.account_key = None self.requestid = None self.protocol = protocol self.host_base = host_base self.dev_host = dev_host #the app is not run in azure emulator or use default development #storage account and key if app is run in emulator. self.use_local_storage = False #check whether it is run in emulator. if os.environ.has_key(EMULATED): if os.environ[EMULATED].lower() == 'false': self.is_emulated = False else: self.is_emulated = True else: self.is_emulated = False #get account_name and account key. If they are not set when constructing, #get the account and key from environment variables if the app is not run #in azure emulator or use default development storage account and key if #app is run in emulator. if not self.account_name or not self.account_key: if self.is_emulated: self.account_name = DEV_ACCOUNT_NAME self.account_key = DEV_ACCOUNT_KEY self.use_local_storage = True else: if os.environ.has_key(AZURE_STORAGE_ACCOUNT): self.account_name = os.environ[AZURE_STORAGE_ACCOUNT] if os.environ.has_key(AZURE_STORAGE_ACCESS_KEY): self.account_key = os.environ[AZURE_STORAGE_ACCESS_KEY] if not self.account_name or not self.account_key: raise WindowsAzureError(azure._ERROR_STORAGE_MISSING_INFO) self._httpclient = _HTTPClient(service_instance=self, account_key=self.account_key, account_name=self.account_name, protocol=protocol) self._batchclient = None self._filter = self._perform_request_worker
def _convert_xml_to_topic(xmlstr): '''Converts xml response to topic The xml format for topic: <entry xmlns='http://www.w3.org/2005/Atom'> <content type='application/xml'> <TopicDescription xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect"> <DefaultMessageTimeToLive>P10675199DT2H48M5.4775807S</DefaultMessageTimeToLive> <MaxSizeInMegabytes>1024</MaxSizeInMegabytes> <RequiresDuplicateDetection>false</RequiresDuplicateDetection> <DuplicateDetectionHistoryTimeWindow>P7D</DuplicateDetectionHistoryTimeWindow> <DeadLetteringOnFilterEvaluationExceptions>true</DeadLetteringOnFilterEvaluationExceptions> </TopicDescription> </content> </entry> ''' xmldoc = minidom.parseString(xmlstr) topic = Topic() invalid_topic = True #get node for each attribute in Topic class, if nothing found then the response is not valid xml for Topic. for desc in _get_children_from_path(xmldoc, 'entry', 'content', 'TopicDescription'): invalid_topic = True node_value = _get_first_child_node_value(desc, 'DefaultMessageTimeToLive') if node_value is not None: topic.default_message_time_to_live = node_value invalid_topic = False node_value = _get_first_child_node_value(desc, 'MaxSizeInMegabytes') if node_value is not None: topic.max_size_in_megabytes = int(node_value) invalid_topic = False node_value = _get_first_child_node_value(desc, 'RequiresDuplicateDetection') if node_value is not None: topic.requires_duplicate_detection = _parse_bool(node_value) invalid_topic = False node_value = _get_first_child_node_value(desc, 'DuplicateDetectionHistoryTimeWindow') if node_value is not None: topic.duplicate_detection_history_time_window = node_value invalid_topic = False node_value = _get_first_child_node_value(desc, 'EnableBatchedOperations') if node_value is not None: topic.enable_batched_operations = _parse_bool(node_value) invalid_topic = False node_value = _get_first_child_node_value(desc, 'SizeInBytes') if node_value is not None: topic.size_in_bytes = int(node_value) invalid_topic = False if invalid_topic: raise WindowsAzureError(azure._ERROR_TOPIC_NOT_FOUND) #extract id, updated and name value from feed entry and set them of topic. for name, value in _get_entry_properties(xmlstr, True).iteritems(): setattr(topic, name, value) return topic
def _convert_etree_element_to_queue(entry_element): ''' Converts entry element to queue object. The format of xml response for queue: <QueueDescription xmlns=\"http://schemas.microsoft.com/netservices/2010/10/servicebus/connect\"> <MaxSizeInBytes>10000</MaxSizeInBytes> <DefaultMessageTimeToLive>PT5M</DefaultMessageTimeToLive> <LockDuration>PT2M</LockDuration> <RequiresGroupedReceives>False</RequiresGroupedReceives> <SupportsDuplicateDetection>False</SupportsDuplicateDetection> ... </QueueDescription> ''' queue = Queue() # get node for each attribute in Queue class, if nothing found then the # response is not valid xml for Queue. invalid_queue = True queue_element = entry_element.find('./atom:content/sb:QueueDescription', _etree_sb_feed_namespaces) if queue_element is not None: mappings = [ ('LockDuration', 'lock_duration', None), ('MaxSizeInMegabytes', 'max_size_in_megabytes', int), ('RequiresDuplicateDetection', 'requires_duplicate_detection', _parse_bool), ('RequiresSession', 'requires_session', _parse_bool), ('DefaultMessageTimeToLive', 'default_message_time_to_live', None), ('DeadLetteringOnMessageExpiration', 'dead_lettering_on_message_expiration', _parse_bool), ('DuplicateDetectionHistoryTimeWindow', 'duplicate_detection_history_time_window', None), ('EnableBatchedOperations', 'enable_batched_operations', _parse_bool), ('MaxDeliveryCount', 'max_delivery_count', int), ('MessageCount', 'message_count', int), ('SizeInBytes', 'size_in_bytes', int), ] for map in mappings: if _read_etree_element(queue_element, map[0], queue, map[1], map[2]): invalid_queue = False if invalid_queue: raise WindowsAzureError(_ERROR_QUEUE_NOT_FOUND) # extract id, updated and name value from feed entry and set them of queue. for name, value in _ETreeXmlToObject.get_entry_properties_from_element( entry_element, True).items(): setattr(queue, name, value) return queue
def _wait_for_completion(azure, promise, wait_timeout, msg): if not promise: return wait_timeout = time.time() + wait_timeout while wait_timeout > time.time(): operation_result = azure.get_operation_status(promise.request_id) time.sleep(5) if operation_result.status == "Succeeded": return raise WindowsAzureError('Timed out waiting for async operation ' + msg + ' "' + str(promise.request_id) + '" to complete.')
def validate_request_row_key(self, request): ''' Validates that all requests have the different RowKey and adds RowKey to existing RowKey list. request: the request to insert, update or delete entity ''' if self.batch_row_keys: if self.get_request_row_key(request) in self.batch_row_keys: raise WindowsAzureError(azure._ERROR_DUPLICATE_ROW_KEY_IN_BATCH) else: self.batch_row_keys.append(self.get_request_row_key(request))
def __init__(self, account_name=None, account_key=None, protocol='https', host_base='', dev_host=''): ''' account_name: your storage account name, required for all operations. account_key: your storage account key, required for all operations. protocol: Optional. Protocol. Defaults to http. host_base: Optional. Live host base url. Defaults to Azure url. Override this for on-premise. dev_host: Optional. Dev host url. Defaults to localhost. ''' self.account_name = account_name self.account_key = account_key self.requestid = None self.protocol = protocol self.host_base = host_base self.dev_host = dev_host # the app is not run in azure emulator or use default development # storage account and key if app is run in emulator. self.use_local_storage = False # check whether it is run in emulator. if EMULATED in os.environ: self.is_emulated = os.environ[EMULATED].lower() != 'false' else: self.is_emulated = False # get account_name and account key. If they are not set when # constructing, get the account and key from environment variables if # the app is not run in azure emulator or use default development # storage account and key if app is run in emulator. if not self.account_name or not self.account_key: if self.is_emulated: self.account_name = DEV_ACCOUNT_NAME self.account_key = DEV_ACCOUNT_KEY self.use_local_storage = True else: self.account_name = os.environ.get(AZURE_STORAGE_ACCOUNT) self.account_key = os.environ.get(AZURE_STORAGE_ACCESS_KEY) if not self.account_name or not self.account_key: raise WindowsAzureError(_ERROR_STORAGE_MISSING_INFO) self._httpclient = _HTTPClient(service_instance=self, account_key=self.account_key, account_name=self.account_name, protocol=protocol) self._batchclient = None self._filter = self._perform_request_worker
def validate_request_table(self, request): ''' Validates that all requests have the same table name. Set the table name if it is the first request for the batch operation. request: the request to insert, update or delete entity ''' if self.batch_table: if self.get_request_table(request) != self.batch_table: raise WindowsAzureError(azure._ERROR_INCORRECT_TABLE_IN_BATCH) else: self.batch_table = self.get_request_table(request)
def get_request_partition_key(self, request): ''' Extracts PartitionKey from request.body if it is a POST request or from request.path if it is not a POST request. Only insert operation request is a POST request and the PartitionKey is in the request body. request: the request to insert, update or delete entity ''' if request.method == 'POST': doc = minidom.parseString(request.body) part_key = _get_children_from_path(doc, 'entry', 'content', (METADATA_NS, 'properties'), (_DATASERVICES_NS, 'PartitionKey')) if not part_key: raise WindowsAzureError(azure._ERROR_CANNOT_FIND_PARTITION_KEY) return part_key[0].firstChild.nodeValue else: uri = urllib2.unquote(request.path) pos1 = uri.find('PartitionKey=\'') pos2 = uri.find('\',', pos1) if pos1 == -1 or pos2 == -1: raise WindowsAzureError(azure._ERROR_CANNOT_FIND_PARTITION_KEY) return uri[pos1 + len('PartitionKey=\''):pos2]
def validate_request_partition_key(self, request): ''' Validates that all requests have the same PartitiionKey. Set the PartitionKey if it is the first request for the batch operation. request: the request to insert, update or delete entity ''' if self.batch_partition_key: if self.get_request_partition_key(request) != self.batch_partition_key: raise WindowsAzureError(azure._ERROR_INCORRECT_PARTITION_KEY_IN_BATCH) else: self.batch_partition_key = self.get_request_partition_key(request)
def get_request_partition_key(self, request): ''' Extracts PartitionKey from request.body if it is a POST request or from request.path if it is not a POST request. Only insert operation request is a POST request and the PartitionKey is in the request body. request: the request to insert, update or delete entity ''' if request.method == 'POST': doc = ETree.fromstring(request.body) part_key = doc.find('./atom:content/m:properties/d:PartitionKey', _etree_entity_feed_namespaces) if part_key is None: raise WindowsAzureError(_ERROR_CANNOT_FIND_PARTITION_KEY) return _get_etree_text(part_key) else: uri = url_unquote(request.path) pos1 = uri.find('PartitionKey=\'') pos2 = uri.find('\',', pos1) if pos1 == -1 or pos2 == -1: raise WindowsAzureError(_ERROR_CANNOT_FIND_PARTITION_KEY) return uri[pos1 + len('PartitionKey=\''):pos2]
def _convert_etree_element_to_topic(entry_element): '''Converts entry element to topic The xml format for topic: <entry xmlns='http://www.w3.org/2005/Atom'> <content type='application/xml'> <TopicDescription xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect"> <DefaultMessageTimeToLive>P10675199DT2H48M5.4775807S</DefaultMessageTimeToLive> <MaxSizeInMegabytes>1024</MaxSizeInMegabytes> <RequiresDuplicateDetection>false</RequiresDuplicateDetection> <DuplicateDetectionHistoryTimeWindow>P7D</DuplicateDetectionHistoryTimeWindow> <DeadLetteringOnFilterEvaluationExceptions>true</DeadLetteringOnFilterEvaluationExceptions> </TopicDescription> </content> </entry> ''' topic = Topic() invalid_topic = True topic_element = entry_element.find('./atom:content/sb:TopicDescription', _etree_sb_feed_namespaces) if topic_element is not None: mappings = [ ('DefaultMessageTimeToLive', 'default_message_time_to_live', None), ('MaxSizeInMegabytes', 'max_size_in_megabytes', int), ('RequiresDuplicateDetection', 'requires_duplicate_detection', _parse_bool), ('DuplicateDetectionHistoryTimeWindow', 'duplicate_detection_history_time_window', None), ('EnableBatchedOperations', 'enable_batched_operations', _parse_bool), ('SizeInBytes', 'size_in_bytes', int), ] for map in mappings: if _read_etree_element(topic_element, map[0], topic, map[1], map[2]): invalid_topic = False if invalid_topic: raise WindowsAzureError(_ERROR_TOPIC_NOT_FOUND) # extract id, updated and name value from feed entry and set them of topic. for name, value in _ETreeXmlToObject.get_entry_properties_from_element( entry_element, True).items(): setattr(topic, name, value) return topic
def _wait_for_async(conn, request_id): count = 0 log.debug('Waiting for asynchronous operation to complete') result = conn.get_operation_status(request_id) while result.status == 'InProgress': count = count + 1 if count > 120: raise ValueError( 'Timed out waiting for async operation to complete.') time.sleep(5) result = conn.get_operation_status(request_id) if result.status != 'Succeeded': raise WindowsAzureError('Operation failed. {message} ({code})'.format( message=result.error.message, code=result.error.code))
def _convert_xml_to_topic(xmlstr): '''Converts xml response to topic The xml format for topic: <entry xmlns='http://www.w3.org/2005/Atom'> <content type='application/xml'> <TopicDescription xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect"> <DefaultMessageTimeToLive>P10675199DT2H48M5.4775807S</DefaultMessageTimeToLive> <MaxSizeInMegaBytes>1024</MaxSizeInMegaBytes> <RequiresDuplicateDetection>false</RequiresDuplicateDetection> <DuplicateDetectionHistoryTimeWindow>P7D</DuplicateDetectionHistoryTimeWindow> <DeadLetteringOnFilterEvaluationExceptions>true</DeadLetteringOnFilterEvaluationExceptions> </TopicDescription> </content> </entry> ''' xmldoc = minidom.parseString(xmlstr) topic = Topic() invalid_topic = True #get node for each attribute in Topic class, if nothing found then the response is not valid xml for Topic. for desc in _get_children_from_path(xmldoc, 'entry', 'content', 'TopicDescription'): invalid_topic = True for attr_name, attr_value in vars(topic).iteritems(): xml_attrs = _get_child_nodes(desc, _get_serialization_name(attr_name)) if xml_attrs: xml_attr = xml_attrs[0] if xml_attr.firstChild: value = xml_attr.firstChild.nodeValue conversion = _TOPIC_CONVERSION.get(attr_name) if conversion is not None: value = conversion(value) setattr(topic, attr_name, value) invalid_topic = False if invalid_topic: raise WindowsAzureError(azure._ERROR_TOPIC_NOT_FOUND) #extract id, updated and name value from feed entry and set them of topic. for name, value in _get_entry_properties(xmlstr, True).iteritems(): setattr(topic, name, value) return topic
def _convert_xml_to_queue(xmlstr): ''' Converts xml response to queue object. The format of xml response for queue: <QueueDescription xmlns=\"http://schemas.microsoft.com/netservices/2010/10/servicebus/connect\"> <MaxSizeInBytes>10000</MaxSizeInBytes> <DefaultMessageTimeToLive>PT5M</DefaultMessageTimeToLive> <LockDuration>PT2M</LockDuration> <RequiresGroupedReceives>False</RequiresGroupedReceives> <SupportsDuplicateDetection>False</SupportsDuplicateDetection> ... </QueueDescription> ''' xmldoc = minidom.parseString(xmlstr) queue = Queue() invalid_queue = True #get node for each attribute in Queue class, if nothing found then the response is not valid xml for Queue. for queue_desc in _get_children_from_path(xmldoc, 'entry', 'content', 'QueueDescription'): for attr_name, attr_value in vars(queue).iteritems(): xml_attrs = _get_child_nodes(queue_desc, _get_serialization_name(attr_name)) if xml_attrs: xml_attr = xml_attrs[0] if xml_attr.firstChild: value = xml_attr.firstChild.nodeValue conversion = _QUEUE_CONVERSION.get(attr_name) if conversion is not None: value = conversion(value) setattr(queue, attr_name, value) invalid_queue = False if invalid_queue: raise WindowsAzureError(azure._ERROR_QUEUE_NOT_FOUND) #extract id, updated and name value from feed entry and set them of queue. for name, value in _get_entry_properties(xmlstr, True).iteritems(): setattr(queue, name, value) return queue
def __init__(self, service_namespace=None, account_key=None, issuer=None, x_ms_version='2011-06-01'): self.requestid = None self.service_namespace = service_namespace self.account_key = account_key self.issuer = issuer #get service namespace, account key and issuer. If they are set when constructing, then use them. #else find them from environment variables. if not service_namespace: if os.environ.has_key(AZURE_SERVICEBUS_NAMESPACE): self.service_namespace = os.environ[AZURE_SERVICEBUS_NAMESPACE] if not account_key: if os.environ.has_key(AZURE_SERVICEBUS_ACCESS_KEY): self.account_key = os.environ[AZURE_SERVICEBUS_ACCESS_KEY] if not issuer: if os.environ.has_key(AZURE_SERVICEBUS_ISSUER): self.issuer = os.environ[AZURE_SERVICEBUS_ISSUER] if not self.service_namespace or not self.account_key or not self.issuer: raise WindowsAzureError('You need to provide servicebus namespace, access key and Issuer') self.x_ms_version = x_ms_version self._httpclient = _HTTPClient(service_instance=self, service_namespace=service_namespace, account_key=account_key, issuer=issuer, x_ms_version=self.x_ms_version) self._filter = self._httpclient.perform_request
def _convert_xml_to_queue(xmlstr): ''' Converts xml response to queue object. The format of xml response for queue: <QueueDescription xmlns=\"http://schemas.microsoft.com/netservices/2010/10/servicebus/connect\"> <MaxSizeInBytes>10000</MaxSizeInBytes> <DefaultMessageTimeToLive>PT5M</DefaultMessageTimeToLive> <LockDuration>PT2M</LockDuration> <RequiresGroupedReceives>False</RequiresGroupedReceives> <SupportsDuplicateDetection>False</SupportsDuplicateDetection> ... </QueueDescription> ''' xmldoc = minidom.parseString(xmlstr) queue = Queue() invalid_queue = True #get node for each attribute in Queue class, if nothing found then the response is not valid xml for Queue. for desc in _get_children_from_path(xmldoc, 'entry', 'content', 'QueueDescription'): node_value = _get_first_child_node_value(desc, 'LockDuration') if node_value is not None: queue.lock_duration = node_value invalid_queue = False node_value = _get_first_child_node_value(desc, 'MaxSizeInMegabytes') if node_value is not None: queue.max_size_in_megabytes = int(node_value) invalid_queue = False node_value = _get_first_child_node_value(desc, 'RequiresDuplicateDetection') if node_value is not None: queue.requires_duplicate_detection = _parse_bool(node_value) invalid_queue = False node_value = _get_first_child_node_value(desc, 'RequiresSession') if node_value is not None: queue.requires_session = _parse_bool(node_value) invalid_queue = False node_value = _get_first_child_node_value(desc, 'DefaultMessageTimeToLive') if node_value is not None: queue.default_message_time_to_live = node_value invalid_queue = False node_value = _get_first_child_node_value( desc, 'DeadLetteringOnMessageExpiration') if node_value is not None: queue.dead_lettering_on_message_expiration = _parse_bool( node_value) invalid_queue = False node_value = _get_first_child_node_value( desc, 'DuplicateDetectionHistoryTimeWindow') if node_value is not None: queue.duplicate_detection_history_time_window = node_value invalid_queue = False node_value = _get_first_child_node_value(desc, 'EnableBatchedOperations') if node_value is not None: queue.enable_batched_operations = _parse_bool(node_value) invalid_queue = False node_value = _get_first_child_node_value(desc, 'MaxDeliveryCount') if node_value is not None: queue.max_delivery_count = int(node_value) invalid_queue = False node_value = _get_first_child_node_value(desc, 'MessageCount') if node_value is not None: queue.message_count = int(node_value) invalid_queue = False node_value = _get_first_child_node_value(desc, 'SizeInBytes') if node_value is not None: queue.size_in_bytes = int(node_value) invalid_queue = False if invalid_queue: raise WindowsAzureError(azure._ERROR_QUEUE_NOT_FOUND) #extract id, updated and name value from feed entry and set them of queue. for name, value in _get_entry_properties(xmlstr, True).iteritems(): setattr(queue, name, value) return queue
def _convert_etree_element_to_event_hub(entry_element): hub = EventHub() invalid_event_hub = True # get node for each attribute in EventHub class, if nothing found then the # response is not valid xml for EventHub. hub_element = entry_element.find('./atom:content/sb:EventHubDescription', _etree_sb_feed_namespaces) if hub_element is not None: mappings = [ ('SizeInBytes', 'size_in_bytes', int), ('MessageRetentionInDays', 'message_retention_in_days', int), ('Status', 'status', None), ('UserMetadata', 'user_metadata', None), ('PartitionCount', 'partition_count', int), ('EntityAvailableStatus', 'entity_available_status', None), ] for map in mappings: if _read_etree_element(hub_element, map[0], hub, map[1], map[2]): invalid_event_hub = False ids = hub_element.find('./sb:PartitionIds', _etree_sb_feed_namespaces) if ids is not None: for id_node in ids.findall('./arrays:string', _etree_sb_feed_namespaces): value = _get_etree_text(id_node) if value: hub.partition_ids.append(value) rules_nodes = hub_element.find('./sb:AuthorizationRules', _etree_sb_feed_namespaces) if rules_nodes is not None: invalid_event_hub = False for rule_node in rules_nodes.findall('./sb:AuthorizationRule', _etree_sb_feed_namespaces): rule = AuthorizationRule() mappings = [ ('ClaimType', 'claim_type', None), ('ClaimValue', 'claim_value', None), ('ModifiedTime', 'modified_time', None), ('CreatedTime', 'created_time', None), ('KeyName', 'key_name', None), ('PrimaryKey', 'primary_key', None), ('SecondaryKey', 'secondary_key', None), ] for map in mappings: _read_etree_element(rule_node, map[0], rule, map[1], map[2]) rights_nodes = rule_node.find('./sb:Rights', _etree_sb_feed_namespaces) if rights_nodes is not None: for access_rights_node in rights_nodes.findall( './sb:AccessRights', _etree_sb_feed_namespaces): node_value = _get_etree_text(access_rights_node) if node_value: rule.rights.append(node_value) hub.authorization_rules.append(rule) if invalid_event_hub: raise WindowsAzureError(_ERROR_EVENT_HUB_NOT_FOUND) # extract id, updated and name value from feed entry and set them of queue. for name, value in _ETreeXmlToObject.get_entry_properties_from_element( entry_element, True).items(): if name == 'name': value = value.partition('?')[0] setattr(hub, name, value) return hub
def __init__(self, service_namespace=None, account_key=None, issuer=None, x_ms_version='2011-06-01', host_base=SERVICE_BUS_HOST_BASE, shared_access_key_name=None, shared_access_key_value=None, authentication=None, timeout=DEFAULT_HTTP_TIMEOUT, request_session=None): ''' Initializes the service bus service for a namespace with the specified authentication settings (SAS or ACS). service_namespace: Service bus namespace, required for all operations. If None, the value is set to the AZURE_SERVICEBUS_NAMESPACE env variable. account_key: ACS authentication account key. If None, the value is set to the AZURE_SERVICEBUS_ACCESS_KEY env variable. Note that if both SAS and ACS settings are specified, SAS is used. issuer: ACS authentication issuer. If None, the value is set to the AZURE_SERVICEBUS_ISSUER env variable. Note that if both SAS and ACS settings are specified, SAS is used. x_ms_version: Unused. Kept for backwards compatibility. host_base: Optional. Live host base url. Defaults to Azure url. Override this for on-premise. shared_access_key_name: SAS authentication key name. Note that if both SAS and ACS settings are specified, SAS is used. shared_access_key_value: SAS authentication key value. Note that if both SAS and ACS settings are specified, SAS is used. authentication: Instance of authentication class. If this is specified, then ACS and SAS parameters are ignored. timeout: Optional. Timeout for the http request, in seconds. request_session: Optional. Session object to use for http requests. If this is specified, it replaces the default use of httplib. ''' self.requestid = None self.service_namespace = service_namespace self.host_base = host_base if not self.service_namespace: self.service_namespace = os.environ.get(AZURE_SERVICEBUS_NAMESPACE) if not self.service_namespace: raise WindowsAzureError('You need to provide servicebus namespace') if authentication: self.authentication = authentication else: if not account_key: account_key = os.environ.get(AZURE_SERVICEBUS_ACCESS_KEY) if not issuer: issuer = os.environ.get(AZURE_SERVICEBUS_ISSUER) if shared_access_key_name and shared_access_key_value: self.authentication = ServiceBusSASAuthentication( shared_access_key_name, shared_access_key_value) elif account_key and issuer: self.authentication = ServiceBusWrapTokenAuthentication( account_key, issuer) else: raise WindowsAzureError( 'You need to provide servicebus access key and Issuer OR shared access key and value' ) self._httpclient = _HTTPClient( service_instance=self, timeout=timeout, request_session=request_session, ) self._filter = self._httpclient.perform_request
def __init__(self, account_name=None, account_key=None, protocol='https', host_base='', dev_host='', timeout=DEFAULT_HTTP_TIMEOUT, sas_token=None, request_session=None): ''' account_name: your storage account name, required for all operations. account_key: your storage account key, required for all operations. protocol: Optional. Protocol. Defaults to http. host_base: Optional. Live host base url. Defaults to Azure url. Override this for on-premise. dev_host: Optional. Dev host url. Defaults to localhost. timeout: Optional. Timeout for the http request, in seconds. sas_token: Optional. Token to use to authenticate with shared access signature. request_session: Optional. Session object to use for http requests. If this is specified, it replaces the default use of httplib. ''' self.account_name = account_name self.account_key = account_key self.requestid = None self.protocol = protocol.lower() self.host_base = host_base self.dev_host = dev_host self.sas_token = sas_token # the app is not run in azure emulator or use default development # storage account and key if app is run in emulator. self.use_local_storage = False # check whether it is run in emulator. if EMULATED in os.environ: self.is_emulated = os.environ[EMULATED].lower() != 'false' else: self.is_emulated = False # get account_name and account key. If they are not set when # constructing, get the account and key from environment variables if # the app is not run in azure emulator or use default development # storage account and key if app is run in emulator. if not self.account_name and not self.account_key: if self.is_emulated: self.account_name = DEV_ACCOUNT_NAME self.account_key = DEV_ACCOUNT_KEY self.protocol = 'http' self.use_local_storage = True else: self.account_name = os.environ.get(AZURE_STORAGE_ACCOUNT) self.account_key = os.environ.get(AZURE_STORAGE_ACCESS_KEY) if not self.account_name: raise WindowsAzureError(_ERROR_STORAGE_MISSING_INFO) self._httpclient = _HTTPClient( service_instance=self, protocol=self.protocol, timeout=timeout, request_session=request_session, ) self._batchclient = None self._filter = self._perform_request_worker