Cosmos DB–Free Practice Resources

As you know Azure Cosmos DB will cost high if you are spending time on learning & experimenting.  Alternatively, following are different options inside/outside the Azure Portal to try with:

MSDN $200 Free Plan

https://azure.microsoft.com/en-us/free/free-account-faq/

Emulator

https://aka.ms/cosmosdb-emulator

Sandbox

https://docs.microsoft.com/en-us/learn/modules/create-cosmos-db-for-scale/2-create-an-account

Advertisements

Cosmos DB–Choosing the right Model

Cosmos DB offer multiple models as below:

  • Document Model with SQL API
  • MongoDB Model with MongoDB API
  • Cassandra Model with Cassandra API
  • Table Model with Table API
  • Graph Model with Gremlin API

In this article we can see which model to choose based on the requirement.

Note As informed previously we are making a Choice of CosmosDB here due to Dynamic Schema requirement & Geo-replication.

Document Model with SQL API

If you are starting with a new project which requires storage of similar items, schema changes a lot, then SQL API is the best choice.

MongoDB with MongoDB API

If you are Migrating from existing MongoDB which have Investments of MongoDB Queries then MongoDB API is the best choice.

Cassandra Model with Cassandra API

If your project requires Web Analytics capabilities, then Cassandra API is the right choice.

Table Model with Table API

If your data consists of Key-Value pairs OR if you wanted to Migrate data from Azure Table Storage, then Table Model API would be right choice.

    • Cosmos DB (access based pricing) is Cheaper than Table Storage (size based pricing) depending on the case

Graph Model with Gremlin API

If you have relationships between data, then Graph Model is the best choice.

Example: Amazon wanted to show Product Recommendations like customer who bought LG TV 46” also bought another product TV Stand 46”

graph.V().hasLabel(‘product’).has(‘productName’, ‘LG TV’).addE(‘boughtWith’).to(g.V().hasLabel(‘product’).has(‘productName’, ‘TV Stand’))

CosmosDB–Schemaless Scenario

As discussed earlier, the Decision for choosing CosmosDB rather than SQL Server is mostly one of the following:

  • Schemaless Advantage
  • Geo Replication

In this post we can explore the same with few scenarios.

Player Table

Let us think of a Table named Player in SQL Server.  There will be properties like following:

  • ID
  • Name
  • Age
  • Address

Requirement 1

Now, the Player table NEED TO support both Football player & Cricket player.

We resolve this by adding a Type column to differentiate between the players.

image

Requirement 2

The requirement changed that:

  • The Football Player should have a Goals column of type int
  • The Cricket Player should have a Run Rate column of type float

We resole this by adding 2 more columns. 

image

Problems in Design

As you can see, there are few problems in current design:

  • There is unwanted column GOALS being allocated for CRICKET Player
  • There is unwanted column RUN RATE being allocated for FOOTBALL Player

The problem is more complicated when the FUTURE REQUIREMENT to support Tennis Player, Badminton Player also comes through.

How COSMOS DB resolves this issue?

Cosmos DB resolves this issue by using only required columns.

{

“name”: “John”,

“age”: “30”,

“type”: “Football”,

“goals”: 4,

}

{

“name”: “Kevin”,

“age”: “25”,

“type”: “Cricket”,

“runrate”: 5.3

}

Summary

In this post we have observed the Schemaless advantage of Cosmos DB.

AZ300 – AAD Service Registration

Azure Active Directory provides Identity Platform which allows Secured Access to your Application & Services. In this article we can explore how to create a Web API Service & Protect it with AAD App Registration.

Create New API Service

Open Visual Studio & Create a new Web API Service.

image

Run the Service and Ensure you are able to access the Results as displayed below.

http://localhost:62573/api/values

Publish the Service

Now right click on the project & publish the service to Azure App Service.

image

image

You need an Azure Subscription to perform this. You can use following link to do the same.

https://azure.microsoft.com/en-us/free/

Choose the App Service option.

image

Enter the App Service option.

image

Azure App Service is a PaaS (Platform as a Service) way of Hosting web sites.

image

You can test your new App Service with the URL.

https://aadservice2019.azurewebsites.net/api/values

If you are getting the same results, you are good!

Protect the Service

Now we can protect the Service with Azure Active Directory. There is a Quick Way to achieve the same without writing a single line of code.

Go to Azure Portal > App Services blade > Click on your service.

image

Go to Authentication/Authorization blade.

image

Turn App Service Authentication to On. Then in the appearing options choose the following:

· Login with Azure Active Directory

· Choose Azure Active Directory from Authentication Providers > Then choose Express option

Save changes.

Test the Service

Now test the service again with the previous URL. This time you will be prompted for Login.

image

This means the Service is protected from Anonymous Access now.

References

https://docs.microsoft.com/en-us/azure/active-directory/develop/authentication-scenarios

Summary

In this article we have explored how to create a Web API Service & Protect it with AAD App Registration.

Make Singleton Class Thread-Safe

Singleton Design Pattern ensures that Only One Instance is created.  But, It will impose challenges in the Multi-threaded scenarios.

  • Multiple Thread causes Issues If entering the GetInstance() method
  • We need to use Lock keyword to ensure only 1 Thread enters the Instance Creation
  • We need to add additional check on Instance is Null inside the lock statement

public class ConnectionPool

{
private static ConnectionPool instance;
private static object _lockObject = new object();

public static ConnectionPool GetInstance()
{
if (instance == null)
{
lock (_lockObject)
{
if (instance != null)
instance = new ConnectionPool();
}
}

return instance;
}

private ConnectionPool()
{
// doesn’t matter what’s here
}

}

Reference

I have written a book Design Patterns in C# few years back.

TDD Test Sample

In this post I would like to demonstrate few of my TDD (Test Driven Development) skills!

