Azure Functions v2 with .NET Core
This example shows simplified billing system in serverless architecture.
Comprehensive guide describing exactly the architecture, applied design patterns and technologies can be found on our blog in article Azure Functions 2.0 – real world use case for serverless architecture.
We encourage you to read, because in this README there is only a substitute for all information.
-
User uploads CSV file (with name structure
CLIENTCODE_YEAR_MONTH_activeList.txt.
) with Beneficiaries (the sample file is located in thedata-examples
folder) to a specific data storage -active-lists
Azure Blob Container. -
The above action triggers a function (
GenerateBillingItemsFunc
) that is responsible for:- generating billing items (using prices from an external database - CosmosDB
crm
database,prices
collection) and saving them in the tablebillingItems
; - sending message about the need to create a new invoice to
invoice-generation-request
;
- generating billing items (using prices from an external database - CosmosDB
-
When a new message appears on the queue
invoice-generation-request
, next function is triggered (GenerateInvoiceFunc
). This function creates domain objectInvoice
and save this object in database (CosmosDBcrm
database,invoices
collection) and send message to queues:invoice-print-request
andinvoice-notification-request
. -
When a new message appears on the queue
invoice-print-request
, functionPrintInvoiceFunc
is triggered. This function uses external engine to PDF generation - JsReport and saves PDF file in BLOB storage. -
When a new message appears on the queue
invoice-notification-request
, functionNotifyInvoiceFunc
is triggered. This function uses two external systems - SendGrid to Email sending and Twilio to SMS sending.
Tutorial from scratch to run locally
-
Install and run Microsoft Azure Storage Emulator.
-
Install and run CosmosDB Emulator. Check this on
https://localhost:8081/_explorer/index.html
. -
Create in Emulator blob Container
active-lists
. -
Upload
ASC_2018_02_activeLists.txt
file fromdata-examples
folder toactive-lists
blob. -
Create CosmosDB database
crm
and in this database create collections:prices
,invoices
. -
Add CosmosDB properties
PriceDbUrl
andPriceDbAuthKey
tolocal.appsettings.json
inPriceDbInitializator
andGenerateBillingIemsFunc
. You can copy this properties fromAzure CosmosDB Emulator
- check point 2 (URI and Primary Key). -
Run project
PriceDbInitializator
to init collectionprices
incrm
database. -
Add CosmosDB connection string as
cosmosDb
tolocal.settings.json
inGenerateInvoiceFunc
. You can copy this string fromAzure CosmosDB Emulator
- check point 2 (Primary Connection String). -
Create an account in SendGrid and add property
SendGridApiKey
tolocal.settings.json
inNotifyInvoiceFunc
. -
Create an account in Twilio and add properties
TwilioAccountSid
TwilioAuthToken
tolocal.settings.json
inNotifyInvoiceFunc
. -
Run JsReport with Docker:
docker run -p 5488:5488 jsreport/jsreport
. Check JsReport Studio onlocalhost:5488
. -
Add JsReport url as
JsReportUrl
tolocal.settings.json
inPrintInvoiceFunc
project. -
Add JsReport template with name
INVOICE
and content:
<h1>Invoice {{invoiceNumber }}</h1>
<h3>Customer: {{ customer }}</h3>
<h3>Address: 00-101 Warszawa, Chłodna 21</h3>
<h3>Description: {{ description }}</h3>
<h3>Details:</h3>
<table width="90%" border="1" bgcolor="#C0C0C0" align="center">
<tr>
<th>Item</th>
<th>Price</th>
</tr>
{{#each lines}}
<tr>
<td>{{ itemName }}</td>
<td align="right">{{ cost }}</td>
</tr>
{{/each}}
<tr>
<td>
<strong>Total</strong>
</td>
<td align="right">
<strong>{{ totalCost }}</strong>
</td>
</tr>
</table>
Example JSON for INVOICE template:
{
"customer": "ASC",
"invoiceNumber": "ASC/10/2018",
"description": "Invoice for insurance policies for 10/2018",
"lines": [
{
"itemName": "Policy A",
"cost": 2140.0
},
{
"itemName": "Policy B",
"cost": 1360.0
}
],
"totalCost": 3500.0
}
All properties in one local.appsettings.json
:
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"PriceDbUrl": "https://localhost:8081",
"PriceDbAuthKey": "AUTH_KEY",
"cosmosDb": "AccountEndpoint=https://localhost:8081/;AccountKey=AUTH_KEY",
"JsReportUrl": "http://localhost:5488",
"SendGridApiKey": "SEND_GRID_API_KEY",
"TwilioAccountSid ": "TWILIO_ACCOUNT_SID",
"TwilioAuthToken": "TWILIO_AUTH_TOKEN"
}
}
Monitoring examples
Application Map for all function in one project:
Application Map for functions in separated projects:
End-to-end transaction details:
Tips & Tricks
-
CSV file is working for client code
ASC
(filename:ASC_2018_12_activeList.txt
). If you want run functions for another client code, you must simulate prices in database. Check projectPriceDbInitializator
, fileProgram.cs
, methodAddDoc
. -
Remember that you must use Twilio Test Credentials.
- Microsoft Azure Storage Emulator with all created storages: