Merge pull request #350 from kfarmer-msft/dev

Port connection string changes to Python
This commit is contained in:
Ze Qian Zhang 2017-09-10 00:43:27 -07:00 коммит произвёл GitHub
Родитель f410feef32 798f4be7a0
Коммит dbdec015b5
3 изменённых файлов: 70 добавлений и 9 удалений

Просмотреть файл

@ -6,6 +6,7 @@
### All:
- Added logging to the library, the name of the logger is 'azure.storage'. User must add handlers to the logger to output logs.
- Secondary endpoints may now be specified in connection strings, provided the corresponding primary endpoint is specified. See the connection string documentation for details.
## Version 0.36.0:

Просмотреть файл

@ -39,17 +39,24 @@ _EMULATOR_ENDPOINTS = {
'file': '',
}
_CONNECTION_ENDPONTS = {
_CONNECTION_ENDPOINTS = {
'blob': 'BlobEndpoint',
'queue': 'QueueEndpoint',
'table': 'TableEndpoint',
'file': 'FileEndpoint',
}
_CONNECTION_ENDPOINTS_SECONDARY = {
'blob': 'BlobSecondaryEndpoint',
'queue': 'QueueSecondaryEndpoint',
'table': 'TableSecondaryEndpoint',
'file': 'FileSecondaryEndpoint',
}
class _ServiceParameters(object):
def __init__(self, service, account_name=None, account_key=None, sas_token=None,
is_emulated=False, protocol=DEFAULT_PROTOCOL, endpoint_suffix=SERVICE_HOST_BASE,
custom_domain=None):
def __init__(self, service, account_name=None, account_key=None, sas_token=None,
is_emulated=False, protocol=DEFAULT_PROTOCOL, endpoint_suffix=SERVICE_HOST_BASE,
custom_domain=None, custom_domain_secondary=None):
self.account_name = account_name
self.account_key = account_key
@ -88,10 +95,21 @@ class _ServiceParameters(object):
self.primary_endpoint = '{}.{}.{}'.format(self.account_name, service, endpoint_suffix)
# Setup the secondary endpoint
if self.account_name:
self.secondary_endpoint = '{}-secondary.{}.{}'.format(self.account_name, service, endpoint_suffix)
if custom_domain_secondary:
if not custom_domain:
raise ValueError(_ERROR_STORAGE_MISSING_INFO)
parsed_url = urlparse(custom_domain_secondary)
# Trim any trailing slashes from the path
path = parsed_url.path.rstrip('/')
self.secondary_endpoint = parsed_url.netloc + path
else:
self.secondary_endpoint = None
if self.account_name:
self.secondary_endpoint = '{}-secondary.{}.{}'.format(self.account_name, service, endpoint_suffix)
else:
self.secondary_endpoint = None
@staticmethod
def get_service_parameters(service, account_name=None, account_key=None, sas_token=None, is_emulated=None,
@ -135,7 +153,8 @@ class _ServiceParameters(object):
endpoint_suffix = config.get('EndpointSuffix')
# Custom URLs
endpoint = config.get(_CONNECTION_ENDPONTS[service])
endpoint = config.get(_CONNECTION_ENDPOINTS[service])
endpoint_secondary = config.get(_CONNECTION_ENDPOINTS_SECONDARY[service])
return _ServiceParameters(service,
account_name=account_name,
@ -144,4 +163,5 @@ class _ServiceParameters(object):
is_emulated=is_emulated,
protocol=protocol,
endpoint_suffix=endpoint_suffix,
custom_domain=endpoint)
custom_domain=endpoint,
custom_domain_secondary=endpoint_secondary)

Просмотреть файл

@ -36,6 +36,20 @@ SERVICES = {
FileService: 'file'
}
_CONNECTION_ENDPOINTS = {
'blob': 'BlobEndpoint',
'queue': 'QueueEndpoint',
'table': 'TableEndpoint',
'file': 'FileEndpoint',
}
_CONNECTION_ENDPOINTS_SECONDARY = {
'blob': 'BlobSecondaryEndpoint',
'queue': 'QueueSecondaryEndpoint',
'table': 'TableSecondaryEndpoint',
'file': 'FileSecondaryEndpoint',
}
class StorageClientTest(StorageTestCase):
def setUp(self):
@ -294,6 +308,32 @@ class StorageClientTest(StorageTestCase):
self.assertEqual(service.primary_endpoint, 'www.mydomain.com')
self.assertEqual(service.secondary_endpoint, self.account_name + '-secondary.blob.core.windows.net')
def test_create_service_with_connection_string_fails_if_secondary_without_primary(self):
for type in SERVICES.items():
# Arrange
conn_string = 'AccountName={};AccountKey={};{}=www.mydomain.com;'.format(self.account_name, self.account_key, _CONNECTION_ENDPOINTS_SECONDARY.get(type[1]))
# Act
# Fails if primary excluded
with self.assertRaises(ValueError):
service = type[0](connection_string=conn_string)
def test_create_service_with_connection_string_succeeds_if_secondary_with_primary(self):
for type in SERVICES.items():
# Arrange
conn_string = 'AccountName={};AccountKey={};{}=www.mydomain.com;{}=www-sec.mydomain.com;'.format(self.account_name, self.account_key, _CONNECTION_ENDPOINTS.get(type[1]), _CONNECTION_ENDPOINTS_SECONDARY.get(type[1]))
# Act
service = type[0](connection_string=conn_string)
# Assert
self.assertIsNotNone(service)
self.assertEqual(service.account_name, self.account_name)
self.assertEqual(service.account_key, self.account_key)
self.assertEqual(service.primary_endpoint, 'www.mydomain.com')
self.assertEqual(service.secondary_endpoint, 'www-sec.mydomain.com')
@record
def test_request_callback_signed_header(self):
# Arrange