Skip to content

Bunnimage#31

Open
mjsigg wants to merge 10 commits intomainfrom
bunnimage
Open

Bunnimage#31
mjsigg wants to merge 10 commits intomainfrom
bunnimage

Conversation

@mjsigg
Copy link
Owner

@mjsigg mjsigg commented Jul 28, 2021

No description provided.

@ghost
Copy link

ghost commented Jul 29, 2021

Week 3 Step 3 ⬤⬤⬤◯◯◯◯◯◯ | 🕐 Estimated completion: 10-20 minutes

Codename Blob + 3RR0R Handling

This week, you will be going through steps to handle POST requests with no data.

✅ Task:

  • 1: Modify your function code so that it receives a header value called codename and uses it to name the image.
    • If an image isn't attached, return "Sorry! No image attached."
    • If an image is attached, return the output of the uploadFile() function
  • 🚀 Commit your updated function code to bunnimage/index.js to the bunnimage branch

🚧 Test Your Work

To test your work, use Postman to send a POST request without an image attached. You should see a response similar to the below:

{
  "body" : "Sorry! No image attached."
}

💡 Yay! This means the error was successfully caught.

1: Modify the Function

Handle Empty Data

Now we'll want to handle cases where the POST request's body happens to be empty. In your original module.exports function, before you parse the body, make sure it exists! Only then should you upload your file to blob storage.

❓ How do I catch empty POST requests?

Use an if-else statement to catch when body == null. If it's empty, set the responseMessage to "Sorry! No image attached." Otherwise, you can safely parse the body!

var responseMessage = ""
if (body == null) {
    responseMessage = "Sorry! No image attached."
} else {
    var password = // get the header called "codename"
    // use parse-multipart to parse the body
    // determine the file-type here!
    responseMessage = await uploadFile(parsedBody, ext, ?);
}

💡 Hint: responseMessage is what we're returning to the user as the output.

💡 Hint: You'll need to code the uploadFile function another parameter since it now has to receive the body, extension, AND filename!

Headers

Headers are yet another way to pass on information in HTTP requests. Here's how to access them:

var the_header_value = req.headers['insert_header_name'];

In this case, the header value will be used to name our picture.

counselorbot and others added 2 commits July 29, 2021 15:20
@ghost
Copy link

ghost commented Jul 29, 2021

Week 3 Step 4 ⬤⬤⬤⬤◯◯◯◯◯ | 🕐 Estimated completion: 10-20 minutes

Your time's up....

This week, you will be going through steps to create a Timer Trigger Function delete all files in your Blob storage container every 5 minutes. This allows for greater security for your users.

✅ Task:

  • 1. Create a Timer Trigger Function to delete all files in your Blob storage container every 5 minutes.
  • 2. Test your new Timer Trigger Function
  • 🚀 Commit your completed Timer Trigger to bunnimage-timer/index.js on the bunnimage branch and comment an expression that tells the Timer Trigger to run everyday at 6:23 AM.

💡 Tip: Cron expressions might help you with the last task.

🚧 Test Your Work

To test your work, use Postman to send a POST request with an image to your previous HTTP trigger function that will save your file within your blob. Recall that a successful save of your file will cause you to see a response similar to the below:

{
  "body" : "File Saved"
}

You should also double check that your file has been saved by navigating to your storage blobs.

Now run your timer trigger function and re-check your storage blobs - they should be gone. Your logs notifying you of the blobs' deletions should also be displayed in your trigger function's console.

💡 Yay! This means your timer trigger function worked.


1. Create your Timer Trigger Function

First, we'll need to create a new Azure Function that runs on a schedule with the Timer Trigger template.

  1. Create a new Function, naming it bunnimage-timer and select Timer trigger

image

  1. Leave the Schedule as 0 */5 * * * * to have the function be triggered every 5 minutes.

image

  1. Press enter on your keyboard.

1. Code your Timer Trigger Function

  • Reference your container string from your environment secrets
  • Reference the @azure/storage-blob package
  • Reference your account name
❓ How do I create the global variables above?

To reference the @azure/storage-blob package:

const { BlobServiceClient } = require("@azure/storage-blob");

To reference your connection string and account name:

const connectionstring = process.env["AZURE_STORAGE_CONNECTION_STRING"];
const account = "YOUR_ACCOUNT_NAME";

To delete all the blobs in the container, you can first list all the blobs, then loop through deleting each one as you go.

❓ How do I delete a blob?

First, your deleteBlob function will have to be asynchronous, so its signature should look like async function deleteBlob(filename).

Inside your function, create a BlobServiceClient object that will be used to create a container client.

const blobServiceClient = await BlobServiceClient.fromConnectionString(connectionstring);

Create a variable that references the name of the container that contains the file you want to delete.

const deletecontainer = "images";

Fetch the container with that name.

const deletecontainerClient = await blobServiceClient.getContainerClient(deletecontainer);

Within that container, fetch the block blob client that has the name of filename.

const deleteblockBlobClient = deletecontainerClient.getBlockBlobClient(filename);

Download the blob from the system and fetch a reference to the readable stream.

const downloadBlockBlobResponse = await deleteblockBlobClient.download(0); // 0 refers to the position of the blob to download

Delete the blob.

const blobDeleteResponse = deleteblockBlobClient.delete();

Set and return result with a progress statement on the blob's deletion.

result = {
    body : {
        deletename: filename,
        success: true
    }
};
return result;
❓ How do I call the `deleteBlob` function within `module.exports` and loop through existing blobs?

Exactly like the beginning of your deleteBlob function, you'll want to:

  1. Create a BlobServiceClient object using your connection string.
  2. Create a variable that references the name of the container that contains the file you want to delete.
  3. Fetch the container with that name.
const blobServiceClient = await BlobServiceClient.fromConnectionString(connectionstring);
const deletecontainer = "images";
const deletecontainerClient = await blobServiceClient.getContainerClient(deletecontainer);

Now you'll want to use the listBlobsFlat function to retrieve a reference to an enumeration of your blobs. Loop through these blobs, and delete each one.

for await (const blob of deletecontainerClient.listBlobsFlat()) {
    context.log('\t', blob.name);
    await deleteBlob(blob.name)
    // access the blob's name and call deleteBlob to delete it!
}

You can also add a log after your for loop that notifies you that all the blobs have been deleted.

context.log("Just deleted your blobs!")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant