Search code examples
androidazure-storageazure-mobile-servicesazure-blob-storageazure-android-sdk

Android Azure Storage Blob upload with SAS; com.microsoft.azure.storage.StorageException: The specified resource does not exist


I am trying to upload a file to Azure Storage as blob from android using Microsoft Azure Storage SDK for Android and Azure Mobile service.

Actually I wasn't able to find any sample code using the Shared Access Signature (SAS) in android. The above mentioned mobile service tutorial is for .NET application. So following the same tutorial I am trying to create a sample app in android for image upload

Here is my android code:

 AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>(){
        @Override
        protected Void doInBackground(Void... params) {
            try {
                final ImageItem entity = addItemInTable(item);
                Log.d("InsertedItem:", entity.toString());

                StorageCredentials cred = StorageCredentials.tryParseCredentials(entity.getSasQueryString());

                URI imageURI = new URI(entity.getImageUri());

                URI containerUri = new URI("https://" + imageURI.getHost() + "/" + entity.getContainerName());
                Log.d("ContainerURI:", containerUri.toString());

                CloudBlobContainer container = new CloudBlobContainer(containerUri, cred);

                CloudBlockBlob blobFromSASCredential = container.getBlockBlobReference(entity.getResourceName());
                AssetManager assManager = getApplicationContext().getAssets();
                InputStream is = null;
                try {
                    is = assManager.open("image.jpg");

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                blobFromSASCredential.upload(is, -1);
              //blobFromSASCredential.uploadText("Sample text");


                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (!entity.isComplete()) {
                            mAdapter.add(entity);
                        }
                    }
                });
            } catch (final Exception e) {
                e.printStackTrace();
                createAndShowDialogFromTask(e, "Error");
            }
            return null;
        }
    };

public ImageItem addItemInTable(ImageItem item) throws ExecutionException, InterruptedException {
    item.setContainerName("todoitemimages");
    item.setResourceName(UUID.randomUUID().toString());

    ImageItem entity = mToDoTable.insert(item).get();
    return entity;
}

Here is my GSON object:

public class ImageItem {
/**
 * imageUri : sample string 6
 * containerName : sample string 3
 * sasQueryString : sample string 5
 * resourceName : sample string 4
 * text : sample string 1
 * id : sample string 7
 * complete : true
 */
@SerializedName("imageUri")
private String imageUri;
@SerializedName("containerName")
private String containerName;
@SerializedName("sasQueryString")
private String sasQueryString;
@SerializedName("resourceName")
private String resourceName;
@SerializedName("text")
private String text;
@SerializedName("id")
private String id;
@SerializedName("complete")
private boolean complete;
}

While running the code I get this error:

08-18 19:05:02.650  11595-11711/com.example.zumoimageupload D/InsertedItem:﹕ ID:58b3722d9d164ff6aae3cbf35b0ccfa7 Text:demo text Completefalse ContainerName:todoitemimages ResourceName:c8041429-3269-4531-87f3-4e24652a3005 ImageUri:https://storageserverdemo.blob.core.windows.net/todoitemimages/c8041429-3269-4531-87f3-4e24652a3005 SasQueryString:?sv=2015-02-21&sr=c&sig=iPRd%2BVROWcOtSvSaTNyLjAKwDmyCG%2B1QEr%2BAPEMLKJ8%3D&st=2015-08-18T13%3A35%3A02Z&se=2015-08-18T13%3A40%3A02Z&sp=w
08-18 19:05:04.253  11595-11711/com.example.zumoimageupload W/System.err﹕ com.microsoft.azure.storage.StorageException: The specified resource does not exist.
08-18 19:05:04.287  11595-11711/com.example.zumoimageupload W/System.err﹕ at com.microsoft.azure.storage.core.StorageRequest.materializeException(StorageRequest.java:305)
08-18 19:05:04.289  11595-11711/com.example.zumoimageupload W/System.err﹕ at com.microsoft.azure.storage.core.ExecutionEngine.executeWithRetry(ExecutionEngine.java:175)
08-18 19:05:04.289  11595-11711/com.example.zumoimageupload W/System.err﹕ at com.microsoft.azure.storage.blob.CloudBlockBlob.uploadFullBlob(CloudBlockBlob.java:826)
08-18 19:05:04.289  11595-11711/com.example.zumoimageupload W/System.err﹕ at com.microsoft.azure.storage.blob.CloudBlockBlob.upload(CloudBlockBlob.java:779)
08-18 19:05:04.290  11595-11711/com.example.zumoimageupload W/System.err﹕ at com.microsoft.azure.storage.blob.CloudBlob.uploadFromByteArray(CloudBlob.java:1921)
08-18 19:05:04.290  11595-11711/com.example.zumoimageupload W/System.err﹕ at com.microsoft.azure.storage.blob.CloudBlockBlob.uploadText(CloudBlockBlob.java:1112)
08-18 19:05:04.291  11595-11711/com.example.zumoimageupload W/System.err﹕ at com.microsoft.azure.storage.blob.CloudBlockBlob.uploadText(CloudBlockBlob.java:1082)
08-18 19:05:04.296  11595-11711/com.example.zumoimageupload W/System.err﹕ at com.example.mcettodolist.ToDoActivity$2.doInBackground(ToDoActivity.java:253)
08-18 19:05:04.297  11595-11711/com.example.zumoimageupload W/System.err﹕ at com.example.mcettodolist.ToDoActivity$2.doInBackground(ToDoActivity.java:226)
08-18 19:05:04.297  11595-11711/com.example.zumoimageupload W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:292)
08-18 19:05:04.297  11595-11711/com.example.zumoimageupload W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
08-18 19:05:04.297  11595-11711/com.example.zumoimageupload W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
08-18 19:05:04.297  11595-11711/com.example.zumoimageupload W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
08-18 19:05:04.297  11595-11711/com.example.zumoimageupload W/System.err﹕ at java.lang.Thread.run(Thread.java:818)

Solution

  • StorageCredentials.tryParseCredentials() takes a connection string, so this isn't quite the right method I think. Try just directly creating the credentials object you want using the StorageCredentialsSharedAccessSignature constructor which takes the SAS token.

    Additionally, in order to upload a blob you need to be sure the container you're uploading it to exists. If you're sure it does, then this code is good. Otherwise, the create() or createIfNotExists() methods on the container object are what you'll need.