Azure Blob Error: StorageException: The condition specified using HTTP conditional header(s) is not met

假装没事ソ 提交于 2021-01-28 09:01:40

问题


So I have a function that simply downloads text from blob storage every 10 minutes and checks for a result. This function can run for days. But it often (roughly every day) fails before finishing with the following error.

Caused by: com.microsoft.azure.storage.StorageException: The condition specified using HTTP conditional header(s) is not met.

My code is pretty simple.

public String downloadTextBlob(CloudBlobDirectory dir, String filename) {
    try {
        return dir.getBlockBlobReference(filename).downloadText();
    } catch (StorageException | IOException | URISyntaxException e) {
        throw new WorkbenchRuntimeException(e.getMessage(), e);
    }
}

I the same issue posted here, and I was interested in the answer which talked about using an OperationContext to fix the issue. But the question wasn't on Java, and the answer didn't really explain what it was actually doing.

Here's the proposed solution (non java code)

 OperationContext context = new OperationContext();
 context.SendingRequest += (sender, e) => { 
     e.Request.Headers["if-match"] = "*";
 };

Can anyone explain what this is actually doing? And maybe how I can replicate this in Java, I notice there is an OperationContext in the Java azure storage sdk, and that I can call the .downloadText() with an operation context as a parameter. I'm just not sure what to do with OperationContext.


回答1:


First, I would encourage you to read about conditional headers in Azure Blob Storage here: https://docs.microsoft.com/en-us/rest/api/storageservices/specifying-conditional-headers-for-blob-service-operations.

I haven't looked at the source code for the Java SDK but my guess is that downloadText() operation is performing multiple operations behind the scenes. In the first operation, it is getting the properties of the blob (like blob's length etc.) and in the next operation it is actually downloading the blob. As part of the first operation it also gets the blob's etag and it is passing the same etag to the 2nd operation in if-match header.

Now between the 1st and 2nd operation something changed with the blob that caused etag value to change. Since the 2nd request still used the old etag value and there's a mismatch between the etag, your request is failing with precondition failed. Presence of etag in if-match header instructs storage service to perform the operation only if the condition matches (i.e. etag matches). Since the etag doesn't match, you're getting this error.

To fix this, you need to use the following override of downloadText() method:

downloadText(final String charsetName, final AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext)

and specify an access condition with "*" value for if-match which essentially tells storage service to ignore the etag value. You can learn more about access condition here: https://docs.microsoft.com/en-us/java/api/com.microsoft.azure.storage.accesscondition?view=azure-java-legacy.

Your code would be something like (untested code):

AccessCondition accessCondition = AccessCondition.generateIfMatchCondition("*");

and use this access condition in your downloadText() method.



来源:https://stackoverflow.com/questions/62308525/azure-blob-error-storageexception-the-condition-specified-using-http-condition

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!