Road To AZ-204 - Integrate Caching And CDNs Within Solutions

Intro

 
This article's intention is to explain the main skills measured in this sub-topic of the AZ-204 Certification. Azure CDNs, Azure Front Door, and Redis Cache are the main components that will have their fundamentals explained here alongside a practical example.
 
This certification is very extensive and this article approaches only the main topics, make sure you know deep down those components before taking the exam. Another great tip is doing exam simulators before the official exam in order to validate your knowledge.
 

What is the Certification AZ-204 - Developing Solutions for Microsoft Azure?

 
The AZ-204 - Developing Solutions for Microsoft Azure certification measures designing, building, testing, and maintaining skills of an application and/or service in the Microsoft Azure Cloud environment. It approaches, among others, those components,
  • Azure Virtual Machines;
  • Docker;
  • Azure Containers;
  • Service Web App;
  • Azure Functions;
  • Cosmos DB;
  • Azure Storage;
  • Azure AD;
  • Azure Key Vault;
  • Azure Managed Identities;
  • Azure Redis Cache;
  • Azure Logic App;
  • Azure Event Grid;
  • Azure Event Hub;
  • Azure Notification Hub;
  • Azure Service Bus;
  • Azure Queue Storage.
Target Audience
 
Any IT professional willing to improve his knowledge in Microsoft Azure is encouraged to take this certification, it is a great way to measure your skills within trending technologies. But, some group of professionals are more keen to take maximum advantage of it:
  • Azure Developers, with at least 1 year of experience with Microsoft Azure;
  • Experienced Software Developers, looking for an Architect position in a hybrid environment;
  • Software Developers, working to move applications to the cloud environment.
Skills Measured
 
According to today's date, the skills that are measured in the exam are split as follows,

Benefits of Getting Certified

 
The main benefit here is having a worldwide recognized certification that proves that you have knowledge of this topic. Among intrinsic and extrinsic benefits, we have,
  • Higher growth potential, as certifications are a big plus;
  • Discounts and deals in Microsoft products and partners, like PluralSight and UpWork;
  • MCP Newsletters, with trending technologies;
  • Higher exposure on LinkedIn, as recruiters usually search for specific certifications;
  • Higher salary, you will be more valuable to your company;
  • Unique happiness when getting the result and you were approved, knowing that all your efforts were worth it;

Main skills Measured by this Topic

 
What are Azure CDNs?
 
Azure CDN is the Azure service to provide a distributed network of servers to your applications, with Azure CDN you can boost your application's load time, save bandwidth with caching strategies, and speed responsiveness with compressed files. Azure CDNs centralizes the requests from your origin into a single point, where it is easier to manage your inbound and outbound traffic with cache strategies, firewall policies, traffic balancing many others features as follows,
  • Caching Strategies, configuring the requests to be cached and its expiring policies;
  • Compressed files, reducing the size of static files in order to save bandwidth when requested;
  • Geo-Filtering, blocking or allowing requests from specific countries;
  • Global distribution, among Azure Regions;
  • Integration, Azure CDNs has full integration with your Azure services;
  • High Security, without additional costs;
  • Scalability with load-balancing, making it much easier to scale your applications.
 
Azure CDN Profile
 
The Azure CDN Profile groups your Azure CDN Endpoints in the same pricing tier, they are not distributed by Azure regions as far as they are a global service. Azure CDN profile has 4 different pricing tiers and can have from 0 to N Endpoints.
 
Azure CDN Endpoint 
 
CDN Endpoints are where we configure the CDN endpoint that will be exposed as far as the host that is going to be accessed. It has the following main properties, 
  • Name, forming the CDN endpoint URI;
  • Origin Type, the host type
    • Storage, for Azure Storage;
    • Cloud Service, for Azure Cloud Service;
    • Web App, for Azure Web Apps;
    • Custom Origin, for any other possible origin.   
  • Origin Hostname, the origin server domain;
  • Origin Path, the sub-sectors if applied inside the Origin Hostname;
  • Origin Host Headers, host header to be sent with each request;
  • Protocol, the HTTP protocol;
  • Origin Port, the host ports;
  • Optimization, the optimization type:
    • Microsoft profile;
    • Verizon profile;
    • Akamei profile; 
CDN Endpoint Caching
 
