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-examplesfolder) to a specific data storage -active-listsAzure Blob Container. -
The above action triggers a function (
GenerateBillingItemsFunc) that is responsible for:- generating billing items (using prices from an external database - CosmosDB
crmdatabase,pricescollection) 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 objectInvoiceand save this object in database (CosmosDBcrmdatabase,invoicescollection) and send message to queues:invoice-print-requestandinvoice-notification-request. -
When a new message appears on the queue
invoice-print-request, functionPrintInvoiceFuncis 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, functionNotifyInvoiceFuncis triggered. This function uses two external systems - SendGrid to Email sending and Twilio to SMS sending.
-
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.txtfile fromdata-examplesfolder toactive-listsblob. -
Create CosmosDB database
crmand in this database create collections:prices,invoices. -
Add CosmosDB properties
PriceDbUrlandPriceDbAuthKeytolocal.appsettings.jsoninPriceDbInitializatorandGenerateBillingIemsFunc. You can copy this properties fromAzure CosmosDB Emulator- check point 2 (URI and Primary Key). -
Run project
PriceDbInitializatorto init collectionpricesincrmdatabase. -
Add CosmosDB connection string as
cosmosDbtolocal.settings.jsoninGenerateInvoiceFunc. You can copy this string fromAzure CosmosDB Emulator- check point 2 (Primary Connection String). -
Create an account in SendGrid and add property
SendGridApiKeytolocal.settings.jsoninNotifyInvoiceFunc. -
Create an account in Twilio and add properties
TwilioAccountSidTwilioAuthTokentolocal.settings.jsoninNotifyInvoiceFunc. -
Run JsReport with Docker:
docker run -p 5488:5488 jsreport/jsreport. Check JsReport Studio onlocalhost:5488. -
Add JsReport url as
JsReportUrltolocal.settings.jsoninPrintInvoiceFuncproject. -
Add JsReport template with name
INVOICEand 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"
}
}
Application Map for all function in one project:
Application Map for functions in separated projects:
End-to-end transaction details:
-
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:





