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

Implemented ORS List Blobs #13096

Merged
merged 6 commits into from
Jul 15, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ public static BlobItem populateBlobItem(BlobItemInternal blobItemInternal) {
}
blobItem.setTags(tags);

blobItem.setObjectReplicationSourcePolicies(
transformObjectReplicationMetadata(blobItemInternal.getObjectReplicationMetadata()));

return blobItem;
}

Expand Down Expand Up @@ -247,25 +250,36 @@ public static BlobItemProperties populateBlobItemProperties(BlobItemPropertiesIn
blobItemProperties.setAccessTierChangeTime(blobItemPropertiesInternal.getAccessTierChangeTime());
blobItemProperties.setTagCount(blobItemPropertiesInternal.getTagCount());

// TODO: (rickle-msft) Uncomment when these properties are returned on lists.
/*this.objectReplicationSourcePolicies = new HashMap<>();
this.objectReplicationDestinationPolicyId = objectReplicationStatus.getOrDefault("policy-id", null);
if (objectReplicationDestinationPolicyId == null) {
for (String str : objectReplicationStatus.keySet()) {
String[] split = str.split("_");
String policyId = split[0];
String ruleId = split[1];
if (objectReplicationSourcePolicies.containsKey(policyId)) {
objectReplicationSourcePolicies.get(policyId)
.putRuleAndStatus(ruleId, objectReplicationStatus.get(str));
} else {
ObjectReplicationPolicy policy = new ObjectReplicationPolicy(policyId);
policy.putRuleAndStatus(ruleId, objectReplicationStatus.get(str));
objectReplicationSourcePolicies.put(policyId, policy);
}
return blobItemProperties;
}

private static List<ObjectReplicationPolicy> transformObjectReplicationMetadata(
Map<String, String> objectReplicationMetadata) {

Map<String, List<ObjectReplicationRule>> internalSourcePolicies = new HashMap<>();
objectReplicationMetadata = objectReplicationMetadata == null ? new HashMap<>() : objectReplicationMetadata;
for (Map.Entry<String, String> entry : objectReplicationMetadata.entrySet()) {
String orString = entry.getKey();
String str = orString.startsWith("or-") ? orString.substring(3) : orString;
String[] split = str.split("_");
String policyId = split[0];
String ruleId = split[1];
ObjectReplicationRule rule = new ObjectReplicationRule(ruleId,
ObjectReplicationStatus.fromString(entry.getValue()));
if (!internalSourcePolicies.containsKey(policyId)) {
internalSourcePolicies.put(policyId, new ArrayList<>());
}
}*/
internalSourcePolicies.get(policyId).add(rule);
}

return blobItemProperties;
if (internalSourcePolicies.isEmpty()) {
return null;
}
List<ObjectReplicationPolicy> objectReplicationSourcePolicies = new ArrayList<>();
for (Map.Entry<String, List<ObjectReplicationRule>> entry : internalSourcePolicies.entrySet()) {
objectReplicationSourcePolicies.add(new ObjectReplicationPolicy(entry.getKey(), entry.getValue()));
}
return objectReplicationSourcePolicies;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

import java.util.List;
import java.util.Map;

/**
Expand Down Expand Up @@ -57,17 +58,11 @@ public final class BlobItem {

private Boolean isCurrentVersion;

/*
* The objectReplicationPolicyId property.
*/
@JsonProperty(value = "ObjectReplicationPolicyId")
private String objectReplicationPolicyId;

/*
* The objectReplicationRuleStatus property.
*/
@JsonProperty(value = "BlobObjectReplicationRuleStatus")
private Map<String, String> objectReplicationRuleStatus;
private List<ObjectReplicationPolicy> objectReplicationSourcePolicies;

/*
* The isPrefix property.
Expand Down Expand Up @@ -236,48 +231,25 @@ public BlobItem setCurrentVersion(Boolean isCurrentVersion) {
}

/**
* Get the objectReplicationPolicyId property: The
* objectReplicationPolicyId property.
*
* @return the objectReplicationPolicyId value.
*/
public String getObjectReplicationPolicyId() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These APIs were added in the recent beta release, so this should not be a breaking change

return this.objectReplicationPolicyId;
}

/**
* Set the objectReplicationPolicyId property: The
* objectReplicationPolicyId property.
*
* @param objectReplicationPolicyId the objectReplicationPolicyId value to
* set.
* @return the BlobItem object itself.
*/
public BlobItem setObjectReplicationPolicyId(String objectReplicationPolicyId) {
this.objectReplicationPolicyId = objectReplicationPolicyId;
return this;
}

