GithubHelp home page GithubHelp logo

daniel-krzyczkowski / cars-island-on-azure Goto Github PK

View Code? Open in Web Editor NEW
288.0 27.0 145.0 11.23 MB

Cars Island is a fake car rental company which used Microsoft Azure cloud services to implement the system for managing car renting.

License: MIT License

CSS 20.25% HTML 16.43% C# 63.32%

cars-island-on-azure's Introduction

Cars Island Car Rental on the Azure cloud

- This repository contains sample project where different Azure cloud services were used

- Some of the concepts were simplified to make it possible to deliver complete solution

- On my tech blog there is a series of articles where I described implementation details

CarsIsland0.jpg

Cars Island is a fake car rental company which used Microsoft Azure cloud services to implement the system for managing car renting.

If you like this content, please give it a star! github-start.png

Use cases are following:

  1. Customer can create account (register)
  2. Customer can sign in
  3. Customer can display list of all available cars
  4. Customer can make a reservation for a specific car (if it is not already reserved by other customer)
  5. Customer can send new enquiry and attach the file

Here are the screenhots of the web app together with the confirmation email template:

Image not found

Image not found

Image not found

Image not found

Image not found

Image not found

Image not found

There is also Open API definition available for the Cars Island Web API:

Image not found

General overview of solution architecture

Solution architecture

Below diagram presents Cars Island Car Rental system architecture.

Image not found

Azure Active Directory B2C

Azure Active Directory B2C is an identity service in the Azure cloud that enables user authentication and management. Implementing own identity service can be challenging. Try to think about data storage, secure connections, or token generation and validation. With Azure AD B2C, adding user authentication is much easier. In the Cars Island solution users can create accounts and login to access some of the functionalities. What is more - with Azure AD B2C, login, registration, password reset, or profile edit pages can be customized and branded (like with the company logo or background). You do not have to implement login, or registration views yourself.

Azure Key Vault

Security is a very important aspect of every project. Secrets and credentials should be stored in the secure store. This is why Azure Key Vault is used in the Cars Island solution. Parameters like connection string to the database or storage key are stored in the Azure Key Vault instance.

Azure Application Insights