Azure CDN provides a caching functionality, facilitating the configuration and management for caching requests from our CDN Endpoints. This caching functionality is available in three query string modes,
  • Ignore query strings, not taking into consideration any query string. The first request with a query string will be cached and until this cached item is expired any request with an equal or different query string will result in the same value. Default mode;
  • Bypass caching for query strings, not caching requests with query strings;
  • Cache every unique URL, every possible request will be cached;
Caching Purge
 
Azure CDNs also provides functionality to purge all the cache, this functionality is at the Azure CDN Profile level and you can filter which endpoint and which path is going to have the cache purged.
 
Caching Rules
 
You can filter and customize your caching strategy with the caching rules, by default Azure CDNs store the cache for 7 days. Under caching rules we have a default global caching rule with the possibility to add many other custom rules, those rules are formed with conditions that have to be satisfied in order to trigger actions that are going to be executed, and on those actions we have three types of caching behavior:
  • Override, overrides any kind of cache headers set by the origin;
  • Bypass cache, not caching and ignoring any kind of cache headers;
  • Set if missing, if the origin does not provide cache headers then it is set; 

What is Azure Front Door? 

 
Azure Front Door is another Azure Service that, like CDN, centralizes incoming requests into a single endpoint that will distribute those calls to different hosts. An Azure Front Door is formed from Frontends/Domains connected to Backend Pools, and those connections are filtered by the routing rules, it works like a modern CDN, using HTTP/HTTPS Layer 7 and anycast protocol and Azure Front Door main functionalities are the ones as follows,
  • Caching, like CDNs with rules and expiring policies;
  • Resiliency, distributing incoming through different Azure Regions; 
  • Cookie-based session affinity, making it easier for restful applications when we need to redirect a client to the same back-end;
  • Health probe, to determine the healthiest and closer back-end to the client request;
  • Web Application Firewall, protecting your back-ends from malicious attacks and vulnerabilities;
  • URL redirect, redirecting traffic based on:
    • Protocol, HTTP or HTTPS;
    • Hostname;
    • Path;
    • QueryString.
  • URL rewrite, with a powerful engine to rewrite income requests to a different request to the back-end. 
Caching Policies
 
Azure Front Door caching policies is almost equal to the Azure CDN caching policies, having some small differences as follows,
  • Caching behavior: 
    • Cache every unique URL, caches any query string individually like Azure CDN;
    • Ignore query string, caching any query string equally like Azure CDN;
    • Ignore specified query strings, ignoring to cache those query strings;
    • Include specified query strings, specifying query string to be cached.
  • Default cache duration, random from 1 to 3 days;   
  • Rule Engine, more powerful than Azure CDN because it does not manage only cache policies. Is formed by:
    • Many rule engine configurations;
    • Each rule engine configurations contain many rules;
    • Group of conditions and actions, conditions that if met are going to trigger the actions;

What is Redis Cache?

 
Azure Redis Cache is based on the popular open-source Redis cache. It gives you access to a secure, dedicated Redis cache, managed by Microsoft and accessible from any application within Azure. 
 
Different from the Azure CDNs and Azure Front Door, Azure Redis Cache is not used to cache requests and responses. Azure Redis Cache is used as an in-memory database caching key-value pairs of data. Azure Redis Cache helps your application become more responsive even as the customer load increases. It takes advantage of the low-latency, high-throughput capabilities of the Redis engine. This separate, distributed cache layer allows your data tier to scale independently for more efficient use of the compute resources in your application layer.
 
Caching Expiration Policies
 
Azure Redis Caches expiration policies are configured per each request, so we could have an expiration policy different for each cache key. Those expiration policies as the ones as follows for Redis Distributed cache,
  • AbsoluteExpirationRelativeToNow, where we set the duration of the cache, starting to count from now;
  • AbsoluteExpiration, setting a specific date time to the cache expiry;
  • SlidingExpiration, configuring how long after this cache not be accessed it will be expired;
Practical Example
 
Azure CDN
 
Pre-Requisites
In order to have a better demonstration of the functionalities used below, some changes were done in the project in order to work as a Rest API as follows,
  1. [HttpGet]  
  2. public IActionResult Index()  
  3. {  
  4.     return Ok();  
  5. }  
  6.   
  7. [HttpPost]  
  8. public IActionResult Index([FromQuery] Operation model )  
  9. {  
  10.     if ( model.OperationType == OperationType.Addition )  
  11.         model.Result = model.NumberA + model.NumberB;  
  12.     return Ok( model );  
  13. }  
  14.   
  15. [HttpPost]  
  16. public IActionResult CompoundInterest( CompoundInterestModel model )  
  17. {  
  18.     model.Result = Calculation.CalculateCompoundInterest( model );  
  19.     return View( model );  
  20. }  
  21.   
  22. [HttpGet]  
  23. public IActionResult CompoundInterest()  
  24. {  
  25.     return View();  
  26. }  

