Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload file with Azure Storage using SAS (Shared Access Signature)

I know that there is library available for uploading the file using Azure Storage. I have refer this for same.

But, they have not give information for how to use SAS with that. I have account name, and sas url for access and upload file there. But I don't know how to use that for uploading file.

If I use above mention library it shows me invalid storage connection string because I am not passing the key in it (Which is not required with sas). So I am confused how I can upload file.

I have refer this documentation also for uploading file using sas. but not getting proper steps to do this. They have made demo for their windows app. I want to have that in android with use of sas.

Update

I have try with below code with reference to the console app made by Azure to check and access SAS.

 try {
        //Try performing container operations with the SAS provided.

        //Return a reference to the container using the SAS URI.
        //CloudBlockBlob blob = new CloudBlockBlob(new StorageUri(new URI(sas)));
        String[] str = userId.split(":");
        String blobUri = "https://myStorageAccountName.blob.core.windows.net/image/" + str[1] + "/story/" + storyId + "/image1.jpg" + sas.toString().replaceAll("\"","");
        Log.d(TAG,"Result:: blobUrl 1 : "+blobUri);
        CloudBlobContainer container = new CloudBlobContainer(new URI(blobUri));
        Log.d(TAG,"Result:: blobUrl 2 : "+blobUri);
        CloudBlockBlob blob = container.getBlockBlobReference("image1.jpg");
        String filePath = postData.get(0).getUrl().toString();
        /*File source = new File(getRealPathFromURI(getApplicationContext(),Uri.parse(filePath))); // File path
        blob.upload(new FileInputStream(source), source.length());*/
        Log.d(TAG,"Result:: blobUrl 3 : "+blobUri);
        //blob.upload(new FileInputStream(source), source.length());
        //blob.uploadText("Hello this is testing..."); // Upload text file
        Log.d(TAG, "Result:: blobUrl 4 : " + blobUri);
        Log.d(TAG, "Write operation succeeded for SAS " + sas);
        response = "success";
        //Console.WriteLine();
    } catch (StorageException e) {
        Log.d(TAG, "Write operation failed for SAS " + sas);
        Log.d(TAG, "Additional error information: " + e.getMessage());
        response = e.getMessage();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        response = e.getMessage();
    } catch (IOException e) {
        e.printStackTrace();
        response = e.getMessage();
    } catch (URISyntaxException e) {
        e.printStackTrace();
        response = e.getMessage();
    } catch (Exception e){
        e.printStackTrace();
        response = e.getMessage();
    }

Now, when I upload text only it says me below error

Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

Now, my requirement is to upload Image file. So when I uncomment code for uploading image file it is not giving me any error but even not uploading image file.

like image 709
Shreyash Mahajan Avatar asked Aug 06 '15 04:08

Shreyash Mahajan


1 Answers

@kumar kundal The mechanism that you have explained is completely right. Below is the more detailed answer about uploading profile image to the Azure Server.

First create SAS url to upload Image(or any file) to blob storage:

String sasUrl = "";
// mClient is the MobileServiceClient
ListenableFuture<JsonElement> result = mClient.invokeApi(SOME_URL_CREATED_TO_MAKE_SAS, null, "GET", null);
Futures.addCallback(result, new FutureCallback<JsonElement>() {
        @Override
        public void onSuccess(JsonElement result) {
            // here you will get SAS url from server
            sasUrl = result; // You need to parse it as per your response
        }

        @Override
        public void onFailure(Throwable t) {
        }
    });

Now, you have sasURL with you. That will be something like the below string:

sv=2015-04-05&ss=bf&srt=s&st=2015-04-29T22%3A18%3A26Z&se=2015-04-30T02%3A23%3A26Z&sr=b&sp=rw&sip=168.1.5.60-168.1.5.70&spr=https&sig=F%6GRVAZ5Cdj2Pw4tgU7IlSTkWgn7bUkkAg8P6HESXwmf%4B

Now, you need to append the sas url with your uploading url. See below code in which I have appended the SAS url with my uploading request.

try {
        File source = new File(filePath); // File path
        String extantion = source.getAbsolutePath().substring(source.getAbsolutePath().lastIndexOf("."));
        // create unique number to identify the image/file.
        // you can also specify some name to image/file
        String uniqueID = "image_"+ UUID.randomUUID().toString().replace("-", "")+extantion; 
        String blobUri = MY_URL_TO_UPLOAD_PROFILE_IMAGE + sas.replaceAll("\"","");
        StorageUri storage = new StorageUri(URI.create(blobUri));
        CloudBlobClient blobCLient = new CloudBlobClient(storage);
        CloudBlobContainer container = blobCLient.getContainerReference("");
        CloudBlockBlob blob = container.getBlockBlobReference(uniqueID);
        BlobOutputStream blobOutputStream = blob.openOutputStream();
        byte[] buffer = fileToByteConverter(source);
        ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer);
        int next = inputStream.read();
        while (next != -1) {
            blobOutputStream.write(next);
            next = inputStream.read();
        }
        blobOutputStream.close();
        // YOUR IMAGE/FILE GET UPLOADED HERE
        // IF YOU HAVE FOLLOW DOCUMENT, YOU WILL RECEIVE IMAGE/FILE URL HERE 
    } catch (StorageException e) {
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (Exception e){
        e.printStackTrace();
    }

I hope this information help you lot for uploading the file using blob storage. Please let me know if you have any doubt apart from this. I can help in that.

like image 182
Shreyash Mahajan Avatar answered Oct 10 '22 01:10

Shreyash Mahajan