Tracking issues in cloud solutions can be challenging. Collecting logs and detecting bugs can be hard. This is why it is good to use an Application Performance Management service like Azure Application Insights. With this Azure cloud service, we can log all events and errors that occure in our solution. Azure Application Insights provides SDKs in many languages (like C# oraz Java) so we can easily integrate them with our application. All logs are then available in the Azure portal, where rich dashboards are displayed with collected log data.

Azure Web Apps with App Service Plans

Hosting web applications in the Azure cloud is much easier with Azure Web Apps. Cars Island Web portal is written with Blazor framework and Cars Island API is written with ASP .NET Core. These web applications are hosted using Azure Web Apps. Azure App Service Plans provide a way to scale in and out, up and down so you can apply automatic scale when there is higher load and traffic. With Azure Web Apps we can also use custom SSL certificates.

Azure Function Apps

Azure Function Apps are serverless services available in the Azure cloud. They are ideal to be used as event handlers for processing events. It is important to mention the cost - you only pay for this service once it is executed. Up to 1 million executions is for free. In the Cars Island solution, Azure Function App was used to handle events related to sending car's reservation confirmation emails once custom complete reservation in the web portal. This Function App is triggered once there is a new message in the Azure Service Bus queue.

Azure Service Bus

Azure Service Bus service is a cloud messaging service. With Azure Service Bus we can build reliable and elastic cloud apps with messaging. In the Cars Island solution, Azure Service Bus queues were used to queue car's reservation confirmations to send emails to customers. Once car's reservation is completed in the web portal, information is passed to the API and saved in the database. After this process, there is new message sent to the queue. Then Azure Function is triggered and new email is sent using Azure SendGrid Service.

Azure SendGrid

Azure SendGrid service enables sending customized emails. It is great because we can create email templates but also it provides SDK that we can use to implement emails sending in the source code. Up to 25.000 emails, it is free.

Azure Cosmos DB

Azure Service Bus is a globally distributed database available in the Azure cloud. Data about all cars and reservations is stored in this database in the Cars Island solution.

Azure Storage Account

Azure Storage Account is one of the oldest services available in the Azure cloud. It provides an easy way to store different kind of files using Blob Storage. In the Cars Island solution, it is used to store car images that are then displayed in the web portal.

Azure API Management

Azure API Management is a service that works as a gateway to different APIs behind it. With Azure API Management you can secure your APIs. It provides a different kind of policies so for instance we can implement throttling or validate tokens. In the Cars Island solution, it was used to protect access to Cars Island API.

Technology used to develop Web API, Mail Sender App and Web portal

Cars Island web application was developed with Blazor Server. (.NET 5.0)

Cars Island Web API was developed with ASP .NET Core (.NET 5.0)

Cars Island Mail Sender Function App was developed with .NET Core (3.1)

Repository structure

In the src folder there are five sub-folders:

  1. ad-b2c-custom-policies - this one contains Azure AD B2C custom policies files together with branding files
  2. arm-templates - this one contains Azure Resource Manager templates to create all required Azure services
  3. func-app - this one contains source code of the Function App responsible for sending email confirmations when car is reserved
  4. web-api - this one contains ASP .NET Core Web API project
  5. web-app - this one contains Blazor Web App project
  6. send-grid-mail-template - this one contains SendGrid email template for car reservation confirmation

cars-island-on-azure's People

Contributors

daniel-krzyczkowski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cars-island-on-azure's Issues

azure configurations for Cars Island

Hi!

I've read your article about the deployment of Cars Island on Azure but I don't see how you have configured, step by step, the services that you use. I'm totally new to Azure and we are beginning to evaluate the possibilitiy to migrate our web sites there are you article is very important to me but it presume that people already know Azure.

Would it be possible to put a little article to explain the steps to achive that?

thank you very much!

Token request status returned 404

Hi Daniel,

Awesome collection of articles and a ton of useful information. I'm struggling with the article steps https://daniel-krzyczkowski.github.io/Cars-Island-ASP-NET-Core-API-Secured-By-Azure-AD-B2C/ , in particular the request for the token.

The part that is somewhat vague is where does the policy name come from and in particular where is this configured in the Azure AD B2C? I see that in the config you have policy name set to B2C_1A_SignUpOrSignin, and the token request would be constructed as follows (I used the docs to check the format https://docs.microsoft.com/en-gb/azure/active-directory-b2c/access-tokens)
https://.b2clogin.com/.onmicrosoft.com//oauth2/v2.0/authorize?client_id=xxxx etc

I get an http 404 as I have not configured a policy and nor do I see where to do this. I looked at the docs https://docs.microsoft.com/en-gb/azure/active-directory-b2c/user-flow-overview and the refer to User flows and Custom policy but I do not see the User flows menu anywhere on the Azure AD B2C configuration.

Thank you.

Help - Getting Error 500 when I include the access token

hello Daniel,

Tks for providing this example -- it has been very educational so far!

I have managed to replicate the api and had been trying to use it. so far, using the swagger interface, I'm able to execute cars get all without using any authorization (since it allowed anonymous).

To execute the post car reservation, I first generated a token using this link: https://<tenantname>.b2clogin.com/<tenantname>.onmicrosoft.com/oauth2/v2.0/authorize?p=<userflowname>&client_id=<clientid>&nonce=defaultNonce&redirect_uri=https%3A%2F%2Fjwt.ms&scope=https://<tenantname>.onmicrosoft.com/<clientid>/<scopename>&response_type=code&prompt=login. From there, I get a JWT, which I then fed into a post command: https://<tenantname>.b2clogin.com/<tenantname>.onmicrosoft.com/{{policy-name}}/oauth2/v2.0/token, with a body that contained:
grant_type=authorization_code &client_id=<application-ID> &scope=https://<tenant-name>.onmicrosoft.com/api/read &code=<jwt from previous call>.. &redirect_uri=https://jwt.ms &client_secret=<generatedsecretforapi>

This then returned an access token, which when I fed it into jwt.ms I do see the "access_as_user" scope.
image

I then proceeded to enter "Bearer " with the access token using the Authorize button on top.

However, when I try to post the car reservation, I get the 500 error :

{
  "Id": "5b5aeb9f-eaec-4f5b-b056-4dd8d34e9be2",
  "Status": 500,
  "Code": null,
  "Links": null,
  "Title": "Some kind of error occurred in the API.  Please use the id and contact our support team if the problem persists.",
  "Detail": null
}

the command shown was:

curl -X POST "https://localhost:44375/api/CarReservation" -H  "accept: */*" -H  "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1jNTdkTzZRR1RWQndhTmsifQ.eyJpc3MiOiJodHRwczovL291dHNpZGU3MjU2MjIxLmIyY2xvZ2luLmNvbS8zYTFlNzYyOS05OGUzLTRmMjEtODc4OC04NzI1MGNlNzQ3OTEvdjIuMC8iLCJleHAiOjE2MTQ5NzI3MDgsIm5iZik2OTEwOCwiYXVkIjoiZjVlYTdiYjUtODE4OS00MTgyLWJmZTQtNmZjZGZhMzNiNTRiIiwiaWRwX2FjY2Vzc190b2tlbiI6InlhMjkuYTBBZkg2U01CaEh1UjRoVDFUbzdnTWZLb3FxWTVnRUtVMlNsV1lxcTM0SHdqcVNYLVEzOTlMUGpUVmhjWEYtYUl2aGVZVGxRbW8wTkhjcUs2a0tiR0lwMFFTWkJia1lqd1BYb1FaVmNjQ3I1cDhNbUdjbXVkX0xLeGdmOWtDT3RmMG82OUQxY2E1YVdoWEtLS0RyTUlZeVl2SFFuU3JrZyIsImdpdmVuX25hbWUiOiJMYXdyZW5jZSAobGF3cmVuY2VvbmcuZGV2KSIsImZhbWlseV9uYW1lIjoiT25nIiwibmFtZSI6Ikxhd3JlbmNlIE9uZyIsImlkcCI6Imdvb2dsZS5jb20iLCJvaWQiOiJkZWJjwN2VhNTA3MTA4MDUiLCJjaXR5Ijoib3R0YXdhIiwic3RhdGUiOiJPTiIsImVtYWlscyI6WyJsYX9uZy5kZXZAZ21haWwuY29tIl0sInRmcCI6IkIyQ18xX3NpZ251cF9zaWduaW4iLCJub25jZSI6ImRlZmF1bHROb25jZSIsInNjcCI6ImFjY2Vzc19hc191c2VyIiwiYXpwIjoiZjVlYTdiYjUtODE4OS00MTgyLWJmZTQtNmZjZGZhMzNiNTRiIiwidmVyIjoiMS4wIiwiaWF0IjoxNjE0OTY5MTA4I6MTYxNDfQ.U9ux_gPjjf5gv6KLyKDQ9VwONLcwL0WLB3mssg5kQfpyEjjqjQ3qwMtJwBwuaOyhnFqwvoynJxWOK6rRBFOEnk2qn6hzmYmvz4c1DA_sj1JqHQoL9WriuhVKvwijsjvZTU2YS03YzJjLTRjZjgtYWU2Ny0wN2VhNTA3MTA4MDUiLCJzdWdyZW5jZWIiOiJkZWJjZTU2YS03YzJjLTRjZjgtYWU2Ny070NTlucEk87SGbDXYl2bVFF8pbk6C8qWxF_p1AlAyZbfqqZI_ryw4oEn3Bh8TYWEHuaTEcvHvgXp_yVzz9KpK5IYkdwHEtUDlGT2orLsOcIfutqz1-0cvp5Se2NfOF7ASvJ0ZSTCr_3Xo_prwDfUtXYk7uLDJnxyTKHkCVkEjhKTPTzDKVL66ic6CErraaQTHqe9ugKx2YJAcbt-iqkit-w" -H  "Content-Type: application/json" -d "{\"carId\":\"5b5aeb9f-eaec-4f5b-b056-4dd8d34e9be2\",\"rentFrom\":\"2021-03-05T19:29:00.915Z\",\"rentTo\":\"2021-03-06T19:29:00.915Z\"}"

interestingly, the cars get all will also fail now when I include the token -- the swagger interface will include the header as well even though it doesn't seem like it's needed.

would you have any suggestions on what I can do to alleviate this issue?

thanks again
Lawrence

Article typo or issue?

Hi Daniel,

I'm back for another question, in the article https://daniel-krzyczkowski.github.io/Cars-Island-ASP-NET-Core-API-Integration-With-Azure-Cosmos-DB/ you use TryAddSingleton to inject the dataservices.

In the next article : https://daniel-krzyczkowski.github.io/Cars-Island-ASP-NET-Core-API-Integration-With-Azure-Storage-Accont/ you are in the same case and you mention the AddSingleton
I have used services.AddSingleton with implementationFactory instead of just using services.AddSingleton.

Why not using the TryAddSingleton in both? is it a typo or a specific needs for storage service?

Thanks!

Idempotency Concern of the Mail Sender Function

Description:

I would like to kindly bring attention to a potential issue in the Mail Sender function, which is invoked when a ServiceBus message arrives at the "reservation" queue. This function calls the SendGrid API to send a car reservation confirmation to a customer's email. However, the email sending is not idempotent; Suppose the ServiceBus-triggered function crashes after successfully sending an email (but before acknowledging the ServiceBus that the function has finished), when the function is retried, another email will be sent by SendGrid. In other words, ServiceBus-triggered function has at-least-once execution guarantee, so in this function, email sending could happen multiple times.

Suggested Fix:

Although there's no serious harm in sending two almost identical emails, this duplicate sending due to untimely retries can be prevented. Specifically, SendGrid provides the Email Activity Feed API that one can use to query whether the email has been sent (in a previous execution) before actually sending the email. Suppose the query finds no email has been sent, then go ahead and send the email. If querying the SendGrid service finds the email has been sent, end the execution without sending the email again.

Thank you for considering this issue. I hope this suggestion could help improve the idempotency and user experience of the Mail Sender function. Please feel free to reach out if you have any questions or concerns.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.