This assignment requires the use of Visual Studio 2022 or Visual Studio for Mac. You are provided with two ASP.NET projects (Version 7.0, C#):
1. A Web application similar to that for the previous assignment, but with some changes in its backend processing.
2. A project that contains three functions to be deployed in Azure Functions.
In the previous assignment, operations were performed in a synchronous fashion. For example, uploading an image consisted of adding a metadata record to SQL Database, and then uploading the image itself to blob storage. The Web application does not respond back to user until all of these steps are completed. Similarly, when an administrator approves an image, the application does not respond until the database record has been updated.
In this assignment, we introduce intermediate queues for asynchronous processing. When an image is submitted for upload, the application responds immediately back to the user while the image is uploaded to blob storage. No attempt is made at this point to add a metadata record to the database. Instead, the metadata is included with the image upload. Completion of the upload triggers an Azure function, UploadResponder, that inserts the metadata into a message and adds this message to an Azure storage queue called approval-requests.
When an image approver reviews the images awaiting approval, the metadata for these images is taken from the approvals request queue. If an image is approved, its metadata is added to another queue, approved-images. Insertion of a message into this queue triggers an Azure function, ApproveResponder, that inserts the metadata for the image into the database. If an image is not approved, its metadata is added to another queue, rejected-images. Insertion of a message into this queue triggers an Azure function, RejectResponder, that deletes the image from blob storage.
For testing purposes, you will want to use the Consumption Plan for Azure Functions. However, this does not support the use of SQL Database in a function. So, although we continue to use SQL Database to store user information for authentication and authorization, we store the image metadata in Table storage1.
The partition key for an image’s metadata record is the primary key for the user that uploaded that image, so that metadata for all images for a user are stored in the same partition. This means that the URI for an image is of the form:
https://.../Images/action-name/user-key/image-key
1 We could use Cosmos DB to store both user data and image metadata. We use Table storage for simplicity, because it is supported for local development in the Azurite storage emulator.
The routing logic for this is specified in the application builder:
app.MapControllerRoute( name: "image",
pattern: "Images/{action}/{userId}/{id}", defaults: new { controller = "Images" });
This is then used in tag helpers to specify links to actions for images:
<a asp-action="Details" asp-route-userId="@image.getUserId()"
asp-route-id="@image.getId()">Details</a>
getUserId() and getId() are helper functions in an image entity object, returning its partition key and row key, respectively.
In the previous assignment, the Web application waited for an image to finish uploading before providing a response to the user:
await blobClient.UploadAsync(...);
In this assignment, in the spirit of serverless computing, the application may respond to the user immediately, while the upload proceeds in the background, with any exceptions in background processing logged on that thread:
blobClient.UploadAsync(...)
.ContinueWith(t => logger.LogError(t.Exception.Message), TaskContinuationOptions.OnlyOnFaulted);
return Task.CompletedTask;
The Azure functions are annotated to specify their triggers, and their queue outputs where appropriate. For example, the function that responds to uploads to blob storage is given by:
[Function("UploadResponder")] [QueueOutput("approval-requests")] public string Run(
[BlobTrigger("images/{blobname}",
Connection = "StorageConnectionString")] string myBlob, string blobname,
BlobProperties blobProperties, IDictionary<string,string> metadata, FunctionContext _context)
The connection string is specified as the value of the StorageConnectionString property in local.settings.json. This descriptor is only used for development and is not included in a deployment in the cloud, so the connection string must be specified as the value of the StorageConnectionString environment variable when the
function is deployed. When this function returns a string, it is inserted as the payload of a message in the specified queue. Azure queues require that the payload be an ASCII string representing a Base64 encoding:
DescriptionIn this final assignment, the students will demonstrate their ability to apply two ma
Path finding involves finding a path from A to B. Typically we want the path to have certain properties,such as being the shortest or to avoid going t
Develop a program to emulate a purchase transaction at a retail store. Thisprogram will have two classes, a LineItem class and a Transaction class. Th
1 Project 1 Introduction - the SeaPort Project series For this set of projects for the course, we wish to simulate some of the aspects of a number of
1 Project 2 Introduction - the SeaPort Project series For this set of projects for the course, we wish to simulate some of the aspects of a number of