Tag: azure

  • 🍽️ What if we explained AKS using a restaurant?

    Deploying an API using YAML files is one thing. Understanding what happens behind the scenes makes the architecture much easier to work with.

    Here’s a simple way to picture Azure Kubernetes Service:

    🏠 AKS cluster — The restaurant
    The overall setup where your applications run.

    👨‍🍳 Nodes — The kitchens
    Azure virtual machines that provide resources to run your workloads.

    🔥 Pods — The cooking stations
    Each pod contains one or more containers. Think of your API container as the chef doing the actual work.

    📋 Ingress — The reception rules
    These specify where requests should go based on the hostname or URL path.

    🙋 Ingress controller — The receptionist
    It follows those rules and routes requests to the right Service.

    🧾 Service — The order dispatcher
    It gives your application a stable access point and directs requests to ready pods.

    👔 Kubernetes — The restaurant manager
    It coordinates workloads and keeps the desired number of pod copies running.

    📈 Autoscaling — Preparing for busy hours
    When configured, pod autoscaling adds application copies, while node autoscaling adds computing capacity.

    The key distinction I wanted to highlight:

    Ingress selects the destination. Service reaches ready pods. Containers do the work.

    The infographic brings these pieces together, along with deployments, YAML, health checks, configuration and secrets.

    Which AKS concept took you the longest to understand?

  • Ditch CrmServiceClient—Embrace ServiceClient for Better Dataverse Performance!!

    Recently, we faced performance issues in our custom C# application that was using CrmServiceClient to connect to Dataverse.

    Upon investigation, we discovered that CrmServiceClient internally uses the Organization Service—i.e., the legacy OData V2 endpoint—for Create and Update operations.

    According to Microsoft’s official documentation, use of the old OData V2 endpoints is discouraged. While the documentation mainly references client-side code, the same guidance applies to server-side implementations as well.

    Microsoft recommends switching to OData V4 (Web API) even for server-side integrations. Although we initially believed that CrmServiceClient, being part of the Microsoft.Xrm.Tooling.Connector NuGet package, would abstract and handle any underlying changes automatically via DLL updates, we realized this was not the case—even when using the latest version.

    We later came across an alternative: the ServiceClient class from the Microsoft.PowerPlatform.Dataverse.Client namespace. This client supports a property called UseWebApi, which defaults to false. We explicitly set it to true, and modified our connection logic to use ServiceClient instead of CrmServiceClient.

    Upon testing (verified via Fiddler), we confirmed that Create, Update, and Execute operations were now using the OData V4 (Web API) endpoint. This allowed us to retain most of our existing codebase without rewriting it entirely for Web API usage with HttpClient.

    Based on this experience, I strongly recommend using ServiceClient for any new tools or executables that interact with Dataverse. It offers better performance, modern authentication support, and a more future-proof architecture.

    Hope this helps if you encounter a similar situation.

  • Tip-Generate PDFs using Fonts through Azure Function using PDFsharp FontResolver and C#

    Recently we had a requirement to change our existing console application to Azure function. The challenging part here was to use the specific fonts which we had installed in the server machine to run the console application and generate the PDF file in desired Font Format.

    We created Azure Function of Timer type to run every 10 minutes and copy the supported code in Azure function. Problem was how to reference the specific Fonts in Azure functions.

    In order to make the Fonts available in Azure function we uploaded the required Font files of “.ttf” type as you in the Azure Blob container named “sidcon1” as shown below-

    After that we created the Environment Variable “BlobConnectionString” in the Azure Function to store the connection string to get the font file as below-

    After adding that now we need to set the GlobalFontSettings.FontResolver with the FontResolver object as documented here – https://www.pdfsharp.net/wiki/FontResolver-sample.ashx?AspxAutoDetectCookieSupport=1

    So we just added below line in the code along with implementation of FontResolver class.

     var fontResolver = new FontResolver(connectionString, templateBlobContainerName);
     GlobalFontSettings.FontResolver = fontResolver;

    One most important thing here I saw was, as the code referenced the FontResolver multiple times we started getting below error in the Azure Functions –

    FontResolver – ‘Must not change font resolver after is was once used.’

    So after spending couple of hours with the error we figure our that using C# lock mechanism we could get the object set only once, so we added below code to set the GlobalFontSettings as below which ensured that FontResolver was assigned value only once.

    (In above code for testing purpose the timer trigger was set to run every 2 minutes)

    Below I will add the FontResolver class which I had created in my application to get and set the Fonts from Azure Blob containers while generating PDF

    using Azure.Storage.Blobs;
    using PdfSharp.Fonts;
    using System;
    using System.IO;
    
    namespace TrialFunctionApp
    {
        // Custom FontResolver implementation
        public class FontResolver : IFontResolver
        {
            string connectionString = string.Empty;
            string containerName = string.Empty;
            public FontResolver(string connectionstring,string containername)
            {
                connectionString = connectionstring ?? string.Empty;
                containerName = containername ?? string.Empty;
            }
            public byte[] GetFont(string faceName)
            {
                // This implementation provides Arial font. You can modify it to load your desired font.
                if (faceName.Contains("Sarabun"))
                {
                    return FontHelper.GetFont(connectionString,containerName, "Sarabun-Bold.ttf");
                }
               
                else
                {
                    return null;
                }
            }
    
            public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)
            {
                return new FontResolverInfo(familyName,isBold,isItalic);
            }
    
    
        }
    
        // Helper class to load font data
        public static class FontHelper
        {
            public static byte[] GetFont(string connectionString, string containerName, string fontFileName)
            {
                // Create BlobServiceClient using the connection string
                BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
    
                // Get a reference to the container
                BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
    
                // Get a reference to the font file blob
                BlobClient blobClient = containerClient.GetBlobClient(fontFileName);
    
                // Download the font file to a memory stream
                MemoryStream memoryStream = new MemoryStream();
                blobClient.DownloadTo(memoryStream);
    
                // Return the font data as byte array
                return memoryStream.ToArray();
            }
        }
    
    }

    The above code ensured that the Fonts were correctly referenced in the Azure functions to generate PDF file.

    The PDF generation code remains the standard code as specified by PDFsharp references as below-

    https://www.pdfsharp.net/wiki/PDFsharpSamples.ashx

    In this blog I have specifically added the Font setting part using custom FontResolver class to help others trying to meet similar requirement.

    Hope this helps !!