Create a CDN with Azure CLI 

 
Pre-Requisites
  • Azure App Service previously created. Here named as NetCoreCalculatorWithCDN and with the following endpoint:
    •     https://netcorecalculatorwithcdn.azurewebsites.net
Setting Variables
  1. $resourceGroup= "cdnCachingResourceGroup"  
  2. $cdnProfileName ="sampleCDNProfile"  
  3. $cdnEndpointName="sampleEndpointName"  
  4. $cdnSku="Standard_Microsoft"  
  5. $appServiceEndpoint ="netcorecalculatorwithcdn.azurewebsites.net"   
Create the CDN Profile
  1. az cdn profile create --resource-group $resourceGroup --name $cdnProfileName --sku $cdnSku  
 
Create the CDN endpoint, pointing to your App Service
  1. az cdn endpoint create --resource-group $resourceGroup --profile-name $cdnProfileName --name $cdnEndpointName --origin $appServiceEndpoint --origin-host-header $appServiceEndpoint
 
Result
 
CDN Caching
 
From your CDN endpoint, go to Caching rules and then Configure your CDN Endpoint caching strategy, here we will be caching every unique URL.
 
 
CDN Expiring Cache
 
From your CDN Endpoint, go to Rules Engine then click on Add Action. Here we will be configuring the cache to expires after 10 seconds
 
 
The result from a cached request,
 
 
Azure Front Door
 
Pre-Requisites
  • Azure App Service previously created. Here named as NetCoreCalculatorWithCDN and with the following endpoint:
    • https://netcorecalculatorwithcdn.azurewebsites.net 
Creating Azure Front Door
 
From your Azure Portal, go to Azure Front door and add a new one. Then on configuration, name your front door.
 
 
Now, configure your backend pool. Add a backend, set its name, health probes, and load-balancing configurations. 
 
 
 
Add a routing rule, configuring the cache policy
 
 
Results
 
 
 
Front Door Caching
 
From your Azure Front Door go to Front Door Design under Settings and update your routing rule to apply your cache strategy.
 
 
 
Front Door Expiring Cache
 
From your Azure Front Door then go to Front Door Design under Settings and update your routing rule to add the seconds that the cache will live in the Front Door. 
 
 
 
Create a new Rule Engine configuration with a rule to append the cache-control in the response header.
 
Result
 
 
Redis Cache with .Net Core Web API
 
Pre-Requisites
 
Connecting 
 
Update your appsettings.json in order to add your Azure Redis Cache connection string.
  1. {  
  2.   "ConnectionStrings": {  
  3.     "RedisConnection""rediscachesample.redis.cache.windows.net:6380,password=+kRlOup8TECk8gNy5dBQv4VG6+KGq3QcbI+MTVxpUwE=,ssl=True,abortConnect=False"  
  4.   },  
  5.   "Logging": {  
  6.     "IncludeScopes"false,  
  7.     "LogLevel": {  
  8.       "Default""Warning"  
  9.     }  
  10.   }  
  11. }  
Update your Startup.cs in order to use dependency injection to inject your Redis Cache into your classes. 
  1. public void ConfigureServices( IServiceCollection services )  
  2. {  
  3.     services.AddMvc();  
  4.     services.AddStackExchangeRedisCache(options =>  
  5.     {  
  6.         options.Configuration = Configuration.GetConnectionString("RedisConnection");  
  7.     });  
  8. }   
Extension methods and helpers
 
