Azure Functions v2 with .NET Core - billing in serverless architecture.
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 the data-examples
folder) to a specific data storage - active-lists
Azure Blob Container.
The above action triggers a function (GenerateBillingItemsFunc
) that is responsible for:
crm
database, prices
collection) and saving them in the table billingItems
;invoice-generation-request
;When a new message appears on the queue invoice-generation-request
, next function is triggered (GenerateInvoiceFunc
). This function creates domain object Invoice
and save this object in database (CosmosDB crm
database, invoices
collection) and send message to queues: invoice-print-request
and invoice-notification-request
.
When a new message appears on the queue invoice-print-request
, function PrintInvoiceFunc
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
, function NotifyInvoiceFunc
is 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.txt
file from data-examples
folder to active-lists
blob.
Create CosmosDB database crm
and in this database create collections: prices
, invoices
.
Add CosmosDB properties PriceDbUrl
and PriceDbAuthKey
to local.appsettings.json
in PriceDbInitializator
and GenerateBillingIemsFunc
. You can copy this properties from Azure CosmosDB Emulator
- check point 2 (URI and Primary Key).
Run project PriceDbInitializator
to init collection prices
in crm
database.
Add CosmosDB connection string as cosmosDb
to local.settings.json
in GenerateInvoiceFunc
. You can copy this string from Azure CosmosDB Emulator
- check point 2 (Primary Connection String).
Create an account in SendGrid and add property SendGridApiKey
to local.settings.json
in NotifyInvoiceFunc
.
Create an account in Twilio and add properties TwilioAccountSid
TwilioAuthToken
to local.settings.json
in NotifyInvoiceFunc
.
Run JsReport with Docker: docker run -p 5488:5488 jsreport/jsreport
. Check JsReport Studio on localhost:5488
.
Add JsReport url as JsReportUrl
to local.settings.json
in PrintInvoiceFunc
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"
}
}
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 project PriceDbInitializator
, file Program.cs
, method AddDoc
.
Remember that you must use Twilio Test Credentials.