TDD

I  started TDD during 2010 with a Product Development Company.  Thereafter I am a Big Fan & Advocate of TDD.

Following are the Properties & Advantages of TDD:

  1. In TDD we first write the Unit Test. Then we start with the actual Code Method.  As the Test Method evolves the Original Method evolves too.
  2. TDD ensures the code is released with enough testing.
  3. TDD is an Investment for Future
  4. TDD is essential for Products
  5. TDD gives the Flexibility for Refactoring, More Confident Deployments
  6. TDD is used mostly in the Backend side

Coding Test

We want to expose a service that calculates the total spend given a supplier ID.

public class SpendService

{

public SpendSummary GetTotalSpend(int supplierId) { … }

}

The business logic is quite straightforward: the total spend is the sum of all the invoices, grouped by year. However, some of the suppliers are working with a separate branch of the company, which has its own invoicing platform.

Therefore, the flow should work as follows:

1) A SupplierService returns supplier data, which can be used to understand whether a supplier is external or not

2) If the supplier is not external, invoice data can be retrieved through the InvoiceRepository class

3) If the supplier is external, invoice data can be retrieved through the ExternalInvoiceService class

4) ExternalInvoiceService invokes a separate system, which might fail. However, data from this system is regularly backed up in a failover storage. A FailoverInvoiceService class gives access to that storage. It is ok to return failover data when ExternalInvoiceService fails.

5) Failover data might be not fresh. A timestamp property indicates when it has been originally stored. If this date is older than a month, it means that it has not been refreshed. In this case, the GetTotalSpend method should fail.

6) When ExternalInvoiceService is offline, usually calls tend to timeout, which means that the method takes long to complete. Therefore, after 3 consecutive errors, we want to bypass ExternalInvoiceService and go to FailoverInvoiceService directly, with the same logic as before. After 1 minute, we can try to re-enable ExternalInvoiceService again.

Solution

[TestClass]
    public class SpendServiceTest
    {
        private UnityContainer container;

        [TestInitialize]
        public void TestInit()
        {
            container = new UnityContainer();
            container.RegisterType<ISupplierDataService, SupplierDataServiceStub>();
            container.RegisterType<ISupplierService, SupplierService>();
            container.RegisterType<IInvoiceRepository, InvoiceRepositoryStub>();
            container.RegisterType<IExternalSpendService, ExternalInvoiceServiceStub>();
            container.RegisterType<ICircuitBreaker, ExternalSpendServiceInvoker>();
            container.RegisterType<IFailoverInvoiceService, FailoverInvoiceServiceStub>();
        }

        [TestMethod]
        public void SpendService_InternalCustomer_Name_Test()
        {
            // Arrange
            int supplierId = 1;
            SpendService spendService = container.Resolve<InternalSpendService>();

            // Act
            SpendSummary result = spendService.GetTotalSpend(supplierId);

            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(“Supplier Internal”, result.Name);
        }

        [TestMethod]
        public void SpendService_InternalCustomer_Spend_Test()
        {
            // Arrange
            int supplierId = 1;
            SpendService spendService = container.Resolve<InternalSpendService>();

            // Act
            SpendSummary result = spendService.GetTotalSpend(supplierId);

            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(2, result.Years.Count);
            Assert.AreEqual(2000, result.Years[0].TotalSpend);
            Assert.AreEqual(1000, result.Years[1].TotalSpend);
        }

        [TestMethod]
        public void SpendService_ExternalCustomer_Name_Test()
        {
            // Arrange
            int supplierId = 2;
            SpendService spendService = container.Resolve<ExternalSpendService>();

            // Act
            SpendSummary result = spendService.GetTotalSpend(supplierId);

            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(“Supplier External”, result.Name);
        }

}

Following is Circuit Breaker.

public interface ICircuitBreaker
{
    int MaxTries { get; }

    int ClosedTimeSeconds { get; }

    int ObsoleteDaysLimit { get; }

    bool IsOpenState { get; set; }

    DateTime FailedTimestamp { get; set; }

    void Reset();

    List<SpendDetail> GetSpendDetail(int supplierId);
}

One Stub Sample.

public class FailoverInvoiceServiceStub : IFailoverInvoiceService
    {
        public FailoverInvoiceCollection GetInvoices(int supplierId)
        {
            FailoverInvoiceCollection result = new FailoverInvoiceCollection();

            if (supplierId == 2)
            {
                IList<ExternalInvoice> list = new List<ExternalInvoice>();
                list.Add(new ExternalInvoice() { Year = 2018, TotalAmount = 900 }); // Only 1 Year
                result.Timestamp = DateTime.Now;
                result.Invoices = list.ToArray();
            }
            else if (supplierId == 3)
            {
                IList<ExternalInvoice> list = new List<ExternalInvoice>();
                list.Add(new ExternalInvoice() { Year = 2018, TotalAmount = 900 }); // Only 1 Year
                result.Timestamp = DateTime.Now;
                result.Invoices = list.ToArray();
            }
            else if (supplierId == 4)
            {
                IList<ExternalInvoice> list = new List<ExternalInvoice>();
                list.Add(new ExternalInvoice() { Year = 2017, TotalAmount = 800 });
                result.Timestamp = DateTime.Now.AddDays(-32); // Obsolete Date
                result.Invoices = list.ToArray();
            }

            return result;
        }
    }

Strategies

I have been using following Frameworks & Strategies:

  1. Unit Test created using C#
  2. Moq Framework for Mocking
  3. Stubbing using C# Classes
  4. Wrapper Methods for Static Methods unit testing

References

You can find the Code in GitHub.

https://github.com/jeanpaulva/jp-tdd

Summary

This is a TDD Code Demonstration to showcase my skills. 

Thank you All!