/**
* Get the objectReplicationRuleStatus property: The
* objectReplicationRuleStatus property.
* Get the objectReplicationSourcePolicies property: The
* objectReplicationSourcePolicies property.
*
* @return the objectReplicationRuleStatus value.
* @return the objectReplicationSourcePolicies value.
*/
public Map<String, String> getObjectReplicationRuleStatus() {
return this.objectReplicationRuleStatus;
public List<ObjectReplicationPolicy> getObjectReplicationSourcePolicies() {
return this.objectReplicationSourcePolicies;
}

/**
* Set the objectReplicationRuleStatus property: The
* objectReplicationRuleStatus property.
* Set the objectReplicationSourcePolicies property: The
* objectReplicationSourcePolicies property.
*
* @param objectReplicationRuleStatus the objectReplicationRuleStatus value
* @param objectReplicationSourcePolicies the objectReplicationSourcePolicies value
* to set.
* @return the BlobItem object itself.
*/
public BlobItem setObjectReplicationRuleStatus(Map<String, String> objectReplicationRuleStatus) {
this.objectReplicationRuleStatus = objectReplicationRuleStatus;
public BlobItem setObjectReplicationSourcePolicies(List<ObjectReplicationPolicy> objectReplicationSourcePolicies) {
this.objectReplicationSourcePolicies = objectReplicationSourcePolicies;
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,6 @@ public final class BlobItemProperties {
@JsonProperty(value = "AccessTierChangeTime")
private OffsetDateTime accessTierChangeTime;

// TODO: (rickle-msft) uncomment when these are returned on lists.
/*
private Map<String, ObjectReplicationPolicy> objectReplicationSourcePolicies;

private String objectReplicationDestinationPolicyId;
*/

/*
* The tagCount property.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@ import com.azure.storage.blob.models.CustomerProvidedKey
import com.azure.storage.blob.models.LeaseStateType
import com.azure.storage.blob.models.LeaseStatusType
import com.azure.storage.blob.models.ListBlobsOptions
import com.azure.storage.blob.models.ObjectReplicationPolicy
import com.azure.storage.blob.models.ObjectReplicationStatus
import com.azure.storage.blob.options.PageBlobCreateOptions
import com.azure.storage.blob.models.PublicAccessType
import com.azure.storage.blob.specialized.AppendBlobClient
import com.azure.storage.blob.specialized.BlobClientBase
import com.azure.storage.common.Utility
import reactor.test.StepVerifier
import spock.lang.Requires
import spock.lang.Unroll

import java.time.Duration
Expand Down Expand Up @@ -983,6 +986,50 @@ class ContainerAPITest extends APISpec {
notThrown(Exception)
}

/*
This test requires two accounts that are configured in a very specific way. It is not feasible to setup that
relationship programmatically, so we have recorded a successful interaction and only test recordings.
*/
@Requires( {playbackMode()})
def "List blobs flat ORS"() {
setup:
def sourceContainer = primaryBlobServiceClient.getBlobContainerClient("test1")
def destContainer = alternateBlobServiceClient.getBlobContainerClient("test2")

when:
def sourceBlobs = sourceContainer.listBlobs().stream().collect(Collectors.toList())
def destBlobs = destContainer.listBlobs().stream().collect(Collectors.toList())

then:
int i = 0
for (def blob : sourceBlobs) {
if (i == 1) {
assert blob.getObjectReplicationSourcePolicies() == null
} else {
assert validateOR(blob.getObjectReplicationSourcePolicies(), "fd2da1b9-56f5-45ff-9eb6-310e6dfc2c80", "105f9aad-f39b-4064-8e47-ccd7937295ca")
}
i++
}

/* Service specifies no ors metadata on the dest blobs. */
for (def blob : destBlobs) {
assert blob.getObjectReplicationSourcePolicies() == null
}
}

def validateOR(List<ObjectReplicationPolicy> policies, String policyId, String ruleId) {
return policies.stream()
.filter({ policy -> policyId.equals(policy.getPolicyId()) })
.findFirst()
.get()
.getRules()
.stream()
.filter({ rule -> ruleId.equals(rule.getRuleId()) })
.findFirst()
.get()
.getStatus() == ObjectReplicationStatus.COMPLETE
}

def "List blobs hierarchy"() {
setup:
def name = generateBlobName()
Expand Down Expand Up @@ -1226,6 +1273,37 @@ class ContainerAPITest extends APISpec {
secondPage.getContinuationToken() == null
}

/*
This test requires two accounts that are configured in a very specific way. It is not feasible to setup that
relationship programmatically, so we have recorded a successful interaction and only test recordings.
*/
@Requires( {playbackMode()})
def "List blobs hier ORS"() {
setup:
def sourceContainer = primaryBlobServiceClient.getBlobContainerClient("test1")
def destContainer = alternateBlobServiceClient.getBlobContainerClient("test2")

when:
def sourceBlobs = sourceContainer.listBlobsByHierarchy("/").stream().collect(Collectors.toList())
def destBlobs = destContainer.listBlobsByHierarchy("/").stream().collect(Collectors.toList())

then:
int i = 0
for (def blob : sourceBlobs) {
if (i == 1) {
assert blob.getObjectReplicationSourcePolicies() == null
} else {
assert validateOR(blob.getObjectReplicationSourcePolicies(), "fd2da1b9-56f5-45ff-9eb6-310e6dfc2c80", "105f9aad-f39b-4064-8e47-ccd7937295ca")
}
i++
}

/* Service specifies no ors metadata on the dest blobs. */
for (def blob : destBlobs) {
assert blob.getObjectReplicationSourcePolicies() == null
}
}

def "List blobs flat simple"() {
setup: "Create 10 page blobs in the container"
def NUM_BLOBS = 10
Expand Down
Loading