In order to facilitate communicating with your Redis Cache, here are some useful extension methods in order to work with complex objects.  
  1. public static class RedisCacheHelper  
  2.    {  
  3.        public static T GetHelper<T>(this IDistributedCache cache, string cacheKey)  
  4.        {  
  5.            return Deserialize<T>(cache.Get(cacheKey));  
  6.        }  
  7.   
  8.        public static object GetHelper(this IDistributedCache cache, string cacheKey)  
  9.        {  
  10.            return Deserialize<object>(cache.Get(cacheKey));  
  11.        }  
  12.   
  13.        public static void SetHelper(this IDistributedCache cache, string cacheKey, object cacheValue)  
  14.        {  
  15.            cache.Set(cacheKey, Serialize(cacheValue));  
  16.        }  
  17.   
  18.        private static byte[] Serialize(object obj)  
  19.        {  
  20.            if (obj == null)  
  21.            {  
  22.                return null;  
  23.            }  
  24.            BinaryFormatter objBinaryFormatter = new BinaryFormatter();  
  25.            using (MemoryStream objMemoryStream = new MemoryStream())  
  26.            {  
  27.                objBinaryFormatter.Serialize(objMemoryStream, obj);  
  28.                byte[] objDataAsByte = objMemoryStream.ToArray();  
  29.                return objDataAsByte;  
  30.            }  
  31.        }  
  32.   
  33.        private static T Deserialize<T>(byte[] bytes)  
  34.        {  
  35.            BinaryFormatter objBinaryFormatter = new BinaryFormatter();  
  36.            if (bytes == null)  
  37.                return default(T);  
  38.   
  39.            using (MemoryStream objMemoryStream = new MemoryStream(bytes))  
  40.            {  
  41.                T result = (T)objBinaryFormatter.Deserialize(objMemoryStream);  
  42.                return result;  
  43.            }  
  44.        }  
  45.    }   
Storing data
 
Example of storing a complex and a list of complex objects
  1. private  IDistributedCache cache;  
  2.       public HomeController(IDistributedCache cache)  
  3.       {  
  4.           this.cache = cache;  
  5.       }  
  6.  public IActionResult SetSimpleComplexObject()  
  7.       {  
  8.           SampleObject sampleObject = new SampleObject  
  9.           {  
  10.               Country = "Brazil",  
  11.               Id = 7,  
  12.               Name = "Mané"  
  13.           };  
  14.           this.cache.SetHelper("test1", sampleObject);  
  15.   
  16.   
  17.           return RedirectToActionPermanent("Index");  
  18.       }  
  19.   
  20.       public IActionResult SetListComplexObject()  
  21.       {  
  22.           List<SampleObject> lstSampleObject = new List<SampleObject>();  
  23.           lstSampleObject.Add(new SampleObject  
  24.           {  
  25.               Country = "Argentina",  
  26.               Id = 1,  
  27.               Name = "Maradona"  
  28.           });  
  29.           lstSampleObject.Add(new SampleObject  
  30.           {  
  31.               Country = "Portugal",  
  32.               Id = 2,  
  33.               Name = "Ronaldo"  
  34.           });  
  35.           lstSampleObject.Add(new SampleObject  
  36.           {  
  37.               Country = "Puskas",  
  38.               Id = 3,  
  39.               Name = "Hungary"  
  40.           });  
  41.           this.cache.SetHelper("test2", lstSampleObject);  
  42.   
  43.           return RedirectToActionPermanent("Index");  
  44.       }  
Retrieving data 
 
Example of retrieving a complex and a list of complex objects
  1. private  IDistributedCache cache;  
  2.  public HomeController(IDistributedCache cache)  
  3.  {  
  4.      this.cache = cache;  
  5.  }  
  6.  public IActionResult Index()  
  7.  {  
  8.      return View(true);  
  9.  }  
  10.   
  11.  IActionResult GetSimpleComplexObject()  
  12.  {  
  13.      SampleObject sampleObject = new SampleObject();  
  14.   
  15.      sampleObject = this.cache.GetHelper<SampleObject>("test1");  
  16.      return View(sampleObject);  
  17.  }  
  18.   
  19.  public IActionResult GetListComplexObject()  
  20.  {  
  21.      List<SampleObject> lstSampleObject = new List<SampleObject>();  
  22.   
  23.      lstSampleObject = this.cache.GetHelper<List<SampleObject>>("test2");  
  24.   
  25.      return View(lstSampleObject);  
  26.  }  
 
Expiring Policies 
 
Azure Redis Caches provides two different ways to expire your cache, you can set a specific date or set how long the cache, after its creation, is going to live.
  1. cache.Set(cacheKey, Serialize(cacheValue), new DistributedCacheEntryOptions  
  2.    {  
  3.        AbsoluteExpirationRelativeToNow = new TimeSpan(1, 9, 0),  
  4.        AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddDays(44))  
  5.    });   
External References