Skip to content

Commit

Permalink
Implemented ORS List Blobs (#13096)
Browse files Browse the repository at this point in the history
  • Loading branch information
gapra-msft authored Jul 15, 2020
1 parent 6bd5b67 commit d409692
Show file tree
Hide file tree
Showing 6 changed files with 336 additions and 65 deletions.
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() {
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

0 comments on commit d409692

Please sign in to comment.