Developing a File Sharing Platform using Azure ! (PRACTICAL)

Developing a File Sharing Platform using Azure ! (PRACTICAL)

Hey! I’m back with another blog, we will be exploring Azure in this medium.

Simran:?Hey! I have heard of Azure, and GCP, a lot but never explored them ??, Can you tell me how to develop something on Azure?

Me:?Yeah, sure once I have developed a file and message sharing platform using Azure, I can explain this.

Simran:?Yeah, this feels interesting can you tell me how to do this and what all we can learn from this?

Me:?We will see how we can create a group, send files/text msgs to Azure container, and how we can fetch and display them. We will also see how to list all conatiners/groups and manage them like deleting of groups and renaming them.

Simran:?Wow! Finally you come with something I wanted to know from long time! Thank You! Can we start?

Me:?Sure, Let’s start! So, first and foremost thing we need is Azure account and education email so that you can get some of the free credits and Azure portal.

No alt text provided for this image


Me:?Now let’s move on to this website[Azure for Students — Free Account Credit | Microsoft Azure] where you can fill on your credentials and register at the Azure portal, using this you will get?FREE Credits.

No alt text provided for this image


No alt text provided for this image

Me:?After registering you can log in to the Azure portal, now this is how our Azure portal looks like

No alt text provided for this image


Simran:

No alt text provided for this image


Me:?In the Azure portal in this block, we will see how I used?“Function app”, “Resource group”, “App Services”?and?“Storage accounts”?these 4 features from the Azure portal to develop our file or message sharing platform.

  1. Resource Group:?We will create first a resource group that will hold all of this stuffs like our function or storage accounts etc. You can say the resource group is the root of the tree and the rest parts will be either function app or storage accounts or different notes acting like a child or the leaf nodes under this root node.
  2. Functions App:?Using the functions app we will deploy our function trigger which can act as an API kind of thing where we will send our request to the server what we want.
  3. App Services:?Using App Services we will use to deploy our API and set environment variables to be used in our Function App
  4. Storage Account:?Using storage accounts we can create containers where our messages and our files will be stored.

10 Steps to Follow:

We will have to follow these 10 steps to make our tasks done


No alt text provided for this image

  1. We will create a resource group first of all, we need to write name of resource group what we want, and select a region then we will select Review and Create

No alt text provided for this image

2. We will create a Function App now, just we need to put a function app name and select our resource group, I chose Nodejs version 14, this may depend on one’s need, In hosting tab we need to write our storage app we need and click create new, This will create a Function App and a Storage App


No alt text provided for this image
No alt text provided for this image


3. We will create a Container inside our Storage App now, just we need to put a container name like here I have used genera, so this can act as public container and anyone can see contents inside this

No alt text provided for this image


4. Now We need to create a function inside our Function App, Let’s select HTTPTrigger Function, and paste the below code in the function file


No alt text provided for this image


