Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Storage][Blob] Added support for Object Replication #11525

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions sdk/storage/azure-storage-blob/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## 12.3.2 (Unreleased)

**New features**

- Added support for object replication properties for download response and get properties.

## 12.3.1 (2020-04-29)

Expand Down
36 changes: 31 additions & 5 deletions sdk/storage/azure-storage-blob/azure/storage/blob/_deserialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@


def deserialize_blob_properties(response, obj, headers):
metadata = deserialize_metadata(response, obj, headers)
blob_properties = BlobProperties(
metadata=metadata,
metadata=deserialize_metadata(response, obj, headers),
object_replication_source_properties=deserialize_ors_policies(response),
**headers
)
if 'Content-Range' in headers:
Expand All @@ -32,6 +32,32 @@ def deserialize_blob_properties(response, obj, headers):
return blob_properties


def deserialize_ors_policies(response):
# For source blobs (blobs that have policy ids and rule ids applied to them),
# the header will be formatted as "x-ms-or-<policy_id>_<rule_id>: {Complete, Failed}".
# The value of this header is the status of the replication.
or_policy_status_headers = {key: val for key, val in response.headers.items()
if key.startswith('x-ms-or') and key != 'x-ms-or-policy-id'}

parsed_result = {}

# all the ors headers have the same prefix, so we note down its length here to avoid recalculating it repeatedly
header_prefix_length = len('x-ms-or-')

for key, val in or_policy_status_headers.items():
policy_and_rule_ids = key[header_prefix_length:].split('_')
policy_id = policy_and_rule_ids[0]
rule_id = policy_and_rule_ids[1]

try:
parsed_result[policy_id][rule_id] = val
except KeyError:
# we are seeing this policy for the first time, so a new rule_id -> result dict is needed
parsed_result[policy_id] = {rule_id: val}

return parsed_result


def deserialize_blob_stream(response, obj, headers):
blob_properties = deserialize_blob_properties(response, obj, headers)
obj.properties = blob_properties
Expand All @@ -49,10 +75,10 @@ def deserialize_container_properties(response, obj, headers):