const 
    Aborter,
    BlobURL,
    BlockBlobURL,
    BlobServiceClient,
    ContainerURL,
    ServiceURL,
    StorageURL,
    SharedKeyCredential,
    AnonymousCredential,
    TokenCredential,
    } = require("@azure/storage-blob");
  const { saveAs } = require('file-saver');
  var multipart = require('parse-multipart');
  const AZURE_STORAGE_CONNECTION_STRING = process.env["AZURE_STORAGE_CONNECTION_STRING"];
  
  module.exports = async function (context, req) {
      context.log('JavaScript HTTP trigger function processed a request.');
      try{
          const type = (req.query.type || req.body.type);
          const blobServiceClient = await BlobServiceClient.fromConnectionString(AZURE_STORAGE_CONNECTION_STRING);
          var list_of_container=[];
          for await (const contain of blobServiceClient.listContainers()) {
              list_of_container.push(contain.name);
          }
          async function streamToString(readableStream) {
              return new Promise((resolve, reject) => {
                  const chunks = [];
                  readableStream.on("data", (data) => {
                  chunks.push(data.toString());
                  });
                  readableStream.on("end", () => {
                  resolve(chunks.join(""));
                  });
                  readableStream.on("error", reject);
              });
              }
          
          if(type=="download"){
              const name = (req.query.name  || req.body.name);
              const itemname = (req.query.itemname  || req.body.itemname);
              var container=name?name:"securesharecc";
              const containerClient = await blobServiceClient.getContainerClient(container);
              const blobName=itemname?itemname:"sample.png";
              const blockBlobClient = containerClient.getBlockBlobClient(blobName);
              const downloadBlockBlobResponse = await blockBlobClient.download(0);
              console.log('\nDownloaded blob content...');
              var base64String=await streamToString(downloadBlockBlobResponse.readableStreamBody);
              console.log('\t', base64String);
              context.res = {
                      body: {data:base64String}
                  };
              context.done();
          }
   
          if(type=="create" ){
              //name new group name
              const name = (req.query.name  || req.body.name);
              var container=name?name:"securesharecc";
  
              if(!list_of_container.includes(container)){
                  const newGroupContainerClient = blobServiceClient.getContainerClient(name.toLowerCase());
                  const createContainerResponse = await newGroupContainerClient.create();
                  console.log(`Create container ${name} successfully`, createContainerResponse.requestId);
  
                  context.res = {
                      body: {status:200, msg: "created successfully!"}
                  };
                  context.done();
              }else{
                  
                  context.res = {
                      body: {status:500, msg: "Group Already Exists!"}
                  };
                  context.done();
              }
              
          }
          if(type=="delete" ){
                  const name = (req.query.name  || req.body.name);
                  var container=name?name:"securesharecc";
                  if(!list_of_container.includes(container)){
                      context.res = {
                          body: {status:404, msg: "No such group exists!"}
                      };
                      context.done();
                  }else{
                      const deleteGroupContainerClient = blobServiceClient.getContainerClient(name.toLowerCase());
                      const deleteContainerResponse = await deleteGroupContainerClient.delete();
                      console.log("Container was deleted successfully. requestId: ", deleteContainerResponse.requestId);
                      context.res = {
                          body: {status:200, msg: "deleted successfully!"}
                      };
                      context.done();
                  }
          }
          if(type=="listall" ){
              context.res = {
                  body: {status:200, data: list_of_container }
              };
              context.done();
          }
          if(type=="listallcontent" ){
              const name = (req.query.name  || req.body.name);
              console.log('\nListing blobs...');
              var container=name?name:"securesharecc";
              const containerClient = await blobServiceClient.getContainerClient(container);
              var list_content=[];
              for await (const blob of containerClient.listBlobsFlat()) {
                  list_content.push(blob.name);
              }
              context.res = {
                  body: {status:200, data: list_content }
              };
              context.done();
          }
          function generateRandomNDigits(n){
              return Math.floor(Math.random() * (9 * (Math.pow(10, n)))) + (Math.pow(10, n));
          }
          if(type=="upload" ){
                  const name = (req.query.name  || req.body.name);
                  var uploadtype = (req.query.uploadtype  || req.body.uploadtype);
                  uploadtype=uploadtype?uploadtype:"text";
                  var container=name?name:"securesharecc";
                  const containerClient = await blobServiceClient.getContainerClient(container);
  
                  if(uploadtype=="text"){
                      const msg = (req.query.msg  || req.body.msg);
                      var random=generateRandomNDigits(1)+generateRandomNDigits(3)+generateRandomNDigits(5)+generateRandomNDigits(4)+generateRandomNDigits(7);
                      random=random.toString();
                      const blobName = 'text'+random+'.txt';
                      const blockBlobClient = containerClient.getBlockBlobClient(blobName);
                      const data = msg;
                      const uploadBlobResponse = await blockBlobClient.upload(data, data.length);
                      console.log("Blob was uploaded successfully. requestId: ", uploadBlobResponse.requestId);
                      context.res = {
                          body: {status:200, msg: "uploaded msg successfully!", value:data, filename:blobName}
                      };
                      context.done();
                  }
                  
                  if(!list_of_container.includes(container)){
                      context.res = {
                          body: {status:404, msg: "No such group exists!"}
                      };
                      context.done();
                  }else{
                      var bodybuffer = Buffer.from(req.body);
                      var boundary = multipart.getBoundary(req.headers['content-type']);
                      var parts = multipart.Parse(bodybuffer, boundary);
                      const blobName = parts[0].filename;
                      const blockBlobClient = containerClient.getBlockBlobClient(blobName);
                      const uploadBlobresponse = await blockBlobClient.upload(parts[0].data,parts[0].data.length);
                      context.res = {
                          body: {status:200 , msg:"uploaded successfully!" , name: parts[0].filename, type: parts[0].type, data: parts[0].data.length}
                      };
                      context.done();
                  }    
              
              //name which container to upload
          }
      }catch(err){
          context.res = {
              body: {status: 500, msg:err}
          };
          context.done();
      }
      
      context.res = {
          body: {status: 500, msg:"ERR! Try something else!"}
      };
      context.done();
  }        

5. Now you need to copy the function URL from the functions app, we will be using this to hit an API and fetch results.