def get_page_ranges_result(ranges):
# type: (PageList) -> Tuple[List[Dict[str, int]], List[Dict[str, int]]]
page_range = [] # type: ignore
clear_range = [] # type: List
page_range = [] # type: ignore
tasherif-msft marked this conversation as resolved.
Show resolved Hide resolved
clear_range = [] # type: List
if ranges.page_range:
page_range = [{'start': b.start, 'end': b.end} for b in ranges.page_range] # type: ignore
page_range = [{'start': b.start, 'end': b.end} for b in ranges.page_range] # type: ignore
if ranges.clear_range:
clear_range = [{'start': b.start, 'end': b.end} for b in ranges.clear_range]
return page_range, clear_range # type: ignore
Expand Down
7 changes: 7 additions & 0 deletions sdk/storage/azure-storage-blob/azure/storage/blob/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,11 @@ class BlobProperties(DictMixin):
container-level scope is configured to allow overrides. Otherwise an error will be raised.
:ivar bool request_server_encrypted:
Whether this blob is encrypted.
:ivar dict(str, dict(str, str)) object_replication_source_properties:
Only present for blobs that have policy ids and rule ids applied to them.
Dictionary<policy_id, Dictionary<rule_id, status of replication(complete,failed)>
:ivar str object_replication_destination_policy:
Represents the Object Replication Policy Id that created this blob.
"""

def __init__(self, **kwargs):
Expand Down Expand Up @@ -511,6 +516,8 @@ def __init__(self, **kwargs):
self.encryption_key_sha256 = kwargs.get('x-ms-encryption-key-sha256')
self.encryption_scope = kwargs.get('x-ms-encryption-scope')
self.request_server_encrypted = kwargs.get('x-ms-server-encrypted')
self.object_replication_source_properties = kwargs.get('object_replication_source_properties')
self.object_replication_destination_policy = kwargs.get('x-ms-or-policy-id')
tasherif-msft marked this conversation as resolved.
Show resolved Hide resolved

@classmethod
def _from_generated(cls, generated):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
User-Agent:
- azsdk-python-storage-blob/12.3.2 Python/3.7.4 (Darwin-19.4.0-x86_64-i386-64bit)
x-ms-date:
- Thu, 04 Jun 2020 07:20:14 GMT
x-ms-version:
- '2019-12-12'
method: HEAD
uri: https://storagename.blob.core.windows.net/test2/bla.txt
response:
body:
string: ''
headers:
accept-ranges:
- bytes
content-disposition:
- ''
content-length:
- '0'
content-md5:
- 1B2M2Y8AsgTpgAmY7PhCfg==
content-type:
- application/octet-stream
date:
- Thu, 04 Jun 2020 07:20:14 GMT
etag:
- '"0x8D7FB118A463E24"'
last-modified:
- Mon, 18 May 2020 09:55:04 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-access-tier:
- Hot
x-ms-access-tier-inferred:
- 'true'
x-ms-blob-type:
- BlockBlob
x-ms-copy-completion-time:
- Mon, 18 May 2020 09:55:04 GMT
x-ms-copy-id:
- 47d2f0e0-9739-42f5-ad74-8359dbb0c2ec
x-ms-copy-progress:
- 0/0
x-ms-copy-source:
- https://ortestsaccountcbn1.blob.core.windows.net/test1/bla.txt?versionid=2020-05-18T09:53:04.5502688Z&sv=2015-04-05&ss=b&srt=sco&sp=rwdlacup&se=2020-05-19T09%3A13%3A27.6586322Z&spr=https
x-ms-copy-status:
- success
x-ms-creation-time:
- Mon, 18 May 2020 09:55:04 GMT
x-ms-lease-state:
- available
x-ms-lease-status:
- unlocked
x-ms-or-policy-id:
- fd2da1b9-56f5-45ff-9eb6-310e6dfc2c80
x-ms-server-encrypted:
- 'true'
x-ms-version:
- '2019-12-12'
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/xml
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
User-Agent:
- azsdk-python-storage-blob/12.3.2 Python/3.7.4 (Darwin-19.4.0-x86_64-i386-64bit)
x-ms-date:
- Thu, 04 Jun 2020 07:20:34 GMT
x-ms-range:
- bytes=0-33554431
x-ms-version:
- '2019-12-12'
method: GET
uri: https://storagename.blob.core.windows.net/test2/bla.txt
response:
body:
string: "\uFEFF<?xml version=\"1.0\" encoding=\"utf-8\"?><Error><Code>InvalidRange</Code><Message>The\
\ range specified is invalid for the current size of the resource.\nRequestId:83ee5103-101e-004a-7540-3a794d000000\n\
Time:2020-06-04T07:20:35.0604924Z</Message></Error>"
headers:
content-length:
- '249'
content-range:
- bytes */0
content-type:
- application/xml
date:
- Thu, 04 Jun 2020 07:20:34 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-error-code:
- InvalidRange
x-ms-version:
- '2019-12-12'
status:
code: 416
message: The range specified is invalid for the current size of the resource.
- request:
body: null
headers:
Accept:
- application/xml
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
User-Agent:
- azsdk-python-storage-blob/12.3.2 Python/3.7.4 (Darwin-19.4.0-x86_64-i386-64bit)
x-ms-date:
- Thu, 04 Jun 2020 07:20:35 GMT
x-ms-version:
- '2019-12-12'
method: GET
uri: https://storagename.blob.core.windows.net/test2/bla.txt
response:
body:
string: ''
headers:
accept-ranges:
- bytes
content-disposition:
- ''
content-length:
- '0'
content-md5:
- 1B2M2Y8AsgTpgAmY7PhCfg==
content-type:
- application/octet-stream
date:
- Thu, 04 Jun 2020 07:20:34 GMT
etag:
- '"0x8D7FB118A463E24"'
last-modified:
- Mon, 18 May 2020 09:55:04 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-blob-type:
- BlockBlob
x-ms-copy-completion-time:
- Mon, 18 May 2020 09:55:04 GMT
x-ms-copy-id:
- 47d2f0e0-9739-42f5-ad74-8359dbb0c2ec
x-ms-copy-progress:
- 0/0
x-ms-copy-source:
- https://ortestsaccountcbn1.blob.core.windows.net/test1/bla.txt?versionid=2020-05-18T09:53:04.5502688Z&sv=2015-04-05&ss=b&srt=sco&sp=rwdlacup&se=2020-05-19T09%3A13%3A27.6586322Z&spr=https
x-ms-copy-status:
- success
x-ms-creation-time:
- Mon, 18 May 2020 09:55:04 GMT
x-ms-lease-state:
- available
x-ms-lease-status:
- unlocked
x-ms-or-policy-id:
- fd2da1b9-56f5-45ff-9eb6-310e6dfc2c80
x-ms-server-encrypted:
- 'true'
x-ms-version:
- '2019-12-12'
status:
code: 200
message: OK
version: 1
Loading