No alt text provided for this image


6. Now we need to install some of the npm package so that we can run it smoothly. We need to select our Function App and go in Advanced Tools Section

No alt text provided for this image

7. Now from Debug Console we can select CMD, and go inside?“site/wwwroot/HTTPTrigger1”?folder, then we can start with these commands

npm init
npm i @azure/storage-blob
npm i parse-multipart
npm i file-saver


No alt text provided for this image


8. Now we need to set an environment variable?“AZURE_STORAGE_CONNECTION_STRING”?which we used in our code, we need to go to our storage account and select “Access Keys”?Section, and select and copy?Key1 connection string

No alt text provided for this image


9. We need to paste this key on our Function App inside Configuration


No alt text provided for this image

10. Ouff Finally we did this, we need to just make a request to this HTTPTrigger Function and our task is done.

No alt text provided for this image


We will create our final local html file to fetch/upload details make sure you replace HTTPTrigger Function URL



<!DOCTYPE html
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>File sharing Azure</title>
</head>
<body>
    <!-- 
        Resource Group: fileshare
        storage a/c name: filesharedb
        container: general
    -->
    <!-- UPLOAD SECTION -->
    <p>Example of HTTPTRIGGER Function URL is https://myapp.azurewebsites.net/api/HttpTrigger1?code=SAMPLEdfsd/ZT24CSAMPLEbuApg==</p>
    <h1>MSG UPLOAD TO AZURE STORAGE BLOB: (CONTAINER: "general" Function: "HttpTrigger1" Type:"Upload"  ResourceGrp: "fileshare")</h1>
    <form method="post"  id="msgform" enctype="multipart/form-data">
        <label  for="msgtext">Write Text</label>
        <input type="text" id="msgtext" name="msgtext"><br><br>
        <input type="submit" onclick="return msgUploadFunction();">
    </form>
    <h1>File UPLOAD TO AZURE STORAGE BLOB: (CONTAINER: "general" Function: "HttpTrigger1" Type:"Upload"  ResourceGrp: "fileshare")</h1>
    <form method="post" action="YOUR_HTTPTRIGGER_URL&type=upload&name=general&uploadtype=other" enctype="multipart/form-data">
        <label  for="myfile">Select File</label>
        <input type="file" id="myfile" name="filename"><br><br>
        <input type="submit">
    </form>
    <!-- NEW GROUP CREATION SECTION -->
    <h1>CREATE A GROUP IN AZURE STORAGE BLOB: (CONTAINER: "write_new_group_name" Function: "HttpTrigger1" Type:"Create" ResourceGrp: "fileshare")</h1>
    <form method="post" id="new_group_form"  enctype="multipart/form-data">
        <label  for="new_group_name">Write Name of the Group:</label>
        <input type="text" id="new_group_name" name="new_group_name"><br><br>
        <input type="submit" onClick="return newGroupCreateFunction();">
    </form>
    <!-- GROUPA UPLOAD SECTION -->
    <h1>GROUPA File UPLOAD TO AZURE STORAGE BLOB: (CONTAINER: "groupa" Function: "HttpTrigger1" Type:"Upload"  ResourceGrp: "fileshare")</h1>
    <form method="post" action="YOUR_HTTPTRIGGER_URL&type=upload&name=groupa&uploadtype=other" enctype="multipart/form-data">
        <label  for="myfile">Select File</label>
        <input type="file" id="myfile" name="filename"><br><br>
        <input type="submit">
    </form>    
    <!-- ANY GROUP UPLOAD SECTION -->
    <h1>(ENTER GROUP NAME) File UPLOAD TO AZURE STORAGE BLOB: (CONTAINER: "groupa" Function: "HttpTrigger1" ResourceGrp: "fileshare")</h1>
    <form method="post" id="your_group_form"  enctype="multipart/form-data">
        <label  for="your_group_name">Write Name of Your Group:</label>
        <input type="text" id="your_group_name" name="your_group_name"><br><br>
        <label  for="myfile">Select File</label>
        <input type="file" id="myfile" name="filename"><br><br>
        <input type="submit" onClick="return yourGroupUploadFunction();">
    </form>
    <!-- LIST ALL GROUPS -->
    <h1>LIST ALL CONTAINERS/GROUPS INSIDE AZURE STORAGE BLOB: ( Function: "HttpTrigger1" ResourceGrp: "fileshare")</h1>
    <form method="post" id="list_groups_form" action="YOUR_HTTPTRIGGER_URL&type=listall" enctype="multipart/form-data">
        <input type="submit" value="Fetch ALL Groups">
    </form>
    <h1>LIST ALL files in a group INSIDE AZURE STORAGE BLOB: ( Function: "HttpTrigger1" ResourceGrp: "fileshare")</h1>
    <form method="post" id="list_group_content_form"  enctype="multipart/form-data">
        <label  for="list_group_content">List Contents of Group(Group Name):</label>
        <input type="text" id="list_group_content" name="list_group_content"><br><br>
        <input type="submit" value="Fetch ALL Contents of Group" onClick="return listGroupContentFunction();">
    </form>

    <h1>DOWNLOAD A FILE FROM AZURE STORAGE BLOB: (GROUP NAME: "write_name" (default: "general") Function: "HttpTrigger1" Type:"Upload"  ResourceGrp: "fileshare")</h1>
    <form method="post" id="download_group_form"  enctype="multipart/form-data">
        <label  for="download_group_name">Write Name of the Group:</label>
        <input type="text" id="download_group_name" name="download_group_name"><br><br>
        <label  for="download_item_name">Write item number of the file to download:</label>
        <input type="text" id="download_item_name" name="download_item_name"><br><br>
        <input type="submit" onClick="return downloadGroupCreateFunction();">
    </form>
    
    <h1>DELETE GROUP ON AZURE STORAGE BLOB: (CONTAINER: "write" Function: "HttpTrigger1" Type:"Upload"  ResourceGrp: "fileshare")</h1>
    <form method="post" id="delete_group_form"  enctype="multipart/form-data">
        <label  for="delete_group_name">Write Name of the Group:</label>
        <input type="text" id="delete_group_name" name="delete_group_name"><br><br>
        <input type="submit" onClick="return deleteGroupCreateFunction();">
    </form>
    
    <script>
        function listGroupContentFunction(){            
            var action_src = "YOUR_HTTPTRIGGER_URL&type=listallcontent&name="+document.getElementsByName("list_group_content")[0].value;
            var msgform = document.getElementById('list_group_content_form');
            msgform.action = action_src;
            msgform.submit();
        }
        function msgUploadFunction(){            
            var action_src = "YOUR_HTTPTRIGGER_URL&type=upload&name=general&uploadtype=text&msg="+document.getElementsByName("msgtext")[0].value;
            var msgform = document.getElementById('msgform');
            msgform.action = action_src;
            msgform.submit();
        }
        function downloadGroupCreateFunction(){
            var action_src = "YOUR_HTTPTRIGGER_URL&type=download&name=" + document.getElementsByName("download_group_name")[0].value+"&itemname="+document.getElementsByName("download_item_name")[0].value;
            var download_group_form = document.getElementById('download_group_form');
            alert(action_src);
            download_group_form.action = action_src;
            download_group_form.submit();
        }
        function deleteGroupCreateFunction(){
            var action_src = "YOUR_HTTPTRIGGER_URL&type=delete&name=" + document.getElementsByName("delete_group_name")[0].value;
            var delete_group_form = document.getElementById('delete_group_form');
            delete_group_form.action = action_src;
            delete_group_form.submit();
        }
        function newGroupCreateFunction(){
            var new_group_name=document.getElementById("new_group_name").value;
            var action_src = "YOUR_HTTPTRIGGER_URL&type=create&name=" + document.getElementsByName("new_group_name")[0].value;
            var new_group_form = document.getElementById('new_group_form');
            new_group_form.action = action_src;
            new_group_form.submit();
        }
        function yourGroupUploadFunction(){
            var your_group_name=document.getElementById("your_group_name").value;
            var action_src = "YOUR_HTTPTRIGGER_URL&type=upload&uploadtype=other&name=" + document.getElementsByName("your_group_name")[0].value;
            var your_group_form = document.getElementById('your_group_form');
            your_group_form.action = action_src;
            your_group_form.submit();
        }
    </script>

</body>
</html>        

This is how our UI looks like with multiple sections

No alt text provided for this image


This is how we get responses after a function works properly

No alt text provided for this image

Me:?Finally its done! Now one can easily create and manage containers, and how we can upload and fetch files and text messages easily using Azure using our local setup.

Simran:?Good Morning! Are we done? ??

Me:?Sorry this was intensive task and need so much explanation, I skipped much but still I guess you learned how to do this? Hope u enjoyed!

Simran:?Thank You! Finally I can work on Azure now! Thanks a LOT!

Me:?Thank you everyone for reading this article! Do like if you like this! ??

要查看或添加评论,请登录

Shubham Kumar Gupta的更多文章

社区洞察

其他会员也浏览了