tag:blogger.com,1999:blog-74836669545204650232024-03-27T23:53:16.834+00:00Microsoft Azure & Dynamics 365 CRM -Learn The RopesThis blog aims to provide some technical tips about Microsoft Azure & Dynamics 365 CRM - D. MANJALYD. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.comBlogger158125tag:blogger.com,1999:blog-7483666954520465023.post-75894423722694224292024-03-21T07:35:00.002+00:002024-03-21T07:35:46.777+00:00Upcoming Breaking Changes in Azure API Management<p><span style="font-family: arial;">There are some upcoming changes in Azure API Management. Full list is given below. Main one is stv1 Platform retirement. And the retirement date is August 31st 2024. So make sure you move to the upgraded version before the retirement date. </span></p><p><span style="font-family: arial;">How to check? - On the Azure portal, if you open the Azure API Management, you could see the platform version on the Overview blade. </span></p><p><span style="font-family: arial;">Full List:</span></p><p><a href="https://learn.microsoft.com/en-us/azure/api-management/breaking-changes/overview"><span style="font-family: arial;">https://learn.microsoft.com/en-us/azure/api-management/breaking-changes/overview</span></a></p><p><span style="font-family: arial;"><br /></span></p><p><br /></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-44524771688026082012024-02-04T11:52:00.002+00:002024-02-04T21:31:43.553+00:00Azure Function - HTTP Trigger Use Case <p><span style="font-family: arial;"> As you all know, there are different triggers available in the Azure Functions. And sometimes it becomes handy to define Cloud solutions. Here is an Azure Function HTTP Trigger scenario.</span></p><p><span style="font-family: arial;">Customer receive Marketing emails and but choose to unsubscribe / opt out. Then Third Party Marketing Solution sends a webhook in order to update the consents. In this diagram, I have shown Dynamics 365 CRM as the system which stores the consent. But it could be any system which stores the consents. </span></p><p><span style="font-family: arial;">Azure function with HTTP Trigger will consume the webhook and updates the consent. In short words, it is used as a light weight API here. So next time that customer will not be included in the Marketing emails. Azure API Management is used here as an API Gateway to secure the Azure Function End point. Diagram is given below. </span></p><p><span style="font-family: arial;"><br /></span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhepPQsfx8CYaO83Li1cTS2U6SWPBzGjTkX6CJdRm_VwPPSm1-5qPKnxvXXEZsB1jLMI8Yg4OX1gsRwwaKBXCYJByJv9FzDFJ8xiW6jsXu1peQ1Qnhng0-vLEDCROUIF0wucyfKWrNP82-uKmbavXJkPassSoNAH5iGcK8P3RWDzmlPYhNG8O4-BlKOBqpE" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: arial;"><img alt="" data-original-height="573" data-original-width="1760" height="202" src="https://blogger.googleusercontent.com/img/a/AVvXsEhepPQsfx8CYaO83Li1cTS2U6SWPBzGjTkX6CJdRm_VwPPSm1-5qPKnxvXXEZsB1jLMI8Yg4OX1gsRwwaKBXCYJByJv9FzDFJ8xiW6jsXu1peQ1Qnhng0-vLEDCROUIF0wucyfKWrNP82-uKmbavXJkPassSoNAH5iGcK8P3RWDzmlPYhNG8O4-BlKOBqpE=w624-h202" width="624" /></span></a></div><p></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-18272795520253297272023-11-06T08:16:00.002+00:002023-11-06T08:16:14.944+00:00Cloud Migration and Modernisation Approaches<p><span style="font-family: arial;">Here are the key High-Level Approaches for the Migration from On-Premise to Cloud - Rehost, Refactor, Rearchitect, Rebuild and Replace. Microsoft provided a nice table where it is clearly described more details. Highly recommended if you are considering Cloud migration or modernisation. It will help you with planning and achieve the good Cloud migration results.</span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhNTjlR3L2MzhDGxzqiMmsIBjvZTb_0MooKXXDYoJczS9zyGRps7y7RISuX3D-IkXCo_NwvT5zUM39JS1n0wpKVBGOIdEJM8T_58CE85IfsoKPL3Z0h5hL0MS5ATkOJdOb2dySC03jn_sn6OqYt0_CQwzGeXqEBzUPg-eUhfw1bKyZ0gjXm0XnwYge2oCMl" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: arial;"><img alt="" data-original-height="830" data-original-width="1952" height="272" src="https://blogger.googleusercontent.com/img/a/AVvXsEhNTjlR3L2MzhDGxzqiMmsIBjvZTb_0MooKXXDYoJczS9zyGRps7y7RISuX3D-IkXCo_NwvT5zUM39JS1n0wpKVBGOIdEJM8T_58CE85IfsoKPL3Z0h5hL0MS5ATkOJdOb2dySC03jn_sn6OqYt0_CQwzGeXqEBzUPg-eUhfw1bKyZ0gjXm0XnwYge2oCMl=w640-h272" width="640" /></span></a></div><span style="font-family: arial;"><br /></span><p></p><p><span style="font-family: arial;">Ref: <a href="https://azure.microsoft.com/en-gb/resources/research/making-the-business-case-for-moving-to-the-cloud">https://azure.microsoft.com/en-gb/resources/research/making-the-business-case-for-moving-to-the-cloud</a></span></p><p></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-43842321841347721362023-10-17T08:05:00.001+01:002023-10-17T08:05:43.017+01:00Difference between Automation, Machine Learning and AI<span style="font-family: arial;">We hear a lot about Automation, Machine Learning and Artificial Intelligence. And sometimes it gets confused between them as well. Recently came across a good and clear explanation about it. It is easy to remember too. Thought to share it.</span><div><span style="font-family: arial;"><br /></span></div><div><span style="font-family: arial;">Credit: Steven Killick</span></div><div><span style="font-family: arial;"><br /></span><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirGTSNsMX_hPQXm1AKxqVb7Uo_Ds3PyUNt1COI6qEhkLosK8x72m6cayO_fmuQjkltcZWGyqj_8eItno0t2bRzI690dyKqTuxf3OrIeguIMtJHPFR82qPONgSC-EYx9Fvqbvs1TDPfWWAYpCga7gcGZaaBP3oFzYTpEw4aoBSDiZDMrjRm8BQT8B0BeWF1/s1920/aimachinelearningautomation.jpeg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1080" data-original-width="1920" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirGTSNsMX_hPQXm1AKxqVb7Uo_Ds3PyUNt1COI6qEhkLosK8x72m6cayO_fmuQjkltcZWGyqj_8eItno0t2bRzI690dyKqTuxf3OrIeguIMtJHPFR82qPONgSC-EYx9Fvqbvs1TDPfWWAYpCga7gcGZaaBP3oFzYTpEw4aoBSDiZDMrjRm8BQT8B0BeWF1/w640-h360/aimachinelearningautomation.jpeg" width="640" /></a></div><br /><span style="font-family: arial;"><br /></span></div></div>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-6990079365806507172023-07-10T23:42:00.002+01:002023-07-10T23:42:29.181+01:00Defender for APIs / Defender for Azure API Management APIs is in Public Preview<p><span style="font-family: arial;">Defender for APIs went to public preview in April 2023. In simple words, "<span style="background-color: white; color: #292827;">Defender for Cloud continuously monitors the configuration of your API management to identity potential security vulnerabilities and recommends actions to mitigate them"</span></span></p><p><span style="background-color: white; color: #292827;"><span style="font-family: arial;">I had a look at my Azure instance. It can be found under the security section.</span></span></p><p><span style="background-color: white; color: #292827;"><span style="font-family: arial;"> If your organisation has many APIs and especially if it is exposed as public APIs or partner APIs or even internal APIs then this would be very useful. Because it continuously monitors.</span></span></p><p><span style="background-color: white; color: #292827;"><span style="font-family: arial;"> Remember security is always important. This adds one more layer of security feature to the Azure API Management service.</span></span></p><p><span style="background-color: white; color: #292827;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_7B_TSA6oCivmMC3QFVJPfxI2RME13jI9UJzif4zukxghn3OBN8sCLjjK7aS_1I9ZIdgOV1VpBuEKdopp6leerOnymBOrV5onjt2vVucs0XM2owTjYU6Pxb0jzpBiEQjFxRkC312v-Nja0Cr04hRLzss7SOAKcBe46Z9FZsq6TqcKgyQiYlYx7mEloXI7/s1893/apimdefender.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="746" data-original-width="1893" height="252" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_7B_TSA6oCivmMC3QFVJPfxI2RME13jI9UJzif4zukxghn3OBN8sCLjjK7aS_1I9ZIdgOV1VpBuEKdopp6leerOnymBOrV5onjt2vVucs0XM2owTjYU6Pxb0jzpBiEQjFxRkC312v-Nja0Cr04hRLzss7SOAKcBe46Z9FZsq6TqcKgyQiYlYx7mEloXI7/w640-h252/apimdefender.png" width="640" /></a></span></div><span style="font-family: arial;"><br /><div class="separator" style="clear: both; text-align: center;"><br /></div></span><span style="background-color: white; color: #292827;"><span style="font-family: arial;"><br /></span></span><span style="background-color: white; color: #292827; font-family: arial;">Ref:</span><p></p><p><span style="background-color: white;"><span style="color: #292827; font-family: arial;"><a href="https://learn.microsoft.com/en-us/azure/defender-for-cloud/defender-for-apis-introduction">https://learn.microsoft.com/en-us/azure/defender-for-cloud/defender-for-apis-introduction</a></span></span></p><p><span style="background-color: white;"><span style="color: #292827; font-family: arial;"><br /></span></span></p><p><span style="background-color: white;"><span style="color: #292827; font-family: arial;"><br /></span></span></p><p><span style="background-color: white; font-size: 13px;"><span style="color: #292827; font-family: az_ea_font, Segoe UI, az_font, system-ui, -apple-system, BlinkMacSystemFont, Roboto, Oxygen, Ubuntu, Cantarell, Open Sans, Helvetica Neue, sans-serif;"><br /></span></span></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-20656971061303614432023-07-08T22:55:00.000+01:002023-07-08T22:55:15.513+01:00Azure Data Factory Connectors Overview/ Supported Connectors for Azure Data Factory<p><span style="font-family: arial;">Recently I was searching, whether it's possible to write to SharePoint using Azure Data Factory. But couldn't find many options. And found this useful info on the Microsoft Site.</span></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhnOGGSRV84D3PgzPrjGUsqqzDJHiC8Y_749YUeu7tW9KQCy-UT5-aWhFm4m5bWwGIkVWlvKK-e-y0JiNeU1DzweheG5p1QDaMhn7YYMBuYShdI2P6ZSkcimKMTby-FRyDKhpcgAjs_VnREXKxq9c22Tiddydf1mYEaPypVsstrcpV3UtYPMTuHQtNOUdHL" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: arial;"><img alt="" data-original-height="830" data-original-width="959" height="555" src="https://blogger.googleusercontent.com/img/a/AVvXsEhnOGGSRV84D3PgzPrjGUsqqzDJHiC8Y_749YUeu7tW9KQCy-UT5-aWhFm4m5bWwGIkVWlvKK-e-y0JiNeU1DzweheG5p1QDaMhn7YYMBuYShdI2P6ZSkcimKMTby-FRyDKhpcgAjs_VnREXKxq9c22Tiddydf1mYEaPypVsstrcpV3UtYPMTuHQtNOUdHL=w640-h555" width="640" /></span></a></div><span style="font-family: arial;"><br /><ul style="text-align: left;"><li><span style="font-family: arial;">Source - Where data starts</span></li></ul></span><span style="font-family: arial;"><ul><li><span style="font-family: arial;">Sink - Where data ends</span></li></ul></span><p></p><p><span style="font-family: arial;">And for SharePoint, it had this row</span></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEimRSYFUXJlMRTLHxznYD5cVCX_-eMg3AeOkLnT1T6TOt3zZfCWVYit_ykhrwNBE9E8HKk5Xx6dUaJxy0SMk1lqK3vB6Rk86gwweQnx2RJbQb5mIXKvaxFJ2PAmN366d54v3rND9EIeL2sKMoKR5bOdRpbk0te903Ely_4zNb4GGywtHHUwWJ0lXm9d573Z" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: arial;"><img alt="" data-original-height="76" data-original-width="986" height="50" src="https://blogger.googleusercontent.com/img/a/AVvXsEimRSYFUXJlMRTLHxznYD5cVCX_-eMg3AeOkLnT1T6TOt3zZfCWVYit_ykhrwNBE9E8HKk5Xx6dUaJxy0SMk1lqK3vB6Rk86gwweQnx2RJbQb5mIXKvaxFJ2PAmN366d54v3rND9EIeL2sKMoKR5bOdRpbk0te903Ely_4zNb4GGywtHHUwWJ0lXm9d573Z=w640-h50" width="640" /></span></a></div><span style="font-family: arial;"><br />Always check whether connectors are available as per your requirements. Here is the link to the documentation</span><p></p><p><a href="https://learn.microsoft.com/en-us/azure/data-factory/connector-overview"><span style="font-family: arial;">https://learn.microsoft.com/en-us/azure/data-factory/connector-overview</span></a></p><p><br /></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-7337391872273984922023-07-05T23:42:00.000+01:002023-07-05T23:42:41.891+01:00How to Choose managed Azure Data store?<p><span style="font-family: arial;">Have you struggled to choose the right managed azure data store for your application? Did you know that Microsoft had released a cool decision tree for it? I found it quite useful when I had choose the correct Azure managed data store. </span></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEj8i8UEz-KcbW8EL04yfKZ83fgKg6jaXVcCHoK78QhWyuNbFmt4rgHWPuv_CMzJmDW3QsPPz93aspXYZhZz5YvmJ8i70cNorT8jTTq1YwXSQHYcid7Ip20r-5BdwCGSXitwlDsk9LXWFkYYRVJegfSRcVe0o4-5-Ao1lG6wGuAh8DN8YerobF9plkir5xC_" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: arial;"><img alt="" data-original-height="1200" data-original-width="960" height="640" src="https://blogger.googleusercontent.com/img/a/AVvXsEj8i8UEz-KcbW8EL04yfKZ83fgKg6jaXVcCHoK78QhWyuNbFmt4rgHWPuv_CMzJmDW3QsPPz93aspXYZhZz5YvmJ8i70cNorT8jTTq1YwXSQHYcid7Ip20r-5BdwCGSXitwlDsk9LXWFkYYRVJegfSRcVe0o4-5-Ao1lG6wGuAh8DN8YerobF9plkir5xC_=w512-h640" width="512" /></span></a></div>(Ref: <a href="https://learn.microsoft.com/en-us/azure/architecture/guide/technology-choices/data-store-decision-tree">https://learn.microsoft.com/en-us/azure/architecture/guide/technology-choices/data-store-decision-tree</a>)<p></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com2tag:blogger.com,1999:blog-7483666954520465023.post-42750575790227691722023-07-05T07:59:00.002+01:002023-07-05T07:59:41.962+01:00Microsoft SaaS Offerings<p><span style="font-family: arial;">Ever wondered what are the SaaS (Software as a Service) offerings from Microsoft? SaaS offering is something like users connect , configure and use without worrying about upgrades, installation etc. Offerings are well described here by Ivan Kosyakov . He has also provided a high level overview of each services. It's worth a read! You might have already used some of the Microsoft SaaS offerings.</span></p><p><span style="font-family: arial;">Thanks to the author. Here is a link to his article. </span></p><p><a href="https://biz-excellence.com/2023/06/21/microsoft-saas/"><span style="font-family: arial;">https://biz-excellence.com/2023/06/21/microsoft-saas/</span></a></p><p><span style="font-family: arial;">If you want to understand the difference between SaaS (Software as a Service), PaaS (Platform as a Service) and IaaS (Infrastructure as a Service) please refer this nice and simple article by Paolo.</span></p><p><span style="font-family: arial;"><a href="https://www.linkedin.com/pulse/how-explain-iaas-paas-saas-pizza-maker-paolo-della-rocca">https://www.linkedin.com/pulse/how-explain-iaas-paas-saas-pizza-maker-paolo-della-rocca</a></span></p><p><br /></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-31303772385451817642022-05-30T21:52:00.000+01:002022-05-30T21:52:11.210+01:00Express Design - Sketch on Paper to Mobile App!<p><span style="font-family: arial;">Here is my favourite from the Microsoft Build 2022!</span></p><p><span style="font-family: arial;">Shared from: Ryan Cunningham </span></p><p><span style="font-family: arial;">Well, I would call it Express power but actually it is called Express Design</span></p><p><span style="font-family: arial;">Here is the shared video - A simple sketch on paper is turning into a working mobile app!! How Cool!!!</span></p><p><a href="https://www.microsoft.com/en-us/videoplayer/embed/RE4XPSq">https://www.microsoft.com/en-us/videoplayer/embed/RE4XPSq</a></p><p><br /></p><p><br /></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-89977904659081824852021-11-10T20:00:00.001+00:002021-11-10T20:00:00.169+00:00Azure Service Bus Large Message<p><span style="font-size: small;"><span style="font-family: arial;"> This was an amazing news for me from Ignite 2021!</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Azure service bus premium, now supports payloads upto 100MB. Previously, it was just 1MB and it was quite challenging for some requirements.Also that is a big jump 1MB to 100 MB!!! <br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><a href="https://azure.microsoft.com/en-gb/updates/azure-service-bus-large-message-support-reaches-general-availability/">https://azure.microsoft.com/en-gb/updates/azure-service-bus-large-message-support-reaches-general-availability/</a></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> <br /></span></span></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com4tag:blogger.com,1999:blog-7483666954520465023.post-63779269751370298712021-10-26T22:49:00.002+01:002021-10-26T22:49:59.071+01:00Auto Number Feature in Dynamics 365 CRM<p><span style="font-family: arial;">'Requester' comes with a requirement.<br /></span></p><p><span style="font-family: arial;"><i><b>Given</b></i> A specific entity is available in Dynamics 365 CRM<br /></span></p><p><span style="font-family: arial;"><i><b>When</b></i> A record is created in Dynamics 365 CRM</span></p><p><span style="font-family: arial;"><i><b>Then</b></i> An autonumber should be generated in a specific format after the record creation.<br /></span></p><p><span style="font-family: arial;">As we all know we used to write plugins for this requirement in Dynamics CRM 2011 version etc. But currently it is an out of the box feature (Introduced in 2019). It's just a new data type introduced by Microsoft. </span></p><p><span style="font-family: arial;">Note: This feature is only available in the new interface ( ie: https://make.powerapps.com/)</span></p><p><span style="font-family: arial;">So navigate to </span><span style="font-family: arial;">https://make.powerapps.com/ and choose the correct environment.</span></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZPC8sargNgF_LYiC7UCp1U2-jwXexPlVsAcEhHGF34bQeHSiRo_J_ntti81EfmO80Zn9JF5_9HNdh3g4NYxSJBTA5oOLvJqsrmFLigBUgd2Mg-ASVUSiyg1iioqCOrkqEDjv1kX0tOURu/s1905/1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="768" data-original-width="1905" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZPC8sargNgF_LYiC7UCp1U2-jwXexPlVsAcEhHGF34bQeHSiRo_J_ntti81EfmO80Zn9JF5_9HNdh3g4NYxSJBTA5oOLvJqsrmFLigBUgd2Mg-ASVUSiyg1iioqCOrkqEDjv1kX0tOURu/w640-h258/1.png" width="640" /></a></div><p><br /><span style="font-family: arial;">When you add a new column after choosing your solution, you would see the magic as a datatype : ). And then when a record is created ( post record creation), it populates the autonumber. Easy Peasy Lemon Squeezy!<br /></span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMZLMouDYWZQ79yjjLSMPc_uTnzGA5LunHbnl_-Uq5cc5oOgHFaPpY34roIr8p8ZVgGgYx4cRwQSc4qwAw2zvA8xePFjbbU8e6guy9Cwe1XJLIoWH-jLEXoJOJWTzEWQlsp6aOMcmScG9T/s614/1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="614" data-original-width="418" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMZLMouDYWZQ79yjjLSMPc_uTnzGA5LunHbnl_-Uq5cc5oOgHFaPpY34roIr8p8ZVgGgYx4cRwQSc4qwAw2zvA8xePFjbbU8e6guy9Cwe1XJLIoWH-jLEXoJOJWTzEWQlsp6aOMcmScG9T/s320/1.png" width="218" /></a></div><span style="font-family: arial;">But then the requester thinks that everything is super easy to do in Dynamics CRM / Power Platform. Well, not everything : )</span><br /><p><br /></p><p></p><p><span style="font-family: arial;"><br /></span></p><p><span style="font-family: arial;"><br /></span></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-78166508343735790252021-10-18T21:17:00.006+01:002021-10-18T21:17:55.657+01:00How to configure Dataverse Search?<p><span style="font-size: small;"><span style="font-family: arial;"> First Things First! "<span style="-webkit-text-stroke-width: 0px; background-color: white; color: #171717; display: inline !important; float: none; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;">Dataverse search helps you quickly find what you're looking for. It delivers fast and comprehensive results across multiple tables in a single list, sorted by relevance"</span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> Now here is the key bit "<span style="-webkit-text-stroke-width: 0px; background-color: white; color: #171717; display: inline !important; float: none; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;">Dataverse search is an opt-out feature, set to </span><strong style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: inherit; color: #171717; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 600; letter-spacing: normal; outline-color: inherit; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;">On</strong><span style="-webkit-text-stroke-width: 0px; background-color: white; color: #171717; display: inline !important; float: none; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"> by default with<span> </span></span><a data-linktype="absolute-path" href="https://docs.microsoft.com/en-us/power-platform-release-plan/2021wave2/power-apps/modern-search-all-end-users-model-driven-power-apps" style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: inherit; color: var(--theme-hyperlink); cursor: pointer; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; outline-color: inherit; outline-style: initial; outline-width: 0px; overflow-wrap: break-word; text-align: start; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;">2021 release wave 2</a><span style="-webkit-text-stroke-width: 0px; background-color: white; color: #171717; display: inline !important; float: none; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;">, on all production environments, except those using their own encryption key."</span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span style="-webkit-text-stroke-width: 0px; background-color: white; color: #171717; display: inline !important; float: none; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"> So if you run into issues related to global search after release wave 2, you know why. Because your table / entity maynot have configured for Dataverse Search. <br /></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span style="-webkit-text-stroke-width: 0px; background-color: white; color: #171717; display: inline !important; float: none; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;">Please refer the below Microsoft Link to see how to configure the dataverse search in detail. Mainly need to set up search indexes.<br /></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><a href="https://docs.microsoft.com/en-us/power-platform/admin/configure-relevance-search-organization">https://docs.microsoft.com/en-us/power-platform/admin/configure-relevance-search-organization</a></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> <br /></span></span></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com2tag:blogger.com,1999:blog-7483666954520465023.post-57069837176324768732021-05-16T23:30:00.000+01:002021-05-17T00:27:27.124+01:00Power App + Power Automate Realtime API call and Display Result - Use Case<p><span style="font-size: small;"><span style="font-family: arial;">Recently I had to explore on a scenario where a real time API call result to be displayed on a Power App. Phone number validation is the current context. There are different providers like Loqate, Prove etc who provides third party APIs to validate a phone number.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Scenario: Given a User enters a phone number on an embedded canvas app and clicks on the validate button. And Canvas App triggers a Power Automate. And Power Automate triggers a third party API. Then Canvas app displays result (Valid number / Not valid) in realtime. </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> Here is an architecture diagram to understand this scenario. Please note that API Management part is optional but highly recommended. In the demo, I haven't used it.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja0KwY9FgC3cQyCCowJeXcoeS0q9S_c0_nt27d_G0JTRLZZQVMO9ZB6NYBOnvSmRjfxBEMUEVnVKoD8xer5_B2zji6hyphenhyphenHGvTPurJ58UQvCNZscFuoWwNbpQJcVN46pFls8nb-b22MAO0n9/s1357/37.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="860" data-original-width="1357" height="406" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja0KwY9FgC3cQyCCowJeXcoeS0q9S_c0_nt27d_G0JTRLZZQVMO9ZB6NYBOnvSmRjfxBEMUEVnVKoD8xer5_B2zji6hyphenhyphenHGvTPurJ58UQvCNZscFuoWwNbpQJcVN46pFls8nb-b22MAO0n9/w640-h406/37.png" width="640" /></a></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><br />As you could see in the diagram, a user accesses an embedded Power App to validate a phone number. Behind the scene, Embedded Power App triggers a Power Automate and Power Automate does a Third party API call ( via API Management - optional ) And result is returned back to Power App. Power App displays the result back to the user. </span></span><p></p><p><span style="font-size: small;"><span style="font-family: arial;">Invalid Number Case: <br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPQafsuLpolcGPjiq_Ajj-r_gldJDsCodzGf8twpHkiFKq2C0TCWXCNnuoITFws52gqqIeGxCw2I988e4B6c4VJEEBt3oVPPtJ8ZfM1ud-56PurxiP4Ahvuk3y0CSh-f82KtuZpteZJpgg/s1455/38.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="832" data-original-width="1455" height="366" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPQafsuLpolcGPjiq_Ajj-r_gldJDsCodzGf8twpHkiFKq2C0TCWXCNnuoITFws52gqqIeGxCw2I988e4B6c4VJEEBt3oVPPtJ8ZfM1ud-56PurxiP4Ahvuk3y0CSh-f82KtuZpteZJpgg/w640-h366/38.png" width="640" /></a></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><br /> Valid number case : Tested with my own number : )</span></span><p></p><p><span style="font-size: small;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNCANwBVkFU0KM0oOBNyb9K03zrg_9ey9_Kf_o9si8QRWoCXECim8ixW0tm3PcX5gFlYqep-9EZYKOxElBDtW1DbR3RsZabVVrklvuuhDmaXT-kmOuQPvyxA1GYc4AlTCevF-1DNJveyXj/s1468/39.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="787" data-original-width="1468" height="344" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNCANwBVkFU0KM0oOBNyb9K03zrg_9ey9_Kf_o9si8QRWoCXECim8ixW0tm3PcX5gFlYqep-9EZYKOxElBDtW1DbR3RsZabVVrklvuuhDmaXT-kmOuQPvyxA1GYc4AlTCevF-1DNJveyXj/w640-h344/39.png" width="640" /></a></span></div><span style="font-size: small;"><br /><span style="font-family: arial;">Let's see how it works!<br /></span></span><p></p><p><span style="font-size: small;"><span style="font-family: arial;"> For demo purpose, I have signed up a trial from Loqate to test the phone number validation scenario. This API doesn't have to be Loqate, whichever provider you prefer.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Loqate documentation could be found here -https://www.loqate.com/resources/support/apis/PhoneNumberValidation/Interactive/Validate/2.2/</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">This API can be tested from Postman first. Unfortunately the result from this webservice is in a table format. So it is a bit tricky to parse the results. In this case I just did the bare minimum. If you have a provider which returns in JSON, you could easily parse it using JSON parser in Power Automate.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span></p><p><span style="font-size: small;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-KkBKakWu6UExit6oZ3Alnp-GlqYcMsyC5cqBCEXw_3UbXzpylCxwvqiS3XE4NMEpv7CKl0_xg4HgfHQuY1H_smuGpy3ZJNgKko1MuV1Yn7pLl3pIRNx7IhWvNGm3ByYgrg9VFXJpo8cQ/s1301/40.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="570" data-original-width="1301" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-KkBKakWu6UExit6oZ3Alnp-GlqYcMsyC5cqBCEXw_3UbXzpylCxwvqiS3XE4NMEpv7CKl0_xg4HgfHQuY1H_smuGpy3ZJNgKko1MuV1Yn7pLl3pIRNx7IhWvNGm3ByYgrg9VFXJpo8cQ/w640-h280/40.png" width="640" /></a></span></div><span style="font-size: small;"><br /><span style="font-family: arial;"></span></span><p></p><p><span style="font-size: small;"><span style="font-family: arial;">Now let's take a look at the embedded canvas App. Very simple Canvas App here. Validate button calls a PowerAutomate as shown here. </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Please note the formula Set(outputFromPowerAutomate,PowerAutomatePhoneNumberAPI.Run(txtNumberInput.Text))</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Here outputFromPowerAutomate is a new variable which would hold the return value from Power Automate. So we set this variable with the result. txtNumberInput is the phonenumber value from the user.</span></span></p><p><span style="font-size: small;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikps_C46Qdb3jzYSqGdJ42BxJn4oaPDyd2z1MJj8k_TLB0yWGFc-2tSZAuKkB5Ax6yM5_MYcMftyikFAnXozRfZ7CEIdKWJ69lYkLbv1gMglKH0mfes3js6G9CcYvWnANYQm0iv5zwYqDQ/s1912/41.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="483" data-original-width="1912" height="162" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikps_C46Qdb3jzYSqGdJ42BxJn4oaPDyd2z1MJj8k_TLB0yWGFc-2tSZAuKkB5Ax6yM5_MYcMftyikFAnXozRfZ7CEIdKWJ69lYkLbv1gMglKH0mfes3js6G9CcYvWnANYQm0iv5zwYqDQ/w640-h162/41.png" width="640" /></a></span></div><p><span style="font-size: small;"><br /><span style="font-family: arial;">Now I have a simple label Text with the below formula.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXRPb9aUaaiNoR6wETCBwOeSYdBQW9UXXIx6AoyvEjnJnjbsCbakUeMPe6Fnpw4N3wmvIG1g-brwVWLl8hKLxQrf0MdZDznlOA1xI5FI3fhQNB9Fy8DG8NT-ao3SmsQjqr1QRL-4lfgXdD/s1889/45.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="433" data-original-width="1889" height="146" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXRPb9aUaaiNoR6wETCBwOeSYdBQW9UXXIx6AoyvEjnJnjbsCbakUeMPe6Fnpw4N3wmvIG1g-brwVWLl8hKLxQrf0MdZDznlOA1xI5FI3fhQNB9Fy8DG8NT-ao3SmsQjqr1QRL-4lfgXdD/w640-h146/45.png" width="640" /></a></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><br /> </span></span><p></p><p></p><p><span style="font-size: small;"><span style="font-family: arial;"> If(IsMatch( outputFromPowerAutomate.result, "Yes", Contains),"Result: Number is Valid","Result: Not Valid")</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">It displays the result based on the result from the Power Automate. As it is simple demo, it is only checking for the word Yes here. In a real scenario, the result needs to be parsed correctly and display accordingly.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Now let's the main one, Power Automate.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Key steps are here. But will expand each step further below.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijnz9JGiks5IvLgEsiL6BdNDefy1ce1P9k2SiBEjOR8tTLAM6E30gfWqHbAVIlUNlaA-dM6GOeV25imlIIwmOVujeDAHnCZdODLPCh73rl4RriODPsYgGkao8wEOhuCKefpLddVCTBSKjg/s1244/42.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="478" data-original-width="1244" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijnz9JGiks5IvLgEsiL6BdNDefy1ce1P9k2SiBEjOR8tTLAM6E30gfWqHbAVIlUNlaA-dM6GOeV25imlIIwmOVujeDAHnCZdODLPCh73rl4RriODPsYgGkao8wEOhuCKefpLddVCTBSKjg/w640-h246/42.png" width="640" /></a></span></span></div><p></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">First step is just a Power Apps step which represents a trigger received from a Power App. Second step is an HTTP call as shown below. Phone number value is received from the Power App. Key needs to be provided. Method is a GET operation. URL depends on your provider. In this context, Loqate webservice is used.<br /> </span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj95PusHz0xUpFZfsVXKs_Ih73kUjaA4lU6j-nhj23lNw1IUAn5WTQ_OFemXHcXASnVPxkuyGFG2dl3ei9pLCYNyOr7_6UCttMKrbHCsUhcItHJbAY5w6LEbUBXgVpAyVzmtjsFY9OvkEbg/s1394/43.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="865" data-original-width="1394" height="398" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj95PusHz0xUpFZfsVXKs_Ih73kUjaA4lU6j-nhj23lNw1IUAn5WTQ_OFemXHcXASnVPxkuyGFG2dl3ei9pLCYNyOr7_6UCttMKrbHCsUhcItHJbAY5w6LEbUBXgVpAyVzmtjsFY9OvkEbg/w640-h398/43.png" width="640" /></a></span></span></div><p></p><p><span style="font-size: small;"><span style="font-family: arial;">Final step is return to Power App. Result is a variable which holds the body results from the HTTP step.<br /></span></span></p><p><span style="font-size: small;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFqxU8ep68tt4lQO0syJvxw6jlDAwm2IUQ2dl6pSluZvuq1SU-3Xtj_Y6AgdACaeEAgsK8bHAdQvZWbbWckD8t4Qm1IXjvfBR7dNQyU4l5AXS1F77jHpnnZrV1AZ3VyCRs1OzGpqPLCuYY/s749/44.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="222" data-original-width="749" height="190" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFqxU8ep68tt4lQO0syJvxw6jlDAwm2IUQ2dl6pSluZvuq1SU-3Xtj_Y6AgdACaeEAgsK8bHAdQvZWbbWckD8t4Qm1IXjvfBR7dNQyU4l5AXS1F77jHpnnZrV1AZ3VyCRs1OzGpqPLCuYY/w640-h190/44.png" width="640" /></a></span></div><span style="font-size: small;"><br /><span style="font-family: arial;"><br /></span></span><p></p><p><span style="font-size: small;"><span style="font-family: arial;">Please note that this is a simple demonstration of API call from Power App + Power Automate. So it just returns the API response to Power App as it is.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">You might need further steps to process the results in a real scenario. For instance, parse the JSON from the API call etc. </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Depending on your scenario / requirements, you could add / remove steps from Power Automate and modify the Power App accordingly.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">I hope it helps : )<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span><br /></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com10tag:blogger.com,1999:blog-7483666954520465023.post-43139452161718751052021-04-18T23:25:00.005+01:002021-04-18T23:50:13.305+01:00Deprecation of Office 365 Authentication Type in Dynamics 365 CRM<p><span style="font-family: arial;"><span style="font-size: small;"><span><span>If you are connecting to Dynamics 365 CRM from a micro service, service, azure function, web apps, web jobs etc you might be using Organization service connectivity. There is an important deprecation happening with this connectivity. OauthType of Office365 wouldn't be supproted in the future. <br /></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span>Office 365 Authentication Type and OrganizationServiceProxy would be deprecated soon. Key dates are below. But I would highly recommend to replace them as soon as possible and test. This post will provide some tips on how to replace them. Views are my own.<br /></span></span></span></span></p><ul style="text-align: left;"><li><span style="font-family: arial;"><span style="font-size: small;"><span><span><span> Effective April 2021, the authentication protocol will be retired for all new environments within a tenant.</span></span></span></span></span></li><li><span style="font-family: arial;"><span style="font-size: small;"><span><span><span> Effective April 2022, the authentication protocol will be retired for all new and existing environments within a tenant.</span></span></span></span></span></li></ul><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>As you all know there are two type of connectivities to Dynamics 365 CRM.</span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>1. Organization Service ( SOAP)</span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>2. CRM Web API (REST API)</span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>This post is regarding organization service only. If you want to know more about CRM Web API have a look at this post - <a href="https://crmdm.blogspot.com/2020/12/dynamics-365-crm-web-api-with-azure.html">https://crmdm.blogspot.com/2020/12/dynamics-365-crm-web-api-with-azure.html</a></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>If you want to find out whether you would be affected, here are the recommendations from the microsoft documentations.<br /></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>1) Check your connection string of the micro service / web app / web job etc. If it has AuthType as Office 365, you need to action on it. For instace, a sample is given below.(ref: Microsoft) </span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span><span style="color: #171717;">connectionString = "AuthType=Office365;Username=jsmith@contoso.onmicrosoft.com;Password=passcode;Url=https://contoso.crm.dynamics.com"</span> <br /></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>(2) In your source code search for OrganizationServiceProxy to see if it is in use. Please note that it is 'z' not s. So make sure you search it correctly. </span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>"Remove all use of that property in your code. CrmServiceClient implements IOrganizationService and exposes everything that is settable for the organization service proxy." - This is the change for OrganizationServiceProxy. Just code changes required as per this instruction and make sure that no OrganizationServiceProxy is in use.<br /></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>If these are applicable to you then below are some tips for the connection string part.<br /></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span> If you are already using AuthType=Office365, that needs to be replaced by AuthType=OAuth. Now if you are thinking, it is just a keyword change, nope, it is not. It is much more than that.</span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Here is the sample OAuth AuthType sample from Microsoft.</span></span></span></span></span></p><p><span style="color: #171717;"><span style="font-size: small;"><span style="font-family: arial;">connectionString = "AuthType=OAuth;Username=jsmith@contoso.onmicrosoft.com; Password=passcode;Url=https://contosotest.crm.dynamics.com;AppId=51f81489-12ee-4a9e-aaae-a2591f45987d; RedirectUri=app://58145B91-0C36-4500-8554-080854F2AC97;LoginPrompt=Auto"</span></span></span><br /></p><p><span style="font-family: arial;"><span style="font-size: small;"><span style="-webkit-text-stroke-width: 0px; background-color: #e3e3e3; color: #171717; display: inline; float: none; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Some bits are easy here and some are can be a bit confusing. Here is diagram to understand the concept.</span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5gEpaK7aXDeNUSJ-VhAimRO9GPQpAx96xe7mRaavOFvVLE8UPZboly7nkInG-oaYO5-NnHp02JIllk6Jlrr3V5O6uOaGfpapyV9kXDukqtBivawdBHHiZlQtQfv7KROUDK9j2_PPETkuq/s725/2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="375" data-original-width="725" height="332" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5gEpaK7aXDeNUSJ-VhAimRO9GPQpAx96xe7mRaavOFvVLE8UPZboly7nkInG-oaYO5-NnHp02JIllk6Jlrr3V5O6uOaGfpapyV9kXDukqtBivawdBHHiZlQtQfv7KROUDK9j2_PPETkuq/w640-h332/2.png" width="640" /></a></span></span></span></span></div><span style="font-family: arial;"><span style="font-size: small;"><span><span>As you could imagine, it brings an extra layer of security. <br /></span></span></span></span><p><span style="font-family: arial;"><span style="font-size: small;"><span><span>First part is the connection using Office 365. Very straightforward one, just need username, password and url - This connection type wouldn't be supported anymore.<br /></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span>Second one is the OAuth type. In addition to username, password and url we need application id, redirect url which is registered in App registrations of Azure Active Directory.</span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span>In other words, this new OAuth type authentication is happening in 2 stages. </span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span>1st stage - It authenticates the user</span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span>2nd stage - It authenticates the application using application user + app registration. <br /></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Let's see the azure set up first. Usually azure part is configured by an infrastructure engineer. I have explained the steps for your understanding. If you just want to see the code part, it is at the bottom of this post.<br /></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Navigate to <a href="https://portal.azure.com">https://portal.azure.com</a></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Navigate to Azure Active Directory</span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span></span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdR2hQXQwnmwHFOLCZyGpxywr-zmzTnUPUa6Zm5-LCfN0QQ8y62xBfraE9FCvTOWo9eMaEXKB8kqUheFcxL1n_uQaL_jATVoIMIFeAP2eLqSr4_HOq7-ifSOGuC7qCqbyfJpOS8dNcGzGp/s1433/3.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="226" data-original-width="1433" height="100" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdR2hQXQwnmwHFOLCZyGpxywr-zmzTnUPUa6Zm5-LCfN0QQ8y62xBfraE9FCvTOWo9eMaEXKB8kqUheFcxL1n_uQaL_jATVoIMIFeAP2eLqSr4_HOq7-ifSOGuC7qCqbyfJpOS8dNcGzGp/w640-h100/3.png" width="640" /></a></span></span></span></span></div><span style="font-size: small;"><span><span><span><br /> Select the Users part from the Active Directory. </span><span><br /></span></span></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span> </span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3Dfupztlc3gicvDFUMtyyaj-dSgWh3-BCZQ62BOs1WPQFr6aTDNHRMat2EYEEm97OLUKBSmkRLck7oxGTIayHQeCLCUy_DqqIMhHIgkHgUEU6T2PePchnEfC14zoxaCAl93OFa-hlVkP2/s934/5.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="934" data-original-width="332" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3Dfupztlc3gicvDFUMtyyaj-dSgWh3-BCZQ62BOs1WPQFr6aTDNHRMat2EYEEm97OLUKBSmkRLck7oxGTIayHQeCLCUy_DqqIMhHIgkHgUEU6T2PePchnEfC14zoxaCAl93OFa-hlVkP2/w228-h640/5.png" width="228" /></a></span></span></span></span></div><span style="font-size: small;"><span><span><span><br /></span></span></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span> Click on New User button. </span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMj-l566HHhnC_SFWoldDk27H03RyVca0ziszzBiDlv_iYix_c0xl48V0Ufq_ug7hxp27OH0zhcAjsONlSNGhDYqhFbtB94VgFGBtC3dk8lO33YXFBMcmR4tCL_eQ_iR1pINmIA5wFvAgk/s1409/6.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="334" data-original-width="1409" height="152" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMj-l566HHhnC_SFWoldDk27H03RyVca0ziszzBiDlv_iYix_c0xl48V0Ufq_ug7hxp27OH0zhcAjsONlSNGhDYqhFbtB94VgFGBtC3dk8lO33YXFBMcmR4tCL_eQ_iR1pINmIA5wFvAgk/w640-h152/6.png" width="640" /></a></span></span></span></div><span style="font-size: small;"><span><span><br /><span><br /></span></span></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span> Create the user with the preferred name. It also provides the option to set the password. Take a note of username and pwd as this is needed in the connection string. </span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span> </span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2iDINCsMQngEyxNiA4eF45QQQvtoj0zSnAaRD1SXxu2YL_0gd-d9jGDitgRg5rBcRFvIImNRgycZBBSv1xUQ-CNQ4LmNKKd_tq_R4bWOQjwfrh0QUut8U_vI9isjP0naz65wM7dw0tIBd/s923/7.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="923" data-original-width="842" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2iDINCsMQngEyxNiA4eF45QQQvtoj0zSnAaRD1SXxu2YL_0gd-d9jGDitgRg5rBcRFvIImNRgycZBBSv1xUQ-CNQ4LmNKKd_tq_R4bWOQjwfrh0QUut8U_vI9isjP0naz65wM7dw0tIBd/w584-h640/7.png" width="584" /></a></span></span></span></span></div><span style="font-size: small;"><span><span><span><br /></span></span></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span> Once created, the user is listed in the users list. We use this user for the stage 1<br /></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFBi1-gn0kpEiqR95nSK9wDaIbyihGs7TLWsXXX76szXKCG-GgplVhJQ92-apC5wRyHYFdXURP0OjXAtryWC14hReTxAkSOEbBt3A-S3aG_OehoaM8PVpt3aNDr9TbTnNiwyoQdXQLfyzI/s1510/4.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="670" data-original-width="1510" height="284" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFBi1-gn0kpEiqR95nSK9wDaIbyihGs7TLWsXXX76szXKCG-GgplVhJQ92-apC5wRyHYFdXURP0OjXAtryWC14hReTxAkSOEbBt3A-S3aG_OehoaM8PVpt3aNDr9TbTnNiwyoQdXQLfyzI/w640-h284/4.png" width="640" /></a></span></span></span></div><span style="font-size: small;"><span><span>Log on to Microsoft 365 Admin center to assign a license to this user.<span><br /></span></span></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span> </span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrIIzYHFfUgjs1-Rj-mRSgIimTBe2pHby74v_YRxspgG45TPTtujirTON0NbczQVTvDD48OG5A8_fr8J98CbIl9Kwe8-kh5gWLyTLiZ69tN9HfwQa-0AVtvwvuVa-swH0kNlB6yDkXRt30/s1687/8.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="651" data-original-width="1687" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrIIzYHFfUgjs1-Rj-mRSgIimTBe2pHby74v_YRxspgG45TPTtujirTON0NbczQVTvDD48OG5A8_fr8J98CbIl9Kwe8-kh5gWLyTLiZ69tN9HfwQa-0AVtvwvuVa-swH0kNlB6yDkXRt30/w640-h246/8.png" width="640" /></a></span></span></span></span></div><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Select the user and assign license. In this case, CE license is assigned.<br /></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUfzNL_ueVEB-EXsENfaZZNBe56wdvoSo2I2rfeA2eWOgNb-uSKN4iV2f5YnFeTLZmURYxNTxtIuqWek3EzrNH8wFNxEgIYEK4dXHQ8jWP-D3bh37CQL5wI87l2DDTUg1ejDK7mcZaVVb4/s1851/9.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="919" data-original-width="1851" height="318" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUfzNL_ueVEB-EXsENfaZZNBe56wdvoSo2I2rfeA2eWOgNb-uSKN4iV2f5YnFeTLZmURYxNTxtIuqWek3EzrNH8wFNxEgIYEK4dXHQ8jWP-D3bh37CQL5wI87l2DDTUg1ejDK7mcZaVVb4/w640-h318/9.png" width="640" /></a></span></span></span></div><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>So stage 1 is ready - We have a user, passord ready to go.</span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Stage 2 is setting up the app registration to get application id, redirect url.</span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>So navigate to Azure Active Directory again and choose app registrations section.</span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjG7AktOAakuUIm86sB6HF5bEoUeATgSG6a23QckAknaisa8cDHz0VdJh1f4VAPyUUHkCyndpUotlLJ126q25E6BHLDYIbkWGd7_kYeFbyS4WJE2LVXbfINw7qpMFFXcKBuIiBuLPycM0r/s1458/10.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="906" data-original-width="1458" height="398" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjG7AktOAakuUIm86sB6HF5bEoUeATgSG6a23QckAknaisa8cDHz0VdJh1f4VAPyUUHkCyndpUotlLJ126q25E6BHLDYIbkWGd7_kYeFbyS4WJE2LVXbfINw7qpMFFXcKBuIiBuLPycM0r/w640-h398/10.png" width="640" /></a></span></span></span></div><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Register a new application. Redirect URI can be a bit confusing. </span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Here is the documentation part - "</span></span></span><span><span><span>We’ll return the authentication response to this URI after successfully
authenticating the user. Providing this now is optional and it can be
changed later, but a value is required for most authentication
scenarios." </span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>So what value to be provided, it is upto you and it depends on your scenario. It doesn't have to be a working url as per my understanding. So here I have provided localhost (https://localhost). Important bit is that a url to be provided, and that should be the same url in your connection string (both should match). <br /></span></span></span></span></span></p><p><span style="font-family: arial;"></span><span style="font-family: arial;"><span style="font-size: small;"><span><span><span><span face="SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace" style="-webkit-text-stroke-width: 0px; background-color: #e3e3e3; color: #171717; display: inline; float: none; font-size: 13.6px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"></span></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Click on the Register button.<br /></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOqDMCX5U1CQnQQBXWLlxlvEtQFFz5HjetXFxa2O41kLpuMIGdgmBJMcgg9fZs1wvxGKKgBie-a-KFTcWuKxKdE8VpZDPLpyBV0Jql-fHzpK5pt8uKEwETn5eaF0QRo4ZqFoKnryZTsPZV/s1234/1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1234" height="466" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOqDMCX5U1CQnQQBXWLlxlvEtQFFz5HjetXFxa2O41kLpuMIGdgmBJMcgg9fZs1wvxGKKgBie-a-KFTcWuKxKdE8VpZDPLpyBV0Jql-fHzpK5pt8uKEwETn5eaF0QRo4ZqFoKnryZTsPZV/w640-h466/1.png" width="640" /></a></span></span></span></div><span style="font-size: small;"><span><span><br /><span><br /></span></span></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Open the app registration and note the application id. This application needs to be provided in the connection string. Also see the highlighted sections. Click on API Permissions as the next step.<br /></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJj7woRrQH2HlCegtINoAb4rjn-yXVBTT9RpOPAp8tGzEbHz5q_5hfJ1pHvfImqaA7B8Mlb9Kdko2s_hh1CZ21eJArko-pBhv-0hvSoVb7lCJehMldUhqFwDPOgejQsquG43oZzSZcLB-a/s1535/11.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="926" data-original-width="1535" height="386" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJj7woRrQH2HlCegtINoAb4rjn-yXVBTT9RpOPAp8tGzEbHz5q_5hfJ1pHvfImqaA7B8Mlb9Kdko2s_hh1CZ21eJArko-pBhv-0hvSoVb7lCJehMldUhqFwDPOgejQsquG43oZzSZcLB-a/w640-h386/11.png" width="640" /></a></span></span></span></div><span style="font-size: small;"><span><span><span><br /></span></span></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Click on Add Permission</span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEji10bCQazxR_bOz-bVoPBt1Dw3CZSRf_Ge3DOmSLWY2PcP_mSk6iUtnMmZs1cpYs3mRstBPjn4EpxvYmvOdKgVhGsAC7xIrKKiduiklsAFuNe9oMfZ4JD37Aj3o0vkJnEJrpqR3Wis7J-G/s1342/12.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="510" data-original-width="1342" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEji10bCQazxR_bOz-bVoPBt1Dw3CZSRf_Ge3DOmSLWY2PcP_mSk6iUtnMmZs1cpYs3mRstBPjn4EpxvYmvOdKgVhGsAC7xIrKKiduiklsAFuNe9oMfZ4JD37Aj3o0vkJnEJrpqR3Wis7J-G/w640-h244/12.png" width="640" /></a></span></span></span></div><span style="font-size: small;"><span><span><br /><span>Select Dynamics CRM from the API list.</span></span></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhei8AqpVxFeUh93lXXTIfbfh97rzFJ7-uIkbMf99pdvpSS2n1ZL7kAjX8wnc4t-2tbcUiuRMHV3OV7z-BDEbErgtqyfbUGA4FBr0FzJdBoGm0fKWyUFB3yFwmSqIynPwtfj3SMZ_u_tFxr/s1058/13.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="878" data-original-width="1058" height="532" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhei8AqpVxFeUh93lXXTIfbfh97rzFJ7-uIkbMf99pdvpSS2n1ZL7kAjX8wnc4t-2tbcUiuRMHV3OV7z-BDEbErgtqyfbUGA4FBr0FzJdBoGm0fKWyUFB3yFwmSqIynPwtfj3SMZ_u_tFxr/w640-h532/13.png" width="640" /></a></span></span></span></div><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span>Tick user_impersonation and click on Add Permissions button.<br /></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgb4evg3EuKtTaWuIZQuxr3DipjtFFz_kjVfz9jdpCipcIoPjT7cWS_76Et1CfbS9f4h5nw5aVE6P1xzlg8nMFieHW5NpGiz5FXm0DqGuTo1Ai3hd_8dz8z7gWq5aJPWfAfGsgICVDOjTxf/s1060/14.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="882" data-original-width="1060" height="532" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgb4evg3EuKtTaWuIZQuxr3DipjtFFz_kjVfz9jdpCipcIoPjT7cWS_76Et1CfbS9f4h5nw5aVE6P1xzlg8nMFieHW5NpGiz5FXm0DqGuTo1Ai3hd_8dz8z7gWq5aJPWfAfGsgICVDOjTxf/w640-h532/14.png" width="640" /></a></span></span></span></div><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span>Also grant admin consent as well.<br /></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span><br /></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxKsLakaKp2CVvObzr3oQgH5D07NrBPKkqdneAzTCXbwmpt5lN1t3XvTWLf84uoC4EIlCyXbMVfKN9fadRAiJxmnlB7M8Qn90KEEiZtxyROXV4G3vFiTFInnmoH81OyPxudbgdiyrQ2bSK/s909/15.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="508" data-original-width="909" height="358" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxKsLakaKp2CVvObzr3oQgH5D07NrBPKkqdneAzTCXbwmpt5lN1t3XvTWLf84uoC4EIlCyXbMVfKN9fadRAiJxmnlB7M8Qn90KEEiZtxyROXV4G3vFiTFInnmoH81OyPxudbgdiyrQ2bSK/w640-h358/15.png" width="640" /></a></span></span></span></div><span style="font-size: small;"><span><span><br /><span>Next step is to set the Manifest. Navigate to app registration and choose Manifest section. Set allowPublicClient to true. And then click on the Save button.<br /></span></span></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUvLH9On7uAgFl69Gsw3WxVfalFwGfEJaD_y0-DWGE-dHL-8k8S2MXkpk6e8BkQx1R16Kkwq7MNkqI-ArGwrjLqQyZIwv92RVRkedaxwIsURSr__bPEuCeg3SpwF6TCXLIMKoLV59abfFe/s1325/16.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="915" data-original-width="1325" height="442" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUvLH9On7uAgFl69Gsw3WxVfalFwGfEJaD_y0-DWGE-dHL-8k8S2MXkpk6e8BkQx1R16Kkwq7MNkqI-ArGwrjLqQyZIwv92RVRkedaxwIsURSr__bPEuCeg3SpwF6TCXLIMKoLV59abfFe/w640-h442/16.png" width="640" /></a></span></span></span></div><span style="font-size: small;"><span><span><br /><span>Azure part is done!</span></span></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Now navigate to Dynamics 365 CRM and users area. Add an application user by clicking the new button.<br /></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1TKKn5F16NAdIQ_8lxEikIi8iRyVZBYJQ_2iZ5zQr8MIQeP5bSVrtfXbc236Bpk3W6402ErGrdP84ynlVxC1AbgDX248bxsyXa8NxacTEe9WR73IWTtizfFZ9XJYi4P5mq-poD35sOhAd/s1914/17.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="254" data-original-width="1914" height="84" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1TKKn5F16NAdIQ_8lxEikIi8iRyVZBYJQ_2iZ5zQr8MIQeP5bSVrtfXbc236Bpk3W6402ErGrdP84ynlVxC1AbgDX248bxsyXa8NxacTEe9WR73IWTtizfFZ9XJYi4P5mq-poD35sOhAd/w640-h84/17.png" width="640" /></a></span></span></span></div><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span> The only information you need to provide here is application id from Azure AD app registration. Rest is populated by Dynamics when the record is saved. <br /></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><br /></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNVx9PGXWxjykYuss0z7JCbT7vGTSTQTklmtYsjkAKG5vIkk1OdAp5_4_3fWwFhsssqRSkJ1bc9vpHzRfh3QtDVnOTMj4GnObbM0tOwP0D_NvjOkacVYIb8vSFBchkSIxl2kTTA60ZCKkX/s988/18.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="915" data-original-width="988" height="592" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNVx9PGXWxjykYuss0z7JCbT7vGTSTQTklmtYsjkAKG5vIkk1OdAp5_4_3fWwFhsssqRSkJ1bc9vpHzRfh3QtDVnOTMj4GnObbM0tOwP0D_NvjOkacVYIb8vSFBchkSIxl2kTTA60ZCKkX/w640-h592/18.png" width="640" /></a></span></span></span></div><span style="font-size: small;"><span><span><br /><span>So here is the record after saving.</span></span></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheuRZgrab7Gg4-XY2cBnBY2os0Otne46hoQUDI06SWUdQMTi4zbEw3XO5uvNs8kVS9nXSAc0VkEQlBQb43fHlQbhbbscCsCbDziduGaYq_i-2Wf5lsgm4da5_Ft7pzhoS2AZb6p1qf_rPZ/s1402/19.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="923" data-original-width="1402" height="422" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheuRZgrab7Gg4-XY2cBnBY2os0Otne46hoQUDI06SWUdQMTi4zbEw3XO5uvNs8kVS9nXSAc0VkEQlBQb43fHlQbhbbscCsCbDziduGaYq_i-2Wf5lsgm4da5_Ft7pzhoS2AZb6p1qf_rPZ/w640-h422/19.png" width="640" /></a></span></span></span></div><span style="font-size: small;"><span><span><br /><span>Now one final bit is missing - Assign the security role for this application user.<br /></span></span></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjX8M-98Edgq9r3_UOrwtQ89A7b7au02EzD5GDWBCPir_pIvTwHg4AX3_uZUWl0DaSsNezdqpKlP1XFd9IM-KhMAy9Uo0jf4LPZW1ZTnlisDUGQ6qfJ43hTZfIJc4x1N75aukuJ9vmbwm11/s1920/20.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="915" data-original-width="1920" height="304" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjX8M-98Edgq9r3_UOrwtQ89A7b7au02EzD5GDWBCPir_pIvTwHg4AX3_uZUWl0DaSsNezdqpKlP1XFd9IM-KhMAy9Uo0jf4LPZW1ZTnlisDUGQ6qfJ43hTZfIJc4x1N75aukuJ9vmbwm11/w640-h304/20.png" width="640" /></a></span></span></span></div><span style="font-size: small;"><span><span><br /><span>Ready to roll!</span></span></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>I have created a very simple .Net framework based console app to test it. Please note that organization service is not supported by .NET core. So it has to be a .NET framework app.</span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUxhHy19-Ndr-hRWML-_0vxQ-Flb-W_-wQvTKJhIZ1fpkiZAsQjjzpPkzWrPpNRjQyoceQgnbgkiiZSCc3IJFIkdJXYbgaLCecTMcU3Mn7l1Zgag6p3T3UVC9Qgfbdn5jsw9uujq1ow6hR/s1877/21.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="964" data-original-width="1877" height="328" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUxhHy19-Ndr-hRWML-_0vxQ-Flb-W_-wQvTKJhIZ1fpkiZAsQjjzpPkzWrPpNRjQyoceQgnbgkiiZSCc3IJFIkdJXYbgaLCecTMcU3Mn7l1Zgag6p3T3UVC9Qgfbdn5jsw9uujq1ow6hR/w640-h328/21.png" width="640" /></a></span></span></span></div><span style="font-size: small;"><span><span><br /><span>Sample code for a simple WhoAmI request is below. Connection string to be replaced with yours.</span></span></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span><br /></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>using Microsoft.Crm.Sdk.Messages;<br />using Microsoft.Xrm.Tooling.Connector;<br />using System;<br /><br />namespace OrganizationServiceDemo<br />{<br /> public class Program<br /> {<br /> public static void Main(string[] args)<br /> {<br /> </span></span></span><br /><span><span><span><span><span><span> string dynamicsCrmConnectionString =<br />
"AuthType=OAuth;Url=https://yourorganization.crm11.dynamics.com;Username=youruser@yourorganization.onmicrosoft.com;Password=yourpassword;AppId=yourappguid;RedirectUri=https://localhost;LoginPrompt=Never;";</span></span></span></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span><span><span><span> <span> </span><span> </span><span> </span>CrmServiceClient.MaxConnectionTimeout= new TimeSpan(0, 5, 0);</span></span></span><br /> CrmServiceClient client = new CrmServiceClient(dynamicsCrmConnectionString);<br /><br /> if (client.IsReady)<br /> {<br /> var whoAmIResult = client.Execute(new WhoAmIRequest());<br /><br /> foreach (var item in whoAmIResult.Results)<br /> {<br /> Console.WriteLine($"\n Key - {item.Key}");<br /> Console.WriteLine($" Value - {item.Value}");<br /> }<br /><br /> Console.ReadLine();<br /> }<br /><br /> }<br /> }<br />}<br /></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Please note this line - CrmServiceClient.MaxConnectionTimeout= new TimeSpan(0, 5, 0);</span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Default connection timeout for organization service is 2 minutes. If you want to set a higher time out value ie: if your application need connection to organization service for more than 2 minutes at a time, this the setting to be used. In Oauth type connection, it has become a static property. In Office365 connection, it used to be tied up with service client it self and not static.</span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>In this scenario it is setting the connection time out to 5 min.</span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span><br /></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>Result from the console:<br /></span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNV4nOATQyQw1oKQKnTGy2aJtRslcxYpsXhn330f0A7aCpdz0sSfx6LTCz0PoKUqH-gIsn1qlyuY0duC9OZRz_9igqsq7Rh0FC4v9sAUbZW2lD0of3rHLVkFMA3luVqcGAcxpZBOJT66bK/s474/22.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="210" data-original-width="474" height="284" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNV4nOATQyQw1oKQKnTGy2aJtRslcxYpsXhn330f0A7aCpdz0sSfx6LTCz0PoKUqH-gIsn1qlyuY0duC9OZRz_9igqsq7Rh0FC4v9sAUbZW2lD0of3rHLVkFMA3luVqcGAcxpZBOJT66bK/w640-h284/22.png" width="640" /></a></span></span></span></div><span style="font-size: small;"><span><span><br /><span></span></span></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>References to Microsoft documentation is below.</span></span></span></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span></span></span></span></span></span></p><p><a href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/authenticate-office365-deprecation"><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>https://docs.microsoft.com/en-us/powerapps/developer/data-platform/authenticate-office365-deprecation</span></span></span></span></span></a><span style="font-family: arial;"><span style="font-size: small;"><span><span><span> <br /></span></span></span></span></span></p><p><a href="https://docs.microsoft.com/en-us/power-platform/important-changes-coming#deprecation-of-office365-authentication-type-and-organizationserviceproxy-class-for-connecting-to-common-data-service"><span style="font-family: arial;"><span style="font-size: small;"><span><span><span>https://docs.microsoft.com/en-us/power-platform/important-changes-coming#deprecation-of-office365-authentication-type-and-organizationserviceproxy-class-for-connecting-to-common-data-service</span></span></span></span></span></a></p><p><span style="font-family: arial;"><span style="font-size: small;"><span><span><span> I hope it helps!<br /></span></span></span></span></span></p><div><p><span style="font-family: arial;"><span style="font-size: small;"><br /><span><span><span> </span></span></span><br /><span><span><span> <br /></span></span></span></span></span></p></div>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-36048755897160765772021-03-22T22:40:00.000+00:002021-03-22T22:40:34.694+00:00Dynamics 365 CRM Diagnostic Tests / NFR Testing<p><span style="font-size: small;"><span style="font-family: arial;"> Dynamics 365 CRM provides an out of the box diagnostics test option. This could be useful if there is a requirement to test the NFRs ( Non-functional Requirements) against Dynamics 365 CRM. If you are not familiar with NFRs here is a simple definition for you<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><em>"Non-functional testing is done to verify the non-functional requirement of the application like Performance, Usability, etc."</em></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><em>Ref: <a href="https://www.softwaretestinghelp.com/what-is-non-functional-testing/ " target="_blank">https://www.softwaretestinghelp.com/what-is-non-functional-testing/ </a><br /></em></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Navigate to this url -<em><a data-linktype="external" href="https://myorg.crm.dynamics.com/tools/diagnostics/diag.aspx">https://myorg.crm.dynamics.com/tools/diagnostics/diag.aspx</a></em></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><b>Note</b> : myorg should be replaced with your organisation name.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Here is a sample run on my D365 CRM trial organisation. And yes, just need to click on that Run button!<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5Kk9qnYBVtg1UGkG0mNEucbz4OAHo5ZkNBflt03wvSHyJcVjEadetS1vlkGbfrWljfeaCr6XSMbZYz8ghisdN-7I6rNqyLbwOGeCfHU5voJ1AdRy3UdzZs6vN6H3DV2ZjyHAV7xPCIT1T/s1667/1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="977" data-original-width="1667" height="376" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5Kk9qnYBVtg1UGkG0mNEucbz4OAHo5ZkNBflt03wvSHyJcVjEadetS1vlkGbfrWljfeaCr6XSMbZYz8ghisdN-7I6rNqyLbwOGeCfHU5voJ1AdRy3UdzZs6vN6H3DV2ZjyHAV7xPCIT1T/w640-h376/1.png" width="640" /></a></span></span></div><p><span style="font-size: small;"><span style="font-family: arial;"><br /> Here is the sample result. <br /></span></span></p><p><span style="font-size: small;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjv8cLleF7okjnoW8KsGSgtiMK6vjN7ULVaK4fn9FnVKTVXYg8KIkCIC1NrcNDRRPrazi67kjy1jAOgNr4PoPq6DUAme6k-98m5NJpYbYgVRQ-pfXOMSj_g7Zl57EsxjH8QmoCbxYwmDg0L/s1503/2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="977" data-original-width="1503" height="416" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjv8cLleF7okjnoW8KsGSgtiMK6vjN7ULVaK4fn9FnVKTVXYg8KIkCIC1NrcNDRRPrazi67kjy1jAOgNr4PoPq6DUAme6k-98m5NJpYbYgVRQ-pfXOMSj_g7Zl57EsxjH8QmoCbxYwmDg0L/w640-h416/2.png" width="640" /></a></span></div><span style="font-size: small;"><br /><span style="font-family: arial;"></span></span><p></p><p><span style="font-size: small;"><span style="font-family: arial;">Ref: Microsoft Documentation</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><a href="https://docs.microsoft.com/en-us/power-platform/admin/verify-network-capacity-throughput-clients">https://docs.microsoft.com/en-us/power-platform/admin/verify-network-capacity-throughput-clients</a></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com2tag:blogger.com,1999:blog-7483666954520465023.post-35504183244379513932021-02-08T23:40:00.005+00:002021-02-08T23:44:46.957+00:00Set up Azure Function with Blob Trigger<div><p><span style="font-family: arial;"><span style="font-size: small;">If you are not familiar with Azure Blob, please refer this post </span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><a href="https://crmdm.blogspot.com/2021/02/automate-file-copy-to-azure-blob.html">https://crmdm.blogspot.com/2021/02/automate-file-copy-to-azure-blob.html</a></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">In this post, we will see how to set up an azure function with blob trigger. </span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">Assumption is that a blob is already set up as explained in the above post. </span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">So we already have storage account , storage container set up. When a blob is copied into the storage container, azure function gets triggered.</span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"> Let's create an Azure function with Blob trigger from the Visual studio. Here I have used Visual studio 2019. Choose azure function from the templates.<br /></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiubTeS0qLTaunEBiG9JBJ_3V1brNMTz4EH-rnqtFqS2-ShFuq258RHxmGlHDi4QI7jMhHIZwdttND4ot8ALRHqvQpPNUMRK0XqFsCSGPJvhDmurRMrBhBCT6xjBIXhPYr7dQ2xmpX_EJcI/s1889/1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="972" data-original-width="1889" height="330" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiubTeS0qLTaunEBiG9JBJ_3V1brNMTz4EH-rnqtFqS2-ShFuq258RHxmGlHDi4QI7jMhHIZwdttND4ot8ALRHqvQpPNUMRK0XqFsCSGPJvhDmurRMrBhBCT6xjBIXhPYr7dQ2xmpX_EJcI/w640-h330/1.png" width="640" /></a></span></div><p></p><p><span style="font-family: arial;"><span style="font-size: small;">Next step is to name the project.</span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"> <br /></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUHQQwl46F2cATjCrgwHqcCtI3cSV5ox1AQLOwxcDLwbnCvTRyGbcHCws6eyxrxjrNGZe5O6wDhSvBmw8BA8l7CJy2XPMMmKIdjcupuEhQpyaTjfZXGksSIbpkv_HjHb8CONH7w01Daf0o/s1855/2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="933" data-original-width="1855" height="322" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUHQQwl46F2cATjCrgwHqcCtI3cSV5ox1AQLOwxcDLwbnCvTRyGbcHCws6eyxrxjrNGZe5O6wDhSvBmw8BA8l7CJy2XPMMmKIdjcupuEhQpyaTjfZXGksSIbpkv_HjHb8CONH7w01Daf0o/w640-h322/2.png" width="640" /></a></span></span></div><p></p><p><span style="font-family: arial;"><span style="font-size: small;">It's time to choose the trigger! Please note the highlighted points. Blob trigger is what we need in this context. Path is the container name. For now, let's put mycontainer and later this can be updated with the value from the Azure. Also connection as MyBlobConnection. This can be mapped to the value from Azure later. So let's click on Create.<br /></span></span></p><p></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihYNyDnrNE4E5nrSSzHksGMzgM_TC_lWI9eKlALj0Q4Yba9DM7YgKarJi3WanAmwE3TVBzQ5W2cF6c4nEzP6LxpecMgxTMyJMyqqQffAnpTzthA4gu9EsYrplsixzbL7XDFngVrbR3x68o/s1283/3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="887" data-original-width="1283" height="442" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihYNyDnrNE4E5nrSSzHksGMzgM_TC_lWI9eKlALj0Q4Yba9DM7YgKarJi3WanAmwE3TVBzQ5W2cF6c4nEzP6LxpecMgxTMyJMyqqQffAnpTzthA4gu9EsYrplsixzbL7XDFngVrbR3x68o/w640-h442/3.png" width="640" /></a></span></span></div><span style="font-family: arial;"><span style="font-size: small;"><br />Rename function name to the preferred name.</span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"> <br /></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj91UmXk1bbCWOjEHq_w-Gn4Rg3fYJG9nyPuwGqEvALiWAtI0aGbMgwy1xgrjb1NJba9bVXPPcY4WmrrPlX21sbPFU90odQSycNqjr8q85wRBTxF36R0pXwQORX8OVPIgrMNQ-TLR9MbGLm/s1876/6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="630" data-original-width="1876" height="214" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj91UmXk1bbCWOjEHq_w-Gn4Rg3fYJG9nyPuwGqEvALiWAtI0aGbMgwy1xgrjb1NJba9bVXPPcY4WmrrPlX21sbPFU90odQSycNqjr8q85wRBTxF36R0pXwQORX8OVPIgrMNQ-TLR9MbGLm/w640-h214/6.png" width="640" /> </a></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"> </span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"> Let's define an entry for the connection string. This can be created in local.settings.json as shown. The same values can be configured in the deployed version.<br /></span></span></div><p></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1y3CctdR7vDMgwhRKKdBLshmzQwyTrdaBC-9cwMoRiAo41TIOBc4MEMiPOffnkrHwzZ-QZF76J9CSLL-P2-MGapDUJJsdQA3yjr-EEtVWMvhicyUwBXOoDUmtNmJGSkOapvXEXRmbc_dd/s1892/7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="290" data-original-width="1892" height="98" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1y3CctdR7vDMgwhRKKdBLshmzQwyTrdaBC-9cwMoRiAo41TIOBc4MEMiPOffnkrHwzZ-QZF76J9CSLL-P2-MGapDUJJsdQA3yjr-EEtVWMvhicyUwBXOoDUmtNmJGSkOapvXEXRmbc_dd/w640-h98/7.png" width="640" /></a></span></span></div><span style="font-family: arial;"></span></div><div><span style="font-family: arial;"></span></div><div><span style="font-family: arial;"><span style="font-size: small;"><br /></span></span><p><span style="font-family: arial;"><span style="font-size: small;">So below are the two items needed from the Azure side.</span></span></p><ul style="text-align: left;"><li><span style="font-family: arial;"><span style="font-size: small;">Connection to Azure Blob</span></span></li><li><span style="font-family: arial;"><span style="font-size: small;">Container Name </span></span></li></ul></div><p><span style="font-family: arial;"><span style="font-size: small;">So let's see how to get these values from Azure. Navigate to the configured Storage Account and choose Access Keys. Click on the Show Keys button. It reveals the Blob connection ( Storage Account ) string. Copy this value.<br /></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"> <br /></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZRAS2lblGJlTy-fn7LOXqCPzLN0JbYnSZs4gq1nWJ05bG0w65oEXgwHWg5tIj-VGZknyA9siOkT7Dg17l5dF3U_h43iszErGNn9hzfWsfrmfPUjWrjxSg_HpxgyAU7UaeQaPEIaDvijYh/s1895/8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="844" data-original-width="1895" height="286" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZRAS2lblGJlTy-fn7LOXqCPzLN0JbYnSZs4gq1nWJ05bG0w65oEXgwHWg5tIj-VGZknyA9siOkT7Dg17l5dF3U_h43iszErGNn9hzfWsfrmfPUjWrjxSg_HpxgyAU7UaeQaPEIaDvijYh/w640-h286/8.png" width="640" /></a></span></div><span style="font-size: small;"><br /></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;">Next bit is the container name</span></span></p><p></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdmo1bkJPf5uc9K6hzh9R0o4ohvirK2oLOBCgumh_Va3MwcTmjjtrqmefB-NoXhSVS4lmXDaBDONKSfbvWutadf6k_65Dos3rO4HGRvW5RKqI2gimpO1J4kcm7yminDimUCV-Wiwwy3y0e/s1892/9.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="418" data-original-width="1892" height="142" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdmo1bkJPf5uc9K6hzh9R0o4ohvirK2oLOBCgumh_Va3MwcTmjjtrqmefB-NoXhSVS4lmXDaBDONKSfbvWutadf6k_65Dos3rO4HGRvW5RKqI2gimpO1J4kcm7yminDimUCV-Wiwwy3y0e/w640-h142/9.png" width="640" /> </a></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"> </span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;">Local.settings.json is updated with the connection string from Storage Account.<br /></span></span></div><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><br /></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZ4k1Z7I43Rb9Qc8jrSWAzdo7LcppUqUkWWvcTWU832RkPF4JFzasZXmv01J13qOsLgl-lnJmLl7Q7F0ShTQ45ic34Q94CDUvXa8l52L9MzXi5kc2pa2PbmHObYD7raG1cFnZg4aR2fK9Q/s1490/11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="269" data-original-width="1490" height="116" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZ4k1Z7I43Rb9Qc8jrSWAzdo7LcppUqUkWWvcTWU832RkPF4JFzasZXmv01J13qOsLgl-lnJmLl7Q7F0ShTQ45ic34Q94CDUvXa8l52L9MzXi5kc2pa2PbmHObYD7raG1cFnZg4aR2fK9Q/w640-h116/11.png" width="640" /></a></span></span></div><span style="font-family: arial;"><span style="font-size: small;"><br />Azure Function is updated with the container name as well.<br /></span></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbFx5uvZhxYbvR5bBFrvT-_4yV8BmP9bpKHKvqWxf0u5GwoqqV8l2LDLVGE0rTWYNN7jLAr1bk0Q7X0n1SqEC6hbll7bM4EixfWblAFnPDtFu3nGOqWsNRRA0iIcXwmPVdOBDwCZ5b5OtO/s1231/12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="634" data-original-width="1231" height="330" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbFx5uvZhxYbvR5bBFrvT-_4yV8BmP9bpKHKvqWxf0u5GwoqqV8l2LDLVGE0rTWYNN7jLAr1bk0Q7X0n1SqEC6hbll7bM4EixfWblAFnPDtFu3nGOqWsNRRA0iIcXwmPVdOBDwCZ5b5OtO/w640-h330/12.png" width="640" /></a></span></div><span style="font-size: small;"><br />We are good to go. Function gets triggered as soon as a blob is added to the storage container.</span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuVll2gzQ0I77eH5xSJjUjldc8QnajjvHVaYaaHzPaqGwXFSYc951xQcLZudC5571C62bPP1ipVPl1JttdxDAaiTyJn5PmZd8o3uJg4YkmYfxbUBIHWPxQdnbgMtLve5YKpnaE5Iq8Y_YQ/s1081/10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="402" data-original-width="1081" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuVll2gzQ0I77eH5xSJjUjldc8QnajjvHVaYaaHzPaqGwXFSYc951xQcLZudC5571C62bPP1ipVPl1JttdxDAaiTyJn5PmZd8o3uJg4YkmYfxbUBIHWPxQdnbgMtLve5YKpnaE5Iq8Y_YQ/w640-h238/10.png" width="640" /></a></span></div><span style="font-size: small;"><br />Inside Azure function you could write additional logic like calling an API, Writing to a SQL Database etc. depending on your requirements.<br /></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"><br /></span></span></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-41202566905595726262021-02-07T19:52:00.008+00:002021-02-08T00:34:30.596+00:00Automate a File Copy to Azure Blob<p><span style="font-size: small;"><span style="font-family: arial;"><span><span>Azure Blob is an object storage solution from Microsoft. It's mainly used for storing unstructured data like files, pictures etc. Blob security is important. So if you have a security team, it is highly recommended to discuss with them before you implement blob based solutions. Views are my own.</span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span>Azure blob is pretty cheap storage too - <a href="https://azure.microsoft.com/en-gb/pricing/details/storage/">https://azure.microsoft.com/en-gb/pricing/details/storage/</a></span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span>Here is a diagram from Microsoft to understand the folder structure. Storage can have multiple storage container and can have multiple blobs in each. </span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5QwRHXV5lIvGnbgre2vCYmqtJfM7kXUc9HjVj2PsRNDthCfMqTQrJNTrlCfvye08T_QFXRXAk7sxuH_qFOaub8wkNQKe9mjY_ZxIrh-MrbQ-O5hp26eFULGDGj18U9wItNo0mjS77Kj2A/s416/19.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="140" data-original-width="416" height="135" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5QwRHXV5lIvGnbgre2vCYmqtJfM7kXUc9HjVj2PsRNDthCfMqTQrJNTrlCfvye08T_QFXRXAk7sxuH_qFOaub8wkNQKe9mjY_ZxIrh-MrbQ-O5hp26eFULGDGj18U9wItNo0mjS77Kj2A/w400-h135/19.png" width="400" /></a></span></span></span></span></div><p><span style="font-size: small;"><span style="font-family: arial;"><span><span>(ref:https://docs.microsoft.com/en-gb/azure/storage/blobs/storage-blobs-introduction)</span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span>As per the diagram img001,img002 and mov1 are blobs. In this sample scenario, it would be just a csv file.<br /></span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span>In a very simple scenario it is just one storage account and storage container and a blob ( csv file) in it. I have a diagram for this scenario.<br /></span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span> </span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMqR65ZiZNsw43SxPUGmOLPHAo3lABXDnFxHRu0AJ1X3iqpOznjkUZ1HZ3swfIaqwU7HH33CwX3xCPugtq0hI-FezXzAvsEulbyvmnGSmP89eLIGWvFQFXZX7a9d21roflg56Aa_csk8Hq/s589/18.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="134" data-original-width="589" height="146" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMqR65ZiZNsw43SxPUGmOLPHAo3lABXDnFxHRu0AJ1X3iqpOznjkUZ1HZ3swfIaqwU7HH33CwX3xCPugtq0hI-FezXzAvsEulbyvmnGSmP89eLIGWvFQFXZX7a9d21roflg56Aa_csk8Hq/w640-h146/18.png" width="640" /></a></span></span></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><span><span><br /></span></span></span></span><p><span style="font-size: small;"><span style="font-family: arial;"><span><span> Scenario: A file is located in a server. We need to copy it securely to Azure blob using a batch file. And then automate it.<br /></span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span> Let's begin!</span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span>Create a storage account from the azure portal.Navigate to<a href=" https://portal.azure.com/" target="_blank"> https://portal.azure.com/</a> and search for Storage accounts. Click New. Account kind is your choice. Here I chose BlobStorage as I just need to store a file in the storage. File becomes the blob in this scenario.<br /></span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span> </span></span><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSzFjvUteg6xyBNCV8DHtincNNp0apm1-j3YgpQ9yZ88oZvOGQ7a1ucxudC1-o6WjY9MgmQt-U9GczI5nP6IzvAH5_fBRQBPiLVCalUITqMH_GtUS91wqZLIKHNtMY3_MPTSurL2R5uv84/s1008/1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="867" data-original-width="1008" height="550" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSzFjvUteg6xyBNCV8DHtincNNp0apm1-j3YgpQ9yZ88oZvOGQ7a1ucxudC1-o6WjY9MgmQt-U9GczI5nP6IzvAH5_fBRQBPiLVCalUITqMH_GtUS91wqZLIKHNtMY3_MPTSurL2R5uv84/w640-h550/1.png" width="640" /></a></span></span></span></span></p><span style="font-size: small;"><span style="font-family: arial;"><span><span><br /></span></span></span></span><p><span style="font-size: small;"><span style="font-family: arial;"><span><span> This displays a screen saying it is ready to create after the validation is passed. If the details are fine, click on the create button.<br /></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAreta8pd2SaWjFeBKvJAZ1dF4QDxxj_O45v8EGUgqUIV82ufCEG67c4sR-bHJVIktpX7eU08PnfZO42S6oGUMsPyDTwhHLRY0HspoWOt3_NidkmKXJtejVTVh_mhFCCBasa0Qz5X8rV2I/s905/2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="879" data-original-width="905" height="622" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAreta8pd2SaWjFeBKvJAZ1dF4QDxxj_O45v8EGUgqUIV82ufCEG67c4sR-bHJVIktpX7eU08PnfZO42S6oGUMsPyDTwhHLRY0HspoWOt3_NidkmKXJtejVTVh_mhFCCBasa0Qz5X8rV2I/w640-h622/2.png" width="640" /></a></span></span></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><span><span>Deployment in progress screen, just be patient / get a coffee : )<br /> </span></span></span></span><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9Jzj9RB41tRo16x6tp-r54VebI_rDR1tf0Gg8w3YUTorzMYIaO_6iFZn6ahsbX1oupxRgAw7B2P8HcDeZWb2HEU66mlAVit6MPSAkvlG6U22rmTCOWw95StJWLJS525Csg7Khqxc1C9qH/s1381/3.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="571" data-original-width="1381" height="264" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9Jzj9RB41tRo16x6tp-r54VebI_rDR1tf0Gg8w3YUTorzMYIaO_6iFZn6ahsbX1oupxRgAw7B2P8HcDeZWb2HEU66mlAVit6MPSAkvlG6U22rmTCOWw95StJWLJS525Csg7Khqxc1C9qH/w640-h264/3.png" width="640" /></a></span></span></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><span><span><br />Good news ! Deployment is complete.<br /></span></span></span></span><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW766DXj-8P-hSMoNX8YkhsLf47fNCQdOtor7a56STqUxxgRC4QQAbODnTQrMQxLTpcX3sECBQoX3D5SYdTyBIVNPe7tGta3gj3zUdY2x7QSQbkAab_rM0ds-B_-kyBaEaST1XfxGvqrmK/s1347/4.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="571" data-original-width="1347" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW766DXj-8P-hSMoNX8YkhsLf47fNCQdOtor7a56STqUxxgRC4QQAbODnTQrMQxLTpcX3sECBQoX3D5SYdTyBIVNPe7tGta3gj3zUdY2x7QSQbkAab_rM0ds-B_-kyBaEaST1XfxGvqrmK/w640-h272/4.png" width="640" /></a></span></span></span></span></div><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span>Next step, view the storage account.<br /></span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKOG0OaazTzapIeisDIOXmmpugy75ujY2qREIxl72trpsaFhO_tDkcMInBHkwTDXIaPQEgjoOJCjt_ubgpxT4V5JuQ-6BDp9YL5GkgCNapyqAb2ez58XoMaryyCki5g0NGKPdsBcX18gOt/s1458/5.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="887" data-original-width="1458" height="390" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKOG0OaazTzapIeisDIOXmmpugy75ujY2qREIxl72trpsaFhO_tDkcMInBHkwTDXIaPQEgjoOJCjt_ubgpxT4V5JuQ-6BDp9YL5GkgCNapyqAb2ez58XoMaryyCki5g0NGKPdsBcX18gOt/w640-h390/5.png" width="640" /></a></span></span></span></span></div><p><span style="font-size: small;"><span style="font-family: arial;"><span><span><br /> Security setting on the storage account level is very important. It is ( kind of hidden ) under the configuration blade. Important thing is that by <b>default is</b> <b>enabled</b> ( Honestly I didn't like the fact that default is enabled). So <b>it is important to disable</b> it if you don't want give public access to your storage account. And save that setting!<br /></span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs57v6yFtN-L4cxC8yif1y1PctlSoQ-FU2fffXiU1186TQ5dxvwalEexOvQY_JWDb18Gv-GTW4cVN-YJDCzhtAnWZOgbdkKgyvuPKS4Wct23Mj5BM2oHeVlMHuRtlZ70fJgUywSjbqfpEY/s1899/6.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="875" data-original-width="1899" height="294" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs57v6yFtN-L4cxC8yif1y1PctlSoQ-FU2fffXiU1186TQ5dxvwalEexOvQY_JWDb18Gv-GTW4cVN-YJDCzhtAnWZOgbdkKgyvuPKS4Wct23Mj5BM2oHeVlMHuRtlZ70fJgUywSjbqfpEY/w640-h294/6.png" width="640" /></a></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><br /><span>Next step is to create a container. Select the container section.<br /></span></span></span><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNjkFKxWIqlXeert4weNUtphPoSGL5LjK4aJIeYyTamVbsRkrx7ITfYOHoOQOLmFUpHAZbU58tu5B3ggjNBtd7TE5wB3APdSkDdgw3xVUrEA04Z9HT50c2-RCbAgXvqnVT6jMvqMBlZ7EK/s694/7.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="694" data-original-width="315" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNjkFKxWIqlXeert4weNUtphPoSGL5LjK4aJIeYyTamVbsRkrx7ITfYOHoOQOLmFUpHAZbU58tu5B3ggjNBtd7TE5wB3APdSkDdgw3xVUrEA04Z9HT50c2-RCbAgXvqnVT6jMvqMBlZ7EK/w290-h640/7.png" width="290" /></a></span></span></div><p><span style="font-size: small;"><span style="font-family: arial;"><span>Click on the + button to create the container.</span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtzRezb5h9JRy4198DmVzw7JSbd_pUWcZ42Jq5Plcl8BzAYXpLr-BVWWf7xmJ2xwvqIHleFCUEEzOIWj1mE-8zEeaQ3pNbOOn9njPnXnoih1E7zA82tOeZVkNs7AVdgeXlM5UasDwruDo8/s1689/8.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="839" data-original-width="1689" height="318" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtzRezb5h9JRy4198DmVzw7JSbd_pUWcZ42Jq5Plcl8BzAYXpLr-BVWWf7xmJ2xwvqIHleFCUEEzOIWj1mE-8zEeaQ3pNbOOn9njPnXnoih1E7zA82tOeZVkNs7AVdgeXlM5UasDwruDo8/w640-h318/8.png" width="640" /> </a></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"> Choose a name for the container and as you could see, because we disabled public access, it is reflected to the container level too. It is good !<br /></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvXjvHcoz7Pu087SfMUoWPdTWJWmKewUEK62K02GcAbk_-ADLxUj9Ctz7694J2ts_NuF2RLEoAqcIPpWBjFIKRYcTtlm6FkcdpFi5FioS5HumPbzX5fOoZ4ef0OQcdAYvJUg-JcARbrt7p/s839/9.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="839" data-original-width="539" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvXjvHcoz7Pu087SfMUoWPdTWJWmKewUEK62K02GcAbk_-ADLxUj9Ctz7694J2ts_NuF2RLEoAqcIPpWBjFIKRYcTtlm6FkcdpFi5FioS5HumPbzX5fOoZ4ef0OQcdAYvJUg-JcARbrt7p/w412-h640/9.png" width="412" /></a></span></span></div><span style="font-size: small;"><span style="font-family: arial;">In the container you could manually upload a file and it is treated as a blob.<br /></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span> <span style="font-size: small;"><span style="font-family: arial;"><br /></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFz7TDCT1PwiK_TngGaiZzrHSpXhR9gy7AhAawRQpEPzAQweGUQ6KDMHO_tV4dNppEVDVl0fUi3FHWkSpz71LOkyxYrqBMf96Gr9qq_FmYSC0q2GMJd0ue8R-UE_VRxVCA_cJftS7Oa2FH/s1911/11.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="384" data-original-width="1911" height="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFz7TDCT1PwiK_TngGaiZzrHSpXhR9gy7AhAawRQpEPzAQweGUQ6KDMHO_tV4dNppEVDVl0fUi3FHWkSpz71LOkyxYrqBMf96Gr9qq_FmYSC0q2GMJd0ue8R-UE_VRxVCA_cJftS7Oa2FH/w640-h128/11.png" width="640" /></a></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><br />Now let's see how to upload it using batch file. As we made the storage account secure, we need a Shared Access Key in order to copy a file / blob to the container.<br /></span></span><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlBvOkH_1cieKknnanVcVu7LEVg41Pq-QDgkYCAlVtA4g1KERsJwBSkBQYCB1KarKdwgSpNCG9xdB8sLOXqq6bFlXi2BY4J929PZu0qnSwTw_MnSTQKkN3Qdt3cemAAQ14XEEND8b0gqCQ/s1880/12.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="807" data-original-width="1880" height="275" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlBvOkH_1cieKknnanVcVu7LEVg41Pq-QDgkYCAlVtA4g1KERsJwBSkBQYCB1KarKdwgSpNCG9xdB8sLOXqq6bFlXi2BY4J929PZu0qnSwTw_MnSTQKkN3Qdt3cemAAQ14XEEND8b0gqCQ/w640-h275/12.png" width="640" /></a></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><br />Important bits are </span></span><ul style="text-align: left;"><li><span style="font-size: small;"><span style="font-family: arial;"><span> Select only the services you need. In order to copy a file the ones on the screen shot are enough</span></span></span></li><li><span style="font-size: small;"><span style="font-family: arial;"><span>Expiry date of the SAS key can be chosen. Shorter the better but remember to update it accordingly. Otherwise entire service would be blocked. So it is important to manage it correctly. SAS key would be valid until this date.</span></span></span></li><li><span style="font-size: small;"><span style="font-family: arial;"><span>Make sure HTTPS is selected. Ip of the server - Upto you. It would make it more secure. <br /></span></span></span></li></ul><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span>SAS token is the main bit. Copy it somewhere safe. <br /></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdYN07ZAWSE57fBVDhgmebkxGO3dRA2LgAbdEBXGUVhgMoP2c-M-MaScNaR-1eMHgnUa2BFVdSvMsXNxQvwiKpKei51IjBMSt5gqBMM0pP7BtGjWQp1_Q3dHqqCtoueoKztM3K8ZPhs4bi/s1903/13.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="807" data-original-width="1903" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdYN07ZAWSE57fBVDhgmebkxGO3dRA2LgAbdEBXGUVhgMoP2c-M-MaScNaR-1eMHgnUa2BFVdSvMsXNxQvwiKpKei51IjBMSt5gqBMM0pP7BtGjWQp1_Q3dHqqCtoueoKztM3K8ZPhs4bi/w640-h272/13.png" width="640" /></a></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"> </span></span></div><span style="font-size: small;"><span style="font-family: arial;"><span>Next is AzCopy - AzCopy is command-line utility from Microsoft.It can be downloaded from the below link. And extract to the preferred folder.<br /></span></span></span><p><span style="font-size: small;"><span style="font-family: arial;"><a href="https://docs.microsoft.com/en-us/azure/storage/common/storage-use-azcopy-v10"><span>https://docs.microsoft.com/en-us/azure/storage/common/storage-use-azcopy-v10</span></a></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span>Open command prompt. And navigate to the downloaded folder.</span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span>Here is a dummy command. demo.csv is a sample file ( contents do not matter in this context). The part from ? ( ie sv= onwards) is the SAS token from the storage account. <br /></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span>azcopy copy "C:\yourfolder\demo.csv" "https://yourstorageaccountname.blob.core.windows.net/yourcontainername/demo.csv?sv=2000-1-1&ss=b&srt=co&sp=w&se=1989-01-07T21:43:04Z&st=2000-01-07T13:43:04Z&spr=https&sig=gr1GZIkNueRiRaavLWiyzhsdilGyLikM4NN5HZYJZ68%3D"<br /></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span>Once executed, it shows a completed status if it is successful<br /></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEGOOOS73Orb4A7LdaveKpH5pqAIeuuqCkx_whhuLQ4VzKkm7s9aQJh4U45b3uX0vJLGOTm4VSxAXGhZv6mSja2jbwliyiRUdl6bKtoIkzk67l2aENX47yaU0_h5FGea7f3w9OpMknJtiz/s1733/17.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="484" data-original-width="1733" height="178" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEGOOOS73Orb4A7LdaveKpH5pqAIeuuqCkx_whhuLQ4VzKkm7s9aQJh4U45b3uX0vJLGOTm4VSxAXGhZv6mSja2jbwliyiRUdl6bKtoIkzk67l2aENX47yaU0_h5FGea7f3w9OpMknJtiz/w640-h178/17.png" width="640" /></a></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><br /><span><div class="separator" style="clear: both; text-align: center;"> </div></span></span></span><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span>And you could see a file in the storage container.<br /><span><br /></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilnlKlBNnm3jwhQxxZzy86LDoT3aWSnGrRVRZMeq6-TIgy_jiG1JXSbNhb-zY9Z6BsXiaaB4Pzs7mdZSiToXoCM7AxsWTjm0ybALbsjsvBCw8292eFMcEGjl1J1aDBcgOFS1Y4rs41iFWH/s1895/14.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="363" data-original-width="1895" height="122" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilnlKlBNnm3jwhQxxZzy86LDoT3aWSnGrRVRZMeq6-TIgy_jiG1JXSbNhb-zY9Z6BsXiaaB4Pzs7mdZSiToXoCM7AxsWTjm0ybALbsjsvBCw8292eFMcEGjl1J1aDBcgOFS1Y4rs41iFWH/w640-h122/14.png" width="640" /> </a></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><span><span> </span></span></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><span><span>Blob URL can be found from the blob. </span></span> <br /></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM_dvbSyXEksbDNsrEebVlYPyghzq0Y8mSu_6vJR0wwmtVxZUEAYyMFkROsV3YjFTVbvT1yrNZ6BGnp45TdgO2ZeWE8q5VEoAMvJvRN9xd5hIaR97Uy5BoV44KkPCF9-7YhKtO4APQNND5/s1896/15.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="808" data-original-width="1896" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM_dvbSyXEksbDNsrEebVlYPyghzq0Y8mSu_6vJR0wwmtVxZUEAYyMFkROsV3YjFTVbvT1yrNZ6BGnp45TdgO2ZeWE8q5VEoAMvJvRN9xd5hIaR97Uy5BoV44KkPCF9-7YhKtO4APQNND5/w640-h272/15.png" width="640" /></a></span></span></div><p><span style="font-size: small;"><span style="font-family: arial;"><span><span>It is worth testing this url from the browser. Because it is vital to make sure that this url can not be accessed publicly.</span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizAR4NLjSi4-G2Xnbh6iu7gPhCOmgYz0hyphenhyphenEJzDYTkgp3d3KYr4k4X-c-09YkBkKSCPbThti41DOP6FGMPwmIOwiqGn3vseT2dKHSHMwmRC7hVIgid3FYtv0L_EeV2xeM1nle6HoTLkYB_x/s1319/16.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="289" data-original-width="1319" height="140" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizAR4NLjSi4-G2Xnbh6iu7gPhCOmgYz0hyphenhyphenEJzDYTkgp3d3KYr4k4X-c-09YkBkKSCPbThti41DOP6FGMPwmIOwiqGn3vseT2dKHSHMwmRC7hVIgid3FYtv0L_EeV2xeM1nle6HoTLkYB_x/w640-h140/16.png" width="640" /></a></span></span></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><span><span><br /> Batch file is very similar to command line option . Key difference is that if we have % value in the SAS key token, then we need to replace % with %% otherwise it doesn't work as per the batch file format. </span></span></span></span><p><span style="font-size: small;"><span style="font-family: arial;"><span><span> </span></span><span><span>azcopy_windows_amd64_10.8.0 folder is the extracted content from Microsoft. Below is the contents of the batch file.<br /></span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span>echo off<br />Cd C:\yourfolder\azcopy_windows_amd64_10.8.0\azcopy_windows_amd64_10.8.0<br />azcopy copy "C:\yourfolder\demo.csv" </span></span><br /><span><span><span>"https://yourstorageaccountname.blob.core.windows.net/yourcontainername/demo.csv?sv=2000-1-1&ss=b&srt=co&sp=w&se=1989-01-07T21:43:04Z&st=2000-01-07T13:43:04Z&spr=https&sig=gr1GZIkNueRiRaavLWiyzhsdilGyLikM4NN5HZYJZ68%%3D"</span></span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span><span>Save this contact as a file.bat For instance, CopyToAzureBlob.bat <br /></span></span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span><span> Batch file is useful because it can be easily used for automation. </span></span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span><span>For instance, in a server, you could set it up in a task scheduler task. It can be executed based on a schedule. For instance, this batch file can be run everyday at 5.00 am. </span></span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span><span>If you have a better way to schedule in your server, feel to try that way. This is just a way to do it.<br /></span></span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span><span> Open the Task Scheduler and create a task.<br /></span></span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY5_Gs_i0cayog6gA5V1YtBTfpKegg6lzU9imw8ClIyao1F-saGgt75O852KlO-ngJ_VG8Mgpa8j6rvqBUm6807kxeJ1lGzkz3JzUsW0jgV15wVt76_uxQrLDNjr_3AmfZdcMFW93I3XQ8/s430/20.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="430" data-original-width="372" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY5_Gs_i0cayog6gA5V1YtBTfpKegg6lzU9imw8ClIyao1F-saGgt75O852KlO-ngJ_VG8Mgpa8j6rvqBUm6807kxeJ1lGzkz3JzUsW0jgV15wVt76_uxQrLDNjr_3AmfZdcMFW93I3XQ8/w554-h640/20.png" width="554" /> </a></span></span></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><span><span> </span></span></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><span><span>Choose a schedule according to your requirement. Here I have chosen to run daily at 5.00 am. Feel free to choose any additional settings if you prefer.<br /></span></span></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><span><span><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR2d3YfkKwqsqNuhg2Apd9eohAO5IFFy2nzgW21NUmOXwoZQEsbC6F9ybdJVKf7953qfg74k4ZEeSyZleiqhMu8XCtOriruK9Eph6YcefkPsZ84mQZgNtCgQCq64f7_g76biRd4cnVKhjK/s826/21.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="761" data-original-width="826" height="590" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR2d3YfkKwqsqNuhg2Apd9eohAO5IFFy2nzgW21NUmOXwoZQEsbC6F9ybdJVKf7953qfg74k4ZEeSyZleiqhMu8XCtOriruK9Eph6YcefkPsZ84mQZgNtCgQCq64f7_g76biRd4cnVKhjK/w640-h590/21.png" width="640" /></a></div></span></span></span></span><p><span style="font-size: small;"><span style="font-family: arial;"><span><span>Choose the Actions and select the batch file created earlier.</span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbkT_2wLP5JQiN6tMWwxASCNaZm0kibKVfPepnW-lP9S-Lmjqtd2daOHOsPL_aN0trSdlDQ_QeoJMOtZAel9m5tBCG3R37R53XuCIbnvszUH6OFhooLEj6VtSsVtCJvIZVqoS4wyMhWNs4/s793/22.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="733" data-original-width="793" height="592" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbkT_2wLP5JQiN6tMWwxASCNaZm0kibKVfPepnW-lP9S-Lmjqtd2daOHOsPL_aN0trSdlDQ_QeoJMOtZAel9m5tBCG3R37R53XuCIbnvszUH6OFhooLEj6VtSsVtCJvIZVqoS4wyMhWNs4/w640-h592/22.png" width="640" /></a></span></span></span></span></div><p><span style="font-size: small;"><span style="font-family: arial;"><span><span>All set! This task would run every day at 5.00 am. And it would copy the file (becomes blob in azure) selected to Azure storage container. <br /></span></span></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><span><span><br /></span></span></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><span><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIyBRbZyjg4gF-jhgD-8246tpcM1AaOn5xZIbwqe5BNyKnOxzrVnYHGNbJ7XKL-51HqlGW_eG2bHFDNiLEE9S6zWVNf9JaJwDE4QiSujv7_q19-0zlUTN3iOosmfR1SPLiNz-0iPeAc4pD/s1098/23.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="60" data-original-width="1098" height="34" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIyBRbZyjg4gF-jhgD-8246tpcM1AaOn5xZIbwqe5BNyKnOxzrVnYHGNbJ7XKL-51HqlGW_eG2bHFDNiLEE9S6zWVNf9JaJwDE4QiSujv7_q19-0zlUTN3iOosmfR1SPLiNz-0iPeAc4pD/w640-h34/23.png" width="640" /></a></span></span></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><span><span><br /><span><br /></span></span></span></span></span><p><span style="font-size: small;"><span style="font-family: arial;"><span><span><span> </span> <br /></span></span></span></span></p><p></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com7tag:blogger.com,1999:blog-7483666954520465023.post-90540250939846528132021-01-17T22:56:00.000+00:002021-01-17T22:56:50.824+00:00Power Automate and Azure Service Bus Queue Use Case<p><span style="font-size: small;"><span style="font-family: arial;">As you all know Power Automate is really cool! It has got a lot of connectivities. This post aims to focus on Power Automate and also a scenario in which it can be utilized. <br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Consider a scenario. Payments are managed by another system and no payment / bank details are stored in Dynamics 365 CRM. But still need the capabiltiy to update it occasionally from Dynamics 365 CRM. Power Apps can be very handy in this context. An embedded Power App ( Canvas App) in Model Driven App is used here to capture the details. It triggers a Power Automate ( Flow) from a button. And then Power Automate publishes an Azure Service Bus message to the queue ( Azure Topics are also supported here in complex scenarios). An Azure function listens to Azure Service Bus queue and it gets triggered when a message arrives in the queue. Please note that it could be a console app as well. I chose Azure function for demo purpose. Azure function calls APIs of payment system and the details get updated there.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Obviously there are other ways to do it. This is just one option. Service bus is known for it'd resilience and also it has other features like retry message mechanism etc.These are just some guidelines, feel free to update as per your requirement / scenario.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Here is a small diagram to understand this sample scenario.</span></span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAuiotTeT6OjV1R39UWTvZkLOzl6RiAfPaNgT6fYYGyoHf0MtFmuo5OKrJmrixPTAt5Yi_stfPnvOJyD44Z1s8YcGmFrK6RT0QRi9OQ7nxDXKX87Cel6I-oORhVcI1w_Kv7bERIKDaUpZn/s1425/20.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="988" data-original-width="1425" height="444" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAuiotTeT6OjV1R39UWTvZkLOzl6RiAfPaNgT6fYYGyoHf0MtFmuo5OKrJmrixPTAt5Yi_stfPnvOJyD44Z1s8YcGmFrK6RT0QRi9OQ7nxDXKX87Cel6I-oORhVcI1w_Kv7bERIKDaUpZn/w640-h444/20.png" width="640" /></a></div><p><span style="font-size: small;"><span style="font-family: arial;">There are plenty of posts about Embedded Power Apps which triggers a Power Automate. So I am skipping screen shots for those. Assumption is that there is a bank wizard Canvas App and user access it when bank details need to be updated. On submission a Power Automate gets triggered from the button.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> First things first! Let's create a Service Bus and a queue. </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Navigate to htts://portal.azure.com/ and choose create new Service Bus option. Here , I chose a basic pricing tier.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOkw5NoRWfY_EC2GxiGK8-qFSNsM1Pgwh2sZcWp4d3z79J_mF7GKBglKOfnlZP-R2TadpRnPv87BBh51aJ7OQoUkkVTSdb6lIksDn3n8HSU2phwEYdU2HTNWHoveZdP-Nir1iKEn_eNilP/s1511/1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="846" data-original-width="1511" height="358" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOkw5NoRWfY_EC2GxiGK8-qFSNsM1Pgwh2sZcWp4d3z79J_mF7GKBglKOfnlZP-R2TadpRnPv87BBh51aJ7OQoUkkVTSdb6lIksDn3n8HSU2phwEYdU2HTNWHoveZdP-Nir1iKEn_eNilP/w640-h358/1.png" width="640" /></a></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span><p></p><p><span style="font-size: small;"><span style="font-family: arial;"> Important part of the Service bus is of course it's connection. This is required to establish a connection. It is found in the Shared Access Policy section.<br /></span></span></p><p><span style="font-size: small;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdr3GeHoGhM-iyAAPeZrwcqNggJgg2aLqx7KdApJUzX8j-on_cqg7wEJ2ecvXWM9EQf7uYdVHBKupJVSIQ2NU27up4wHk1itNIYnv1sFlYxbaadYfUtwKF2gqveNh7nLGMkK0Sj_FA6ZS7/s1522/2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="583" data-original-width="1522" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdr3GeHoGhM-iyAAPeZrwcqNggJgg2aLqx7KdApJUzX8j-on_cqg7wEJ2ecvXWM9EQf7uYdVHBKupJVSIQ2NU27up4wHk1itNIYnv1sFlYxbaadYfUtwKF2gqveNh7nLGMkK0Sj_FA6ZS7/w640-h246/2.png" width="640" /></a></span></div><span style="font-size: small;"><br /><span style="font-family: arial;">Primary connection string is what we need.</span><br /><span style="font-family: arial;"><br /></span></span><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_UJX2MeufAckKf8pZ_61ftQrIw0qxdNawPu0vIGz3S7V9VKQr-zA99zdkbcKepcUdeCiCEj_pcnKuRymfk4fZmMCew2QGX8MxsSMp90x3LvLIdPIEzjhGtXjBrYFVfOAtCwcX_VwkuV5u/s1523/3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="588" data-original-width="1523" height="248" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_UJX2MeufAckKf8pZ_61ftQrIw0qxdNawPu0vIGz3S7V9VKQr-zA99zdkbcKepcUdeCiCEj_pcnKuRymfk4fZmMCew2QGX8MxsSMp90x3LvLIdPIEzjhGtXjBrYFVfOAtCwcX_VwkuV5u/w640-h248/3.png" width="640" /> </a></div><div class="separator" style="clear: both; text-align: center;"> <span style="font-size: small;"><span style="font-family: arial;"> </span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;">Next part is the queue. Select the Queues section.</span></span><br /></div><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUCEEAQiFLTZuQhnLhJ3yOR8F77AaW9hPpDwZ8f8W2Jc4FRsHsd-3WauaJM9-FyCKKEo_0-ngvZlc0HpM0J4d3o-z8AaFVGkr9sMKhUrfYvoh9CtO5rEL_MUOwlKMhWe0npokaK3j_Y_Cc/s752/4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="752" data-original-width="336" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUCEEAQiFLTZuQhnLhJ3yOR8F77AaW9hPpDwZ8f8W2Jc4FRsHsd-3WauaJM9-FyCKKEo_0-ngvZlc0HpM0J4d3o-z8AaFVGkr9sMKhUrfYvoh9CtO5rEL_MUOwlKMhWe0npokaK3j_Y_Cc/w286-h640/4.png" width="286" /> </a></div><div class="separator" style="clear: both; text-align: center;"> </div><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;">Let's call the queue as bankwizardq. Properies of the queue is left as it is. But this can be changed accordingly.</span></span> <br /></div><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYI_GbfY7xk7gC9zJYem_brc40qcT1vz_hgUYYrAlyEvuC_-tf3u-rWo4T0zSHlUt6YXhbctTRCVEGzbjal2TwJhhcE8mlg64SxgiJLewPrHUPLk6OdL7wjU6ScWy8YPycJ0PZeJwXWorU/s865/5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="865" data-original-width="526" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYI_GbfY7xk7gC9zJYem_brc40qcT1vz_hgUYYrAlyEvuC_-tf3u-rWo4T0zSHlUt6YXhbctTRCVEGzbjal2TwJhhcE8mlg64SxgiJLewPrHUPLk6OdL7wjU6ScWy8YPycJ0PZeJwXWorU/w390-h640/5.png" width="390" /> </a></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;">Service Bus has a cool feature in preview - Service Bus explorer. This bit is interesting because I used to use a third party tool for this (https://github.com/paolosalvatori/ServiceBusExplorer). Now Microsoft provides this feature within the service bus.</span></span> <br /></div><div class="separator" style="clear: both; text-align: center;"> </div></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKgBNARhM69TU3FvHmg25euDaCk2eAmndOgxjBm89JibMk0yUUPfy1ovnI5SQPcd1Ybwqr1FXICzd7bNc6r3Nw6EmDArf5i5IA7jONAOKzpywEdUq1gNJ6GlyEhIDV2ar8y3lK9ImYhkpf/s1822/6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="752" data-original-width="1822" height="264" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKgBNARhM69TU3FvHmg25euDaCk2eAmndOgxjBm89JibMk0yUUPfy1ovnI5SQPcd1Ybwqr1FXICzd7bNc6r3Nw6EmDArf5i5IA7jONAOKzpywEdUq1gNJ6GlyEhIDV2ar8y3lK9ImYhkpf/w640-h264/6.png" width="640" /> </a></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;">Messages can be viewed using the Peek button. Currently no messages available. But it is ready to receive messages.</span></span> <br /></div><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUOsuaORPzH6Nyi9cx2qersjl82mRZ1ibM0tjSuG2aIlChy8FeEijSO_UpjxsfEeleOOp_Wd36PQFBNVma4Eboe7EyvZxHARL0mR9Sx4Bi-iWTcVRGS32ST7W8YsjkzFmlh2bzYOaeIuub/s1615/7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="752" data-original-width="1615" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUOsuaORPzH6Nyi9cx2qersjl82mRZ1ibM0tjSuG2aIlChy8FeEijSO_UpjxsfEeleOOp_Wd36PQFBNVma4Eboe7EyvZxHARL0mR9Sx4Bi-iWTcVRGS32ST7W8YsjkzFmlh2bzYOaeIuub/w640-h298/7.png" width="640" /></a></div><p><span style="font-family: arial;"><span style="font-size: small;">At this stage, assumption is that an Embedded canvas app triggers a flow with 4 Parameter values. Skipping this, as there are plenty of posts about this part. </span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">Next part is the Power Automate. It has mainly 3 steps. PowerApps is the trigger point of this Power Automate. Compose step forms a Json message from the values sent across. Send Message step is for sending a service bus message.</span></span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc8aqy6PYvB2KjoVW5Ae8NPq2Z8PBTPJkcSe9OFZrJ8pTR3HDtLMf6UzRxuAdXeULxno_AxYzd8jcfzVTQ0HD7cSaZ_ejUdsxAJ_EhcoS4r7yFz_RxfKFn_B0Q4eAqN_BNq-X-Rdl5MHbi/s1615/7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></p><div class="separator" style="clear: both; text-align: center;"> <br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSuBYINEJ6qO90kq8HspDEFygRPIpBaZmCmgUK76NbwR1MvYeXZzttGWEc6O-CmPHIC_wWbh-UYKXMsKbVBg2Gzr7FDFoVgFapHC78OUkis6m3yfI4gggn7RX1vM7N4vTJIgHOFmeOjzox/s998/8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="998" data-original-width="778" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSuBYINEJ6qO90kq8HspDEFygRPIpBaZmCmgUK76NbwR1MvYeXZzttGWEc6O-CmPHIC_wWbh-UYKXMsKbVBg2Gzr7FDFoVgFapHC78OUkis6m3yfI4gggn7RX1vM7N4vTJIgHOFmeOjzox/w498-h640/8.png" width="498" /> </a></div><div class="separator" style="clear: both; text-align: center;"> <span style="font-family: arial;"><span style="font-size: small;">Session Id is set to a new guid but feel free to set whichever you prefer. Output of the compose message is set to the Content. </span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"><br /></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;">Service Bus connection part is shown below. Service bus connection from the Shared Access policy is provided here.<br /></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"> </span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4IqK5sKcMuGYB4X4KJpYBq7EsktfZ155Xuyvd0tASN56nEr1jxxY1q3Rz9zXvvVFRVFTQ3sGKfPpw2rTbjDKyF01d5ff8pKyAAoWzj1SBnkfID0zsPOqH0HR3yIjFLiZm2D3LjIKv6nnd/s805/11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="805" data-original-width="771" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4IqK5sKcMuGYB4X4KJpYBq7EsktfZ155Xuyvd0tASN56nEr1jxxY1q3Rz9zXvvVFRVFTQ3sGKfPpw2rTbjDKyF01d5ff8pKyAAoWzj1SBnkfID0zsPOqH0HR3yIjFLiZm2D3LjIKv6nnd/s320/11.png" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNeetjf8mditpTO6fYfwXIlrT7gPyikd9nuzAJhcPpVYG1kRW8c0xl8-shHNPOaXZHTRm1F8Z2KYC3ypff8Bn92I_Bt25cCha_DPdXGD4gfTWSeUB88lNOI0b6eh2o1LeKOJ2qo4nuUpVL/s749/12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="459" data-original-width="749" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNeetjf8mditpTO6fYfwXIlrT7gPyikd9nuzAJhcPpVYG1kRW8c0xl8-shHNPOaXZHTRm1F8Z2KYC3ypff8Bn92I_Bt25cCha_DPdXGD4gfTWSeUB88lNOI0b6eh2o1LeKOJ2qo4nuUpVL/s320/12.png" width="320" /></a></div><br /> </span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"> </span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"> Power Automate is triggered from the Power App and a message is received in the queue.<br /></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"><br /></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_6PvIWB4T41THKY9S7TPDNNa-bek5Yu2eJryxM8S4CUvgtBeaYNXbBXB7cfKO5o9laIt_YlpdIwmfi_UUWBRxFbcema-H4TkQ7hDUlBuAV3bqiMnhJDCZHS8g5NeL2NPvkqX09Z2UC_uA/s1900/9.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="998" data-original-width="1900" height="336" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_6PvIWB4T41THKY9S7TPDNNa-bek5Yu2eJryxM8S4CUvgtBeaYNXbBXB7cfKO5o9laIt_YlpdIwmfi_UUWBRxFbcema-H4TkQ7hDUlBuAV3bqiMnhJDCZHS8g5NeL2NPvkqX09Z2UC_uA/w640-h336/9.png" width="640" /> </a></div><div class="separator" style="clear: both; text-align: center;">Power Automate run sample is below. <br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgExweNEKjAby31ZFd3bzhHm9WT9gva-qcGyy8bQt4pq3xOGyL6QanxQ9JcpVBWCuA98LZg2AuMLOCPxDLcVMAuTzwdPw1NB8AQFWTxoWSDSNwrBzNIXp7PJuBlzXhfosyhZDiT6jETl5Xy/s2390/10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="2390" data-original-width="771" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgExweNEKjAby31ZFd3bzhHm9WT9gva-qcGyy8bQt4pq3xOGyL6QanxQ9JcpVBWCuA98LZg2AuMLOCPxDLcVMAuTzwdPw1NB8AQFWTxoWSDSNwrBzNIXp7PJuBlzXhfosyhZDiT6jETl5Xy/s16000/10.png" /> </a></div><div class="separator" style="clear: both; text-align: center;"> </div><div class="separator" style="clear: both; text-align: center;"><br /> Next part is to have an Azure function to gets triggered as soon as the message arrives in the queue. As mentioned earlier this could be a console app as well.</div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;">From Visual studio select a new project and choose azure function<br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm9_2yUU1F0zuJlwhWwvUaZS9lNSQkBzLwIEcqbisedXaagX99kl5XTket9Caatl3QUj5bZ4-cuiP9vftpgRUa1beoxYAQ-B7HDphTsYnTytTM4IUmRFSZjzVsc6DMiAL6olCzzqMjgxc0/s1845/14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="931" data-original-width="1845" height="322" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm9_2yUU1F0zuJlwhWwvUaZS9lNSQkBzLwIEcqbisedXaagX99kl5XTket9Caatl3QUj5bZ4-cuiP9vftpgRUa1beoxYAQ-B7HDphTsYnTytTM4IUmRFSZjzVsc6DMiAL6olCzzqMjgxc0/w640-h322/14.png" width="640" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div>Choose Service Bus Queue trigger and provide queue name and connection string values. This can be updated later as well. At this point, just put myqueue and mySBConnection.<br /><span style="font-size: small;"><br /></span></span><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHf49l9FOhytT-u86CLOkETcxjduGqZpHnMTO1_tr-fRwZLC94Z6tAIP9_SjlP_uUokYYn69fTFMuIKliKWldcQJmzTIp6ArgIzbntjsIxFDIvpnq72hFlu9dlo4woQ9QHNZOQFIUZV2Qh/s1283/15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="887" data-original-width="1283" height="442" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHf49l9FOhytT-u86CLOkETcxjduGqZpHnMTO1_tr-fRwZLC94Z6tAIP9_SjlP_uUokYYn69fTFMuIKliKWldcQJmzTIp6ArgIzbntjsIxFDIvpnq72hFlu9dlo4woQ9QHNZOQFIUZV2Qh/w640-h442/15.png" width="640" /> </a></div><div class="separator" style="clear: both; text-align: center;"> </div><div class="separator" style="clear: both; text-align: center;"> <span style="font-family: arial;">Connection string is updated in loal.settings.json file.</span><br /></div></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiMUXhxhYKfALiFwrtrykbVIWM42ikD9hjlLWoe733JPkekrCA6gh7mYVOg8f6L4ZGcbAutiuwmB-L3CBkog506qIfg3WzqCWs0mdLfVMZOBUr3swlV9dlzWpBW2WVrUj0ym8kGUd_uGfO/s1403/19.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="259" data-original-width="1403" height="118" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiMUXhxhYKfALiFwrtrykbVIWM42ikD9hjlLWoe733JPkekrCA6gh7mYVOg8f6L4ZGcbAutiuwmB-L3CBkog506qIfg3WzqCWs0mdLfVMZOBUr3swlV9dlzWpBW2WVrUj0ym8kGUd_uGfO/w640-h118/19.png" width="640" /></a></div><p></p><p><span style="font-size: small;"><span style="font-family: arial;">Queue name is updated as bankwizardq in the function. Next step is to run the function using the run button. When a message arrives in the service bus queue, function gets triggered. </span></span><br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjey2ZgL1Aomk-Ff2r9EvnLdd0XIA5jguk2OUPfGT8FjavzLZSfdqBS6mxaSP7mDsYjrmqsf7suI911Rp8xCLUYabKeyYC04PTPilFJlIkDJojZRqHDOKnI_M8IXzyulAd5leLzzBWD49U0/s1367/17.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="494" data-original-width="1367" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjey2ZgL1Aomk-Ff2r9EvnLdd0XIA5jguk2OUPfGT8FjavzLZSfdqBS6mxaSP7mDsYjrmqsf7suI911Rp8xCLUYabKeyYC04PTPilFJlIkDJojZRqHDOKnI_M8IXzyulAd5leLzzBWD49U0/w640-h232/17.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"> <span style="font-family: arial;"><span style="font-size: small;">Console window output is below.<br /></span></span></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwzuF_Um52Cu0KnaUuSP8gNoyMQkgD-XJdOU_aZ5GbjV1p5WDHAL9VuZ6oEseQUU4SBxqhlg-R2trgFjqprY27q6jebo5pCLhNp2XyO_f0CCg6xREQi7mnv3x1gzGlG0z40NRHVartVl4V/s1849/18.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="105" data-original-width="1849" height="36" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwzuF_Um52Cu0KnaUuSP8gNoyMQkgD-XJdOU_aZ5GbjV1p5WDHAL9VuZ6oEseQUU4SBxqhlg-R2trgFjqprY27q6jebo5pCLhNp2XyO_f0CCg6xREQi7mnv3x1gzGlG0z40NRHVartVl4V/w640-h36/18.png" width="640" /></a></div><p><span style="font-size: small;"><span style="font-family: arial;">Azure function can call Third party APIs to udpate the details / Udpate DB as per the requirements. These are guidelines only. As per your requirement, things change.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span><br /></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-50096358843003806722021-01-10T00:58:00.003+00:002021-01-10T01:17:39.442+00:00How to Send a Webhook from Dynamics 365 CRM?<p><span style="font-size: small;"><span style="font-family: arial;">Webhooks are lightweight HTTP patterns for connecting to Web APIs. Dynamics CRM provides a nice out of the box feature for this. And that too no code option! It just need some configuration. So no coding in this post !!<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Scenario: We all are familiar with Marketing preferences. Let's imagine we have another Marketing system ( Could be third party or internal) where we need to update this information. For instance, when a contact's preference is udpated it calls an API and sends that update. It is a POST operation.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Webhooks are very useful in this scenario. They are configurable and based on triggers. For instance, when a contact is updated / created it can send a webhook to an API.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Here is a small diagram to understand this concept. Please note that the API Management services is optional. But highly recommended. It accepts API calls and routes them securely to your backend services. API Managment services is not used in this demo and is optional.<br /></span></span></p><p></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgX-lmGXF3_z0YbIX8PG229y0clVBJ-ifNfxu70-uEKqsTtKcNXjp_tMiJWV8I8m97FvqHIy6AGp5yETFivMuF2yEN_CH-DmZvQTCoPrgN5GDMny4l_yekJZaHRyhKSEUkPm7kXlFdhHojO/s985/13.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="528" data-original-width="985" height="344" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgX-lmGXF3_z0YbIX8PG229y0clVBJ-ifNfxu70-uEKqsTtKcNXjp_tMiJWV8I8m97FvqHIy6AGp5yETFivMuF2yEN_CH-DmZvQTCoPrgN5GDMny4l_yekJZaHRyhKSEUkPm7kXlFdhHojO/w640-h344/13.png" width="640" /></a></div><br /><span style="font-family: arial;"></span></span></div><span style="font-size: small;"><span style="font-family: arial;">Dynamics user updates marketing preferences of a contact record in Dynamics. This triggers a webhook and sends / posts to an API endpoint.</span></span><p></p><p></p><p><span style="font-size: small;"><span style="font-family: arial;">Now the API app could be internal APIs or even external APIs depending on the requirements. There are different ways to mock this. One of the option is Requestbin (<a href="https://requestbin.com/ " target="_blank">https://requestbin.com/ </a>). This is really cool one! And it is recommended in Microsoft documentations.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">It acts like an API app. So it would help to do initial testing, How the webhook contents looks like etc. So let's configure one first. </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">So navigate to <a href="https://requestbin.com/ " target="_blank">https://requestbin.com/ </a></span></span><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> It is super easy to create an account. And then click on the create request bin option.<br /></span></span></p><p></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgcknYPgeIDA3ExMrK8J4JeD_Hf_h3CRUxQIyimmiz-zBoCQDkRgh1SAb8hurwYuY7ApZFR1LckEfG45k59jvWowB8MEsX96bElR8Is1C9-ycFUTlBXNt3EoOpAdkYwapIYf68GXoo2MND/s1844/2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="971" data-original-width="1844" height="338" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgcknYPgeIDA3ExMrK8J4JeD_Hf_h3CRUxQIyimmiz-zBoCQDkRgh1SAb8hurwYuY7ApZFR1LckEfG45k59jvWowB8MEsX96bElR8Is1C9-ycFUTlBXNt3EoOpAdkYwapIYf68GXoo2MND/w640-h338/2.png" width="640" /></a></span></span></div><p></p><p><span style="font-size: small;"><span style="font-family: arial;">You could see your unique end point as shown in the picture. Also note on the left you could see the triggers. So leave this page open. When a webhook is triggered that gets logged here.<br /></span></span></p><p></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSD_-2Ij6t-kU-PGxl4I6H6t5BYakAzvvrMykbZZu9w4WhM58FaSj16HVz2smMPb5HEW8KJPg5hQdNkoqYDo3_NenjS4HRUPst0Jp2wOaFJzf7uzsgrA6aZdwIPIGjJf1KmIPVDRJwJJ0k/s1824/3.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="869" data-original-width="1824" height="304" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSD_-2Ij6t-kU-PGxl4I6H6t5BYakAzvvrMykbZZu9w4WhM58FaSj16HVz2smMPb5HEW8KJPg5hQdNkoqYDo3_NenjS4HRUPst0Jp2wOaFJzf7uzsgrA6aZdwIPIGjJf1KmIPVDRJwJJ0k/w640-h304/3.png" width="640" /></a></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><br />Now this is our mock end point ( API app to test this ). So copy that end point value.</span></span><p></p><p><span style="font-size: small;"><span style="font-family: arial;">Next part is to do the configuration in Dynamics plugin registration tool.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Plugin registration tool is a tool provided by Microsoft based on Dynamics CRM SDK. It can be downloed from the below link.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><a href="https://www.nuget.org/packages/Microsoft.CrmSdk.XrmTooling.PluginRegistrationTool">https://www.nuget.org/packages/Microsoft.CrmSdk.XrmTooling.PluginRegistrationTool</a></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Once downloaded, click on the exe and connect to your organisation.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">After connecting to your organisation, you could see the option to register a webhook.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span></p><p></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmijr0SI9ZCofiTALAJbPFDzLhtuf0wvwrsG18gJfvu3chgvc2gPSmZwf4gPqIw13mWj3nrhhMVF7FP_DvTwDe66Uc95SnHsaEx7XPv_sRnAFCoX8rT8eMFEWVtYS_idIonvC26cZfXKjV/s1439/4.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="383" data-original-width="1439" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmijr0SI9ZCofiTALAJbPFDzLhtuf0wvwrsG18gJfvu3chgvc2gPSmZwf4gPqIw13mWj3nrhhMVF7FP_DvTwDe66Uc95SnHsaEx7XPv_sRnAFCoX8rT8eMFEWVtYS_idIonvC26cZfXKjV/w640-h170/4.png" width="640" /></a></span></span></div><p></p><p><span style="font-size: small;"><span style="font-family: arial;">Now name you could provide any. There are three types of authentication available. In this case WebhookKey option is chosen.Value doesn't matter in this case as Requestbin is a mock. End point URL is the url that is generated from Request bin. In real scenario this would the real API end point / Azure API management URL. After entering values click on Save.<br /></span></span></p><p></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiP8v8YYpU0SczPsyEnigYdN815Szwi5IxJ64AczYi-XjagIcUdojgVjJ_j8OqcCmZvPiMNp9KPq3EmZrU0j2X3oFgxIassfxgSl1KmUoFKNdd-XtK_b7BrreZd5OdmLfcSK5ZR-1Ni8Un0/s585/5.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="585" data-original-width="562" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiP8v8YYpU0SczPsyEnigYdN815Szwi5IxJ64AczYi-XjagIcUdojgVjJ_j8OqcCmZvPiMNp9KPq3EmZrU0j2X3oFgxIassfxgSl1KmUoFKNdd-XtK_b7BrreZd5OdmLfcSK5ZR-1Ni8Un0/w614-h640/5.png" width="614" /></a></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><br />Next step is to configure a trigger. So right click on the webhook end point and choose register a step.</span></span><p></p><p></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXMP-o6zB_t2hyKSNys3TISPxR0jqODV2o3K8d9yHFMGhBrJcxdJUwKh0bDA7bIeltj7izUZf9xRuzJZnvF-2grPUOBmJ0chIGR0yqaovAgBza_pF5fTPyfpxwK0Zvya8wA3fR3jE3YQKy/s1430/6.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="790" data-original-width="1430" height="354" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXMP-o6zB_t2hyKSNys3TISPxR0jqODV2o3K8d9yHFMGhBrJcxdJUwKh0bDA7bIeltj7izUZf9xRuzJZnvF-2grPUOBmJ0chIGR0yqaovAgBza_pF5fTPyfpxwK0Zvya8wA3fR3jE3YQKy/w640-h354/6.png" width="640" /></a></span></span></div><p></p><p><span style="font-size: small;"><span style="font-family: arial;">Steps are based on operations. A step for record creation and another one for record update. Contact Update step is ok.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> Few things to understand here.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Message - Operation</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Entity - Entity for which the trigger is required.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Filter Attributes - This is quite useful. So it decides when the webhook gets triggered. For instance, we may only be interestered in certain attributes update and not all. So we could choose here. As it is a demo , its left as it is . But in real scenario, highly recommended to filter them.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Execution Mode - Make sure that this async. </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Also make sure that delete asyncoperation if successful. Otherwise storage space would be wasted. <br /></span></span></p><p></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjABYhRHq55dEm8KcDrRRH83kku0NffVUi3z8WxITCe3l7udDu3TPROzaHDqCpTdnN5ARqDx5-lO1nhMPERYCmq5rA7RpDXcumkdk-O7dBYc5InQDKSag8lm9WrByqhNZN01VK_QEM8dewV/s1252/7.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="787" data-original-width="1252" height="402" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjABYhRHq55dEm8KcDrRRH83kku0NffVUi3z8WxITCe3l7udDu3TPROzaHDqCpTdnN5ARqDx5-lO1nhMPERYCmq5rA7RpDXcumkdk-O7dBYc5InQDKSag8lm9WrByqhNZN01VK_QEM8dewV/w640-h402/7.png" width="640" /></a></span></span></div><p></p><p><span style="font-size: small;"><span style="font-family: arial;">Webhook registration is below.<br /><br /></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8K-6VXjpFzJiTKGFamw8JI3s45eVDoUzP1SP4XQlW71i0zuYIE8wc7JrX3cle1QTKm11p9d7moRDSVevxD6kZIu78a6f3hcuTOO5Jgsgf3RXzjpeKiBJNoKTk98Kk0MsmijtOauePKPfZ/s861/8.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="60" data-original-width="861" height="44" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8K-6VXjpFzJiTKGFamw8JI3s45eVDoUzP1SP4XQlW71i0zuYIE8wc7JrX3cle1QTKm11p9d7moRDSVevxD6kZIu78a6f3hcuTOO5Jgsgf3RXzjpeKiBJNoKTk98Kk0MsmijtOauePKPfZ/w640-h44/8.png" width="640" /></a></span></span></div><p></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span><span style="font-size: small;"><span style="font-family: arial;">Time to see it in action!!!</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Let's navigate to Dynamics CRM and update preferences on a contact record. Contact methods Email and Phone updated from Allow to Do Not Allow.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><br /><br /></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2bX1m7GX10Mq13ik2aKuN2FATEUBrKjjmMjwd6RPW8bepJenLeVcvsMW1_l-GafCKSJB8Ry10FWMVPkv4WHwMnjI9ghAgEv-Xmc6hg7sMmj77RljZ0H4PzR0CI6GKg-BbSwTBfPjAEevz/s1562/9.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="767" data-original-width="1562" height="314" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2bX1m7GX10Mq13ik2aKuN2FATEUBrKjjmMjwd6RPW8bepJenLeVcvsMW1_l-GafCKSJB8Ry10FWMVPkv4WHwMnjI9ghAgEv-Xmc6hg7sMmj77RljZ0H4PzR0CI6GKg-BbSwTBfPjAEevz/w640-h314/9.png" width="640" /> </a></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"> </span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;">This trigger gets logged in Request Bin straightaway.</span> <br /></span></div><p></p><p></p><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrailG3nPd5g2E_81I9To55UNIIfRpMcEr3EVbdd3KtxquO53pMwlw524T7LAFysXRZE3iXl1fRla4Ir6z2E3qTCnX_00fWpL08opPQmsntXLQwgVO5Kl7GIelR4WB4jywV-kPgB1GewBR/s576/10.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="576" data-original-width="476" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrailG3nPd5g2E_81I9To55UNIIfRpMcEr3EVbdd3KtxquO53pMwlw524T7LAFysXRZE3iXl1fRla4Ir6z2E3qTCnX_00fWpL08opPQmsntXLQwgVO5Kl7GIelR4WB4jywV-kPgB1GewBR/w528-h640/10.png" width="528" /></a></div><span style="font-size: small;"></span><p></p><p><span style="font-size: small;"><span style="font-family: arial;">It is possible to inspect the data. That is the coolest part. The whole structure is available. This means you could see the values in the webhook content.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCYbnUKrvOzP2wKyURi6lRrSL0ttIxGGb1Gc0oPotqxHMHS_AdhPdkiIb4qAKgETRIC4oWg_gEXVRy2ktiAXlurFBD3JMfXFvm_DTSSvftA_vdtv485KHSYwMiVM5WC56OK6KNpFZRjQWn/s1743/11.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="481" data-original-width="1743" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCYbnUKrvOzP2wKyURi6lRrSL0ttIxGGb1Gc0oPotqxHMHS_AdhPdkiIb4qAKgETRIC4oWg_gEXVRy2ktiAXlurFBD3JMfXFvm_DTSSvftA_vdtv485KHSYwMiVM5WC56OK6KNpFZRjQWn/w640-h176/11.png" width="640" /></a></span></span></div><p></p><p><span style="font-size: small;"><span style="font-family: arial;">For instance, you could see the values that were udated on the CRM side.<br /> </span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWDCcmsVIbzA9UvHFab6d5FcyUa4bbjPaKBzJxp83qamvfWtKZKqOx7AGiW7jBSG7hGQ6d_MOYAYUT6HalskCs2zWbpaVHZBwTt7_WjXIWjCfCWRMODtqLtO-SvSMOLqfyOVIFgja_MGNa/s1323/12.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="788" data-original-width="1323" height="382" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWDCcmsVIbzA9UvHFab6d5FcyUa4bbjPaKBzJxp83qamvfWtKZKqOx7AGiW7jBSG7hGQ6d_MOYAYUT6HalskCs2zWbpaVHZBwTt7_WjXIWjCfCWRMODtqLtO-SvSMOLqfyOVIFgja_MGNa/w640-h382/12.png" width="640" /></a></span></span></div><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span><p></p><p><span style="font-size: small;"><span style="font-family: arial;">So we managed to send an update happened in Dynamics to an API using webhook and that too in real time. So this is like a mock scenario. In a real scenario it could be an API that would update data in another system. All we need to do is to post a webhook to the API and then code should be written on the API side to update whereever needed. Sending part doesn't need any code. Just configuration will do. Please read Microsoft documentations for further details. As Azure service bus is also an out of the box integration, it is always confusing which one to choose. So Microsoft has provided some guidelines for this as well.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">(Ref: <a href="https://docs.microsoft.com/en-us/dynamics365/customerengagement/on-premises/developer/use-webhooks#query-failed-asynchronous-jobs-for-a-given-step">https://docs.microsoft.com/en-us/dynamics365/customerengagement/on-premises/developer/use-webhooks#query-failed-asynchronous-jobs-for-a-given-step )</a></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">"When deciding between the webhook model and the Azure Service Bus integration, here are some items to keep in mind:</span></span></p><span style="font-size: small;"><span style="font-family: arial;">
</span></span><ul><li><span style="font-size: small;"><span style="font-family: arial;">Azure Service Bus works for high scale processing, and provides a
full queueing mechanism if Dynamics 365 is pushing many events.</span></span></li><li><span style="font-size: small;"><span style="font-family: arial;">Webhooks can only scale to the point at which your hosted web service can handle the messages.</span></span></li><li><span style="font-size: small;"><span style="font-family: arial;">Webhooks enables synchronous and asynchronous steps. Azure Service Bus only allows for asynchronous steps.</span></span></li><li><span style="font-size: small;"><span style="font-family: arial;">Webhooks send POST requests with JSON payload and can be consumed by
any programming language or web application hosted anywhere.</span></span></li><li><span style="font-size: small;"><span style="font-family: arial;">Both webhooks and Azure Service Bus can be invoked from a plugin or custom workflow activity."</span></span><span style="font-size: small;"><span style="font-family: arial;"></span></span></li></ul><p><span style="font-size: small;"><span style="font-family: arial;"> <br /></span></span></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-70379483286049714812020-12-30T23:58:00.005+00:002021-01-01T21:04:38.811+00:00Tips for Implementing Service Protection API Limits with Dynamics 365 CRM Web API Scenario<p></p><p><span style="font-size: small;"><span style="font-family: arial;">Dynamics CRM API limits is a big topic. If you are not familiar what are the API limits for Dynamics 365, it is described here in a nutshell ( <a href="https://crmdm.blogspot.com/2020/11/dynamics-365-api-limits.html?m=0">https://crmdm.blogspot.com/2020/11/dynamics-365-api-limits.html?m=0 )<br /></a></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> This post aims to provide some tips for implementing the service protection API limits along with Dynamicis CRM Web API scenario.<br /></span></span></p><p></p><p></p><p><span style="font-size: small;"><span style="font-family: arial;"> In simple words, if your API requests exceeds the API limits mentioned below, your system would be throttled. API request returns a famous error called 'Too Many Requests' / 429 error.</span></span><br /><span style="font-size: small;"><span style="font-family: arial;"> </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">"API limits enforced <i>per web server</i> within the 5 minute sliding window.
</span></span></p><p></p><table class="table"><thead>
<tr>
<th>Measure</th>
<th>Description</th>
<th>Limit per web server</th>
</tr>
</thead><tbody><tr>
<td>Number of requests</td>
<td>The cumulative number of requests made by the user.</td>
<td>6000</td>
</tr><tr>
<td>Execution time</td>
<td>The combined execution time of all requests made by the user.</td>
<td>20 minutes (1200 seconds)</td>
</tr><tr><td>Number of concurrent requests</td><td>The number of concurrent requests made by the user</td><td>52"</td></tr></tbody></table><p><span style="font-size: small;"><span style="font-family: arial;">( Ref:<a href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/api-limits#retry-operations">https://docs.microsoft.com/en-us/powerapps/developer/data-platform/api-limits#retry-operations)</a></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> Solution is mentioned by Microsoft in the above link. Basically the error response would have something like a header called 'Retry-After'. It would also have a retry after time in seconds.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">I have some code snippets that I tried based on Microsoft documentation+ improved+unit tests. </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> As per Microsoft documentation, all requests go through HttpClient.SendAsync method. Here is a small diagram to understand this concept. One main advantage of this implementation is that Retry implementation can be done in one place.HttpClient.SendAsync() is a generic method. In other words, it's wrapping common operations with Http method.<br /></span></span></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF9SDfGclzv3dEEEBR6JVJqvb5-f8-pDVYz39AfMR6xz8PKvZ-PXtapc6T5q07eRCqShUUwwCJyJA71LWnXGsuu4dU5ilKlzCGnXJxocMwUtwwN0IxuxP7ccMTjMuxmagUqCJnvGQ9G5kh/s1170/CRMWebAPIMethods.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="770" data-original-width="1170" height="422" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF9SDfGclzv3dEEEBR6JVJqvb5-f8-pDVYz39AfMR6xz8PKvZ-PXtapc6T5q07eRCqShUUwwCJyJA71LWnXGsuu4dU5ilKlzCGnXJxocMwUtwwN0IxuxP7ccMTjMuxmagUqCJnvGQ9G5kh/w640-h422/CRMWebAPIMethods.png" width="640" /></a></div><br /><span style="font-size: small;"><span style="font-family: arial;">For instance, a read
operation is GetAsync. Eventhough HttpClient has a GetAsync method, it
should go through HttpClient.SendAsync() as shown. </span></span><span style="font-size: small;"><span style="font-family: arial;"><span style="font-size: small;"><span style="font-family: arial;">HttpClient.SendAsync() captures 429 error and 'Retry-After' values accurately. So it is possible to set up the retry mechanism on the HttpClient.SendAsync(). And Retry is needed only in one place because rest of the methods call this one.<br /></span></span></span></span><p></p><span style="font-size: small;"><span style="font-family: arial;"><span style="font-size: small;"><span style="font-family: arial;">So make sure that only SendAsync() is called for HttpClient request.Code sample is below. <br /></span></span></span></span><p><span style="font-size: small;"><span style="font-family: arial;"></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span><span style="font-size: small;"><span style="font-family: arial;">For understanding tokens part , please refer this post - (<a href="https://crmdm.blogspot.com/2020/12/dynamics-365-crm-web-api-with-azure.html?m=0" target="_blank">https://crmdm.blogspot.com/2020/12/dynamics-365-crm-web-api-with-azure.html?m=0 </a>). You would get a better idea. For unit tests, it's possible to mock the token service.</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Maximum Retry is set to 3 in this sample. But feel free to change it accordingly.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">using Demo.Core.Helper;<br />using Demo.Core.Interfaces;<br />using Microsoft.Extensions.Logging;<br />using System;<br />using System.Linq;<br />using System.Net;<br />using System.Net.Http;<br />using System.Net.Http.Headers;<br />using System.Threading;<br />using System.Threading.Tasks;<br /><br />namespace Demo.Core.Services<br />{<br /> public class HttpClientService : IHttpClientService<br /> {<br /> public HttpClient HttpClient { get; set; }<br /> private readonly ITokenService _tokenService;<br /> private readonly ILogger _logger;<br /><br /> public HttpClientService(ITokenService tokenService, ILogger<HttpClientService> logger)<br /> {<br /> _tokenService = tokenService ?? throw new ArgumentNullException(nameof(tokenService));<br /> _logger = logger ?? throw new ArgumentNullException(nameof(logger));<br /><br /> HttpClient = new HttpClient();<br /> HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));<br /><br /> var token = _tokenService.GenerateToken().Result;<br /> HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",<br /> token);<br /> }<br /><br /> public async Task<HttpResponseMessage> GetAsync(string requestUri)<br /> {<br /> HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri);<br /> HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead;<br /> return await SendAsync(request, completionOption);<br /> }<br /><br /> private async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,<br /> HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseHeadersRead, int retryCount = 0)<br /> {<br /> var maxRetry = 3;<br /> HttpResponseMessage response = null;<br /> try<br /> {<br /> response = await HttpClient.SendAsync(request.Clone(), httpCompletionOption);<br /> }<br /> catch (Exception e)<br /> {<br /> _logger.LogError(e.Message);<br /> }<br /><br /> if (!response.IsSuccessStatusCode)<br /> {<br /> if (response.StatusCode != HttpStatusCode.TooManyRequests)<br /> {<br /> throw new HttpRequestException();<br /> }<br /> else<br /> {<br /> if (++retryCount >= maxRetry)<br /> {<br /> throw new HttpRequestException();<br /> }<br /> var seconds = (response.Headers.Contains("Retry-After"))? <br /> int.Parse(response.Headers.GetValues("Retry-After").FirstOrDefault())<br /> :(int)Math.Pow(2, retryCount);<br /> Thread.Sleep(TimeSpan.FromSeconds(seconds));<br /><br /> return await SendAsync(request, httpCompletionOption, retryCount);<br /> }<br /> }<br /> else<br /> {<br /> return response;<br /> }<br /> }<br /> }<br />}<br /><br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">As you could see in the code, it sends a request copy rather than actual request. This is because request wouldn't be available if error occurs.A function called Clone takes the copy of the request. This is provided by Microsoft. Didn't make any changes to it. Code snippet is below ( Ref:Microsoft)</span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">using System;<br />using System.Collections.Generic;<br />using System.Net.Http;<br /><br />namespace Demo.Core.Helper<br />{<br /> /// <summary><br /> /// Contains extension methods to clone HttpRequestMessage and HttpContent types.<br /> /// </summary><br /> public static class Extensions<br /> {<br /><br /> /// <summary><br /> /// Clones a HttpRequestMessage instance<br /> /// </summary><br /> /// <param name="request">The HttpRequestMessage to clone.</param><br /> /// <returns>A copy of the HttpRequestMessage</returns><br /> public static HttpRequestMessage Clone(this HttpRequestMessage request)<br /> {<br /> var clone = new HttpRequestMessage(request.Method, request.RequestUri)<br /> {<br /> Content = request.Content.Clone(),<br /> Version = request.Version<br /> };<br /> foreach (KeyValuePair<string, object> prop in request.Properties)<br /> {<br /> clone.Properties.Add(prop);<br /> }<br /> foreach (KeyValuePair<string, IEnumerable<string>> header in request.Headers)<br /> {<br /> clone.Headers.TryAddWithoutValidation(header.Key, header.Value);<br /> }<br /><br /> return clone;<br /> }<br /> /// <summary><br /> /// Clones a HttpContent instance<br /> /// </summary><br /> /// <param name="content">The HttpContent to clone</param><br /> /// <returns>A copy of the HttpContent</returns><br /> public static HttpContent Clone(this HttpContent content)<br /> {<br /><br /> if (content == null) return null;<br /><br /> HttpContent clone;<br /><br /> switch (content)<br /> {<br /> case StringContent sc:<br /> clone = new StringContent(sc.ReadAsStringAsync().Result);<br /> break;<br /> default:<br /> throw new Exception($"{content.GetType()} Content type not implemented for HttpContent.Clone extension method.");<br /> }<br /><br /> clone.Headers.Clear();<br /> foreach (KeyValuePair<string, IEnumerable<string>> header in content.Headers)<br /> {<br /> clone.Headers.Add(header.Key, header.Value);<br /> }<br /><br /> return clone;<br /><br /> }<br /> }<br />}<br /><br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Wrote a couple of unit tests to test this scenario. Thanks to this post (ref: <a href="https://www.c-sharpcorner.com/article/mocking-httpclient-using-xunit-in-net-core/">https://www.c-sharpcorner.com/article/mocking-httpclient-using-xunit-in-net-core/</a>) </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">using AutoFixture;<br />using Demo.Core.Interfaces;<br />using Demo.Core.Services;<br />using Microsoft.Extensions.Logging;<br />using Moq;<br />using Moq.Protected;<br />using System;<br />using System.Net;<br />using System.Net.Http;<br />using System.Net.Http.Headers;<br />using System.Threading;<br />using System.Threading.Tasks;<br />using Xunit;<br /><br />namespace Demo.Core.Unit.Tests<br />{<br /> public class HttpClientServiceTests<br /> {<br /> private readonly Mock<ILogger<HttpClientService>> _mockLogger;<br /> private readonly Mock<ITokenService> _mockTokenService;<br /> private HttpClientService _sut;<br /> public HttpClientServiceTests()<br /> {<br /> _mockLogger = new Mock<ILogger<HttpClientService>>();<br /> _mockTokenService = new Mock<ITokenService>();<br /> _sut = new HttpClientService(_mockTokenService.Object, _mockLogger.Object);<br /> }<br /><br /> [Fact]<br /> public async Task GetAsyncReturnsSuccessfully()<br /> {<br /> var expected = "I am Tom";<br /> var Result = new StringContent(expected);<br /> var httpMessageHandler = new Mock<HttpMessageHandler>();<br /> var fixture = new Fixture();<br /><br /> httpMessageHandler.Protected()<br /> .Setup<Task<HttpResponseMessage>>(<br /> "SendAsync",<br /> ItExpr.IsAny<HttpRequestMessage>(),<br /> ItExpr.IsAny<CancellationToken>()<br /> )<br /> .ReturnsAsync((HttpRequestMessage request, CancellationToken token) =><br /> {<br /> HttpResponseMessage response = new HttpResponseMessage();<br /> response.StatusCode = HttpStatusCode.OK;<br /> response.Content = Result;<br /> response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");<br /> return response;<br /> });<br /><br /> var httpClient = new HttpClient(httpMessageHandler.Object);<br /> httpClient.BaseAddress = fixture.Create<Uri>();<br /> _sut.HttpClient = httpClient;<br /><br /> var response = await _sut.GetAsync(string.Empty);<br /> var actual = await response.Content.ReadAsStringAsync();<br /><br /> Assert.Equal(actual, expected);<br /> }<br /><br /> [Fact]<br /> public async Task GetAsyncReturnsTooManyRequestsThrowsException()<br /> {<br /><br /> var expected = "I am Tom";<br /> var Result = new StringContent(expected);<br /> var httpMessageHandler = new Mock<HttpMessageHandler>();<br /> var fixture = new Fixture();<br /> var waitTimeInSeconds = 5;<br /> httpMessageHandler.Protected()<br /> .Setup<Task<HttpResponseMessage>>(<br /> "SendAsync",<br /> ItExpr.IsAny<HttpRequestMessage>(),<br /> ItExpr.IsAny<CancellationToken>()<br /> )<br /> .ReturnsAsync((HttpRequestMessage request, CancellationToken token) =><br /> {<br /> HttpResponseMessage response = new HttpResponseMessage();<br /> response.StatusCode = HttpStatusCode.TooManyRequests;<br /> response.Content = Result;<br /> response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");<br /> response.Headers.RetryAfter = new RetryConditionHeaderValue(TimeSpan.FromSeconds(waitTimeInSeconds));<br /> return response;<br /> });<br /><br /> var httpClient = new HttpClient(httpMessageHandler.Object);<br /> httpClient.BaseAddress = fixture.Create<Uri>();<br /> _sut.HttpClient = httpClient;<br /><br /> await Assert.ThrowsAsync<HttpRequestException>(() => _sut.GetAsync(string.Empty));<br /> }<br /> }<br />}<br /><br /> Green is good!<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><img alt="" src="data:image/png;base64,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" /></span></span></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-56840047127878003772020-12-29T00:30:00.003+00:002020-12-30T21:50:16.859+00:00Dynamics 365 CRM Web API with Azure Function - Nail it!<p><span style="font-family: arial;"><span style="font-size: small;">As you all know there are mainly two connectivity options are available for our apps ( Azure function, Console app, mobile app, web apps etc) to communicate with Dynamics 365 CRM.</span></span></p><ul style="text-align: left;"><li><span style="font-family: arial;"><span style="font-size: small;">Organization service - SOAP service </span></span></li></ul><ul style="text-align: left;"><li><span style="font-family: arial;"><span style="font-size: small;">Dynamics 365 CRM Web API - HTTP REST API <br /></span></span></li></ul><p><span style="font-family: arial;"><span style="font-size: small;">Organization service has some limitations. For instance, you could only use a .Net Frame work based app with organisation service. Also in my view, it is getting less popular day by day.<br /></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">Dynamics 365 CRM Web API has a lot of cool features. One of the main advantages is that you could use .Net core based apps ( for instance, azure functions, web apps etc)to connect to Dynamics CRM. Third party systems can utilise Crm Web Apis to communicate with Dynamics 365 CRM. Using a timer triggered .Net core azure function we could easily demonstrate this. Main steps are below. Detailed steps and sample code are also provided in this post. <br /></span></span></p><ul style="text-align: left;"><li><span style="font-family: arial;"><span style="font-size: small;">How to generate a token from Azure AD for Dynamics 365 CRM Web API</span><span style="font-size: small;"> </span><br /></span></li></ul><ul style="text-align: left;"><li><span style="font-family: arial;"><span style="font-size: small;">Use the token to call a simple Dynamics CRM Web Api - Who am I- It returns some basic info like your organizationid,userid etc</span></span></li></ul><p><span style="font-family: arial;"><span style="font-size: small;">First things first , let's understand the architecture first. I have created an architecture diagram to understand this functionality. </span><span style="font-size: small;"><span style="font-size: small;">Please note that the Azure AD and Dynamics 365 CRM are under the same tenant. </span> <br /></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqFhg2GDKbqx8mHi8fGseivmUTt4vPMGR6YNw6LRtJo2XiiI-0Bt-XQ2r7pMTIOUMqeiHyzdTeG7Om_tuDjAX67vhE9ABdBx0DAiD8SZ-v0GCumNv_VoCXDBtNQDL9MQJaPT8OEYFMbsYw/s1010/CRM+Web+API+Architecure+Diagram.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1010" data-original-width="880" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqFhg2GDKbqx8mHi8fGseivmUTt4vPMGR6YNw6LRtJo2XiiI-0Bt-XQ2r7pMTIOUMqeiHyzdTeG7Om_tuDjAX67vhE9ABdBx0DAiD8SZ-v0GCumNv_VoCXDBtNQDL9MQJaPT8OEYFMbsYw/w558-h640/CRM+Web+API+Architecure+Diagram.png" width="558" /></a></span></span></div><p><span style="font-family: arial;"><span style="font-size: small;">As you could see in the diagram, Azure function requests the token from Azure AD first. Using this token it can do API calls( CRUD - Create, Read, Update and Delete operations) to Dynamics 365 CRM. </span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">Tokens life time: By default Azure AD tokens expire in one hour (ref: <a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-configurable-token-lifetimes#access-tokens">https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-configurable-token-lifetimes#access-tokens)</a></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><p><span style="font-family: arial;"><b><span style="font-size: small;">Azure AD Part:</span></b></span></p><p><span style="font-family: arial;"><span style="font-size: small;">From Azure we need the below values in order to retrieve a token.</span></span></p><ul style="text-align: left;"><li><span style="font-family: arial;"><span style="font-size: small;">Tenant Id</span></span></li><li><span style="font-family: arial;"><span style="font-size: small;">Application Id</span></span></li><li><span style="font-family: arial;"><span style="font-size: small;">Client Secret<br /></span></span></li></ul><p><span style="font-family: arial;"><span style="font-size: small;">In order to get these values we need to do some configurations. These are shown in the diagram. But now let's do it step by step.</span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">Navigate to <a href="https://portal.azure.com/"> https://portal.azure.com/</a> and look for Active Directory.</span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"> </span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpH_3VhtixcftWemetqJ_6sLheq03VMJIuq10erLbXs3-wPtDIe5Z9RNOe1fbhheuG4gKmPa7OYSN_XiLxocVmu3WcQposO2-cKMIBZJ8jBsnPiyiXq8w7Ib2DWp6QabCOE-YIO0DDyeKV/s1655/2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="907" data-original-width="1655" height="350" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpH_3VhtixcftWemetqJ_6sLheq03VMJIuq10erLbXs3-wPtDIe5Z9RNOe1fbhheuG4gKmPa7OYSN_XiLxocVmu3WcQposO2-cKMIBZJ8jBsnPiyiXq8w7Ib2DWp6QabCOE-YIO0DDyeKV/w640-h350/2.png" width="640" /> </a></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"> We get the Tenant Id straightaway as shown in the picture. That was easy! one down!<br /></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"> <br /></span></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijtIufl2N7Bfi4dieqFJEhQjQwlwBAtw3RMrpGVx5IN5U1EzGHqUZ-H8Hh7xrc-uy4VyCnGadMyZJ14b_jSckNmXDYo1OzXnZpwQvqoDjy_N5R8-HfzYUrcLh2Njxig02DzXY5uGAUyPsO/s1383/3.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="925" data-original-width="1383" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijtIufl2N7Bfi4dieqFJEhQjQwlwBAtw3RMrpGVx5IN5U1EzGHqUZ-H8Hh7xrc-uy4VyCnGadMyZJ14b_jSckNmXDYo1OzXnZpwQvqoDjy_N5R8-HfzYUrcLh2Njxig02DzXY5uGAUyPsO/w640-h428/3.png" width="640" /></a></span></span></div><p><span style="font-family: arial;"><span style="font-size: small;"> </span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">Navigate to App Registrations on the left navigation.<br /></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyjQOQ4YsTIiekoiPxMxn1MC-YypP82w6jycHDp6n3a3zvGmfMnj7u31dgAm3Kr2Qt7RmGiGXV1bCP0fYDw4Xfm8PV6OzgCZrOT5VERRDK2wBUfCBh92-b-AuRaKBnXBMCjN82CqkDn2at/s755/4.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="755" data-original-width="323" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyjQOQ4YsTIiekoiPxMxn1MC-YypP82w6jycHDp6n3a3zvGmfMnj7u31dgAm3Kr2Qt7RmGiGXV1bCP0fYDw4Xfm8PV6OzgCZrOT5VERRDK2wBUfCBh92-b-AuRaKBnXBMCjN82CqkDn2at/w274-h640/4.png" width="274" /></a></span></div><span style="font-family: arial;"><br /><span style="font-size: small;"><br /></span></span><p><span style="font-family: arial;"><span style="font-size: small;">Click on New Registration.</span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5IFxyyaUDLX6mVp_kdg4CgzikvZe-rZ-eDGbVlKpzS_WEzrgjEePHp6TfyB00nAy2rk2cG5skmBNXH1DEgUAet8WDxPMoTMfQovwSx-PU-KMiw9f6yQrDBOE7OzVNmU1IHKQzKLITR86G/s1665/5.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="597" data-original-width="1665" height="230" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5IFxyyaUDLX6mVp_kdg4CgzikvZe-rZ-eDGbVlKpzS_WEzrgjEePHp6TfyB00nAy2rk2cG5skmBNXH1DEgUAet8WDxPMoTMfQovwSx-PU-KMiw9f6yQrDBOE7OzVNmU1IHKQzKLITR86G/w640-h230/5.png" width="640" /></a></span></div><span style="font-family: arial;"><br /></span><p><span style="font-family: arial;"><span style="font-size: small;">Register a new application with a preferred name.<br /></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"> </span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKqF76FrE8QxuqbC6uPZ6F7DEqOXt5Rr2sKOk3flZOuz02pYGLwpFqxi3r4cvAHBCYveIXc4uuGQVGO0jvtNh22ycvT0n08YJaCA27rO7Hzgw4gBEWo-ktN4Rj7dAU9jQQHT0C_2Er1gjQ/s1650/6.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="902" data-original-width="1650" height="350" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKqF76FrE8QxuqbC6uPZ6F7DEqOXt5Rr2sKOk3flZOuz02pYGLwpFqxi3r4cvAHBCYveIXc4uuGQVGO0jvtNh22ycvT0n08YJaCA27rO7Hzgw4gBEWo-ktN4Rj7dAU9jQQHT0C_2Er1gjQ/w640-h350/6.png" width="640" /></a></span></span></div><span style="font-family: arial;"><span style="font-size: small;"><br />And we get the Application Id from here.<br /></span></span><p><span style="font-family: arial;"><span style="font-size: small;"><br /></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp8p7xsetz-qNS7gaxeQNkAllnwTYVB4kEBh713M-RVT4IPnpw9FQ8MHny-mSZpPI58WPYdEKroQ2x9tZq1wkFZSyLvwfHyUaNVih27cGFrlV-E9yC8dCa_ANWPnGS6qjOjh29maBrMbDN/s1913/7.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="902" data-original-width="1913" height="302" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp8p7xsetz-qNS7gaxeQNkAllnwTYVB4kEBh713M-RVT4IPnpw9FQ8MHny-mSZpPI58WPYdEKroQ2x9tZq1wkFZSyLvwfHyUaNVih27cGFrlV-E9yC8dCa_ANWPnGS6qjOjh29maBrMbDN/w640-h302/7.png" width="640" /></a></span></div><span style="font-family: arial;"><br /><span style="font-size: small;">Next step is to set up API permission for our Dynamics 365 CRM instance. So let's navigate to API Permissions.<br /></span></span><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhg9F2CO2fQffYRIkpZBx4T7_LSIQmZNibotfGczL3JNZ6dR4o9Eqp6dHf3vA47ibrfJtKlkp4rflklunY1kFBNwZVVo6-QrmVQ7YPFpE3f3eIAIOj21NU08091sNlcHvpZV2lFncRWoVRc/s829/8.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="829" data-original-width="335" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhg9F2CO2fQffYRIkpZBx4T7_LSIQmZNibotfGczL3JNZ6dR4o9Eqp6dHf3vA47ibrfJtKlkp4rflklunY1kFBNwZVVo6-QrmVQ7YPFpE3f3eIAIOj21NU08091sNlcHvpZV2lFncRWoVRc/w258-h640/8.png" width="258" /></a></span></div><p><span style="font-family: arial;"><span style="font-size: small;">Click on Add a permission option.<br /></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpTBg-evv6ecrCHpGi8lIEUv7pyjTi1zSbdekxw-DIwOQAb4gsrq_xH0AQq91TvxRqYTL8n0dCXRgqa4MmTulVexDIQUb78Gl4C_gUQzHuEpceY0tAUjyl2870Tsd4DbGr58NBDWUMMpgT/s830/9.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="830" data-original-width="573" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpTBg-evv6ecrCHpGi8lIEUv7pyjTi1zSbdekxw-DIwOQAb4gsrq_xH0AQq91TvxRqYTL8n0dCXRgqa4MmTulVexDIQUb78Gl4C_gUQzHuEpceY0tAUjyl2870Tsd4DbGr58NBDWUMMpgT/w442-h640/9.png" width="442" /></a></span></div><span style="font-size: small;"><br />Let's choose Dynamics CRM from the list. You could also see that other app registrations are possible here. Our focus is Dynamics CRM.<br /></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsFgS64VxACPwjBZEebZOdijFPFrx-OveB2Z7A12kGbOD8kCqjHhrasZpEoLebUpjhh9SeMX-wnlkk7pXmpYkT3JGjdMf6mkreZEQX6lT5P5QairFBd2riHsuwfRekPWU7EMDKnFpCjQaZ/s1059/10.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="881" data-original-width="1059" height="532" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsFgS64VxACPwjBZEebZOdijFPFrx-OveB2Z7A12kGbOD8kCqjHhrasZpEoLebUpjhh9SeMX-wnlkk7pXmpYkT3JGjdMf6mkreZEQX6lT5P5QairFBd2riHsuwfRekPWU7EMDKnFpCjQaZ/w640-h532/10.png" width="640" /></a></span></div><span style="font-size: small;"><br /></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;">Tick on the user_impersonation option and click on Add permission. It means that this application is registered here and it can access Dynamics CRM as a user (ref:<a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app">https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app</a>) <br /></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimuYtEakuv5hWPmz-R05u5l4h4PQF11he1CJfJ2vJsQCBOBxhe6pHE2yOJlABONn5NVIzSizRHOvEuHC_pglZ7eyOu7t8CahqgvOVhA6q4wR7bjn_mJRg86rqfhCJ600X5r7GPWlUKrRv-/s1070/11.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="884" data-original-width="1070" height="528" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimuYtEakuv5hWPmz-R05u5l4h4PQF11he1CJfJ2vJsQCBOBxhe6pHE2yOJlABONn5NVIzSizRHOvEuHC_pglZ7eyOu7t8CahqgvOVhA6q4wR7bjn_mJRg86rqfhCJ600X5r7GPWlUKrRv-/w640-h528/11.png" width="640" /></a></span></div><span style="font-size: small;"><br />Next step is to define a new client secret for our app registration.Click on the Certificates & Secrets option. And then click on the New Client Secret button.<br /></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5FxbB0R5ZzCGArgL99rBmmmr26v726onfAhq7BfCjwd0GRH80g9FTsO6OrMlYiLvVZAnU9IvXuJ69iLhMXYJjyE8mvWn7CRT7j8bIBBd1n7EHUuQlhH6tKL4eCl35lKkKnnVcSV3bh8KV/s1647/13.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="904" data-original-width="1647" height="352" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5FxbB0R5ZzCGArgL99rBmmmr26v726onfAhq7BfCjwd0GRH80g9FTsO6OrMlYiLvVZAnU9IvXuJ69iLhMXYJjyE8mvWn7CRT7j8bIBBd1n7EHUuQlhH6tKL4eCl35lKkKnnVcSV3bh8KV/w640-h352/13.png" width="640" /></a></span></div><p></p><p><span style="font-family: arial;"><span style="font-size: small;">It is possible to set expiry for the secret. In our case, it doen't matter. Just a description and choose the expiry as per our preference.<br /></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZ1Yx-zGp-ByIOeVDnyezsAtikrr37eh9hl4MCOtToz9FXcdSwmQzCWmCr7j80Sb6DSRW_Wxy7Ro0kUkjl17rVNby2_4XK9DzI2c7BbqlRfRW3AWIzXM3qSOUbvAgX2s1D3r5bHzwQxoOF/s1321/14.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="738" data-original-width="1321" height="358" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZ1Yx-zGp-ByIOeVDnyezsAtikrr37eh9hl4MCOtToz9FXcdSwmQzCWmCr7j80Sb6DSRW_Wxy7Ro0kUkjl17rVNby2_4XK9DzI2c7BbqlRfRW3AWIzXM3qSOUbvAgX2s1D3r5bHzwQxoOF/w640-h358/14.png" width="640" /></a></span></div><p></p><p><span style="font-family: arial;"><span style="font-size: small;">Now there is an important bit here. We need only Client secret value not the ID displayed there. I didn't have to use that anywhere.<br /></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd0oVJn3R7U-17pHisom7aRcnjkYD0RjuRhHkFxPn3PAORcisbVLzzLHADUHuw-Kq-1KaDFB1_IzWjelLCd5vbIi35eCKTxr-9bA0v5xrt5EFFo2HLqgt1v73vZRJvfbCWR1tHSpfUTTvZ/s1646/15.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="741" data-original-width="1646" height="288" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd0oVJn3R7U-17pHisom7aRcnjkYD0RjuRhHkFxPn3PAORcisbVLzzLHADUHuw-Kq-1KaDFB1_IzWjelLCd5vbIi35eCKTxr-9bA0v5xrt5EFFo2HLqgt1v73vZRJvfbCWR1tHSpfUTTvZ/w640-h288/15.png" width="640" /></a></span></div><span style="font-size: small;"><br /></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;">Azure set up is done here. </span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"><b>Dynamics CRM Part: </b><br /></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">Next part is Dynamics 365 CRM. So we need to create a new 'application user' in Dynamics. This user is created based on the application id from the Azure App registration that we did earlier.</span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">Navigate to Dynamics CRM->Settings->Security->Users and choose application users. <br /></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpuv_LuZGvvYd4yIQSC2xjVNW9AlGTotc2g_XOlmS2gB57XF4J6rw5ARYjTbX55l_oUm71eTl-F6IvvtOeP9vKJAAUhekzvIoHaoxQMuZnQjHRBr1aYYAcHBLn0R1EJSBcBEJBmIKiCmIC/s1920/16.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="443" data-original-width="1920" height="148" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpuv_LuZGvvYd4yIQSC2xjVNW9AlGTotc2g_XOlmS2gB57XF4J6rw5ARYjTbX55l_oUm71eTl-F6IvvtOeP9vKJAAUhekzvIoHaoxQMuZnQjHRBr1aYYAcHBLn0R1EJSBcBEJBmIKiCmIC/w640-h148/16.png" width="640" /></a></span></div><span style="font-size: small;"><br />Click on the New button</span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtXD5nPUHhjkCsQenetgoufAdFU5r0rXmzyahAXMZWF5FJ0-VuET4ZFLxa2vlZvEgDbIWnVKhiVc18y3IG9CVl5ApixeDFnvFp6el98b8P_UxLj6GQTnWHqndBtqegPQBWdnDXBjtDt6l8/s1920/17.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="253" data-original-width="1920" height="84" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtXD5nPUHhjkCsQenetgoufAdFU5r0rXmzyahAXMZWF5FJ0-VuET4ZFLxa2vlZvEgDbIWnVKhiVc18y3IG9CVl5ApixeDFnvFp6el98b8P_UxLj6GQTnWHqndBtqegPQBWdnDXBjtDt6l8/w640-h84/17.png" width="640" /></a></span></div><span style="font-size: small;"><br />Here is a tricky part. We need to make sure that we switch forms to Application user form.</span><p></p><p><span style="font-family: arial;"><span style="font-size: small;">Application Id - The one from Azure app registrion. Please refere previous step.</span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">User Name, Primary Email - I usally put something like this</span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">preferredusername@mycrmtrialorganisationname.onmicrosoft.com</span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">For instance, testuser1@mytrialcrm.onmicrosoft.com ( Refer your trial crm login)</span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">Full Name - As you prefer.</span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">After providing all the above details, save the record.</span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">If the user creation is successul, you should see </span><span style="font-size: small;"><span class="ms-crm-InlineEditLabel ms-crm-UnsetWhiteSpace" id="applicationiduri_cl_span"><span class="ms-crm-InlineEditLabelText ms-crm-UnsetWhiteSpace" id="applicationiduri_cl" style="max-width: 138px; text-align: left;">Application ID URI and </span></span></span><span style="font-size: small;"><span class="ms-crm-InlineEditLabel ms-crm-UnsetWhiteSpace" id="applicationiduri_cl_span"><span class="ms-crm-InlineEditLabelText ms-crm-UnsetWhiteSpace" id="applicationiduri_cl" style="max-width: 138px; text-align: left;"><span class="ms-crm-InlineEditLabel ms-crm-UnsetWhiteSpace keyboardFocusClass" id="azureactivedirectoryobjectid_cl_span"><span class="ms-crm-InlineEditLabelText ms-crm-UnsetWhiteSpace" id="azureactivedirectoryobjectid_cl" style="max-width: 138px; text-align: left;">Azure AD Object ID auto populated.<br /></span></span></span></span></span></span></p><div class="ms-crm-Inline-GradientMask"><span style="font-size: small;">
</span></div><p></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrpn29jdtG4hQOgcHYjCQOAuExVaGB6hSHZuoYGv2-MT8YAtZxg6TZmFvWKUC84uXROKs7hrtWSG5dYEZfKdUUYl6gPJtyDgG0f4T3rsy-IgnaYBcZ5wGVjH9Aawkp33s7oDMJIZ_-T8GI/s1920/18.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="914" data-original-width="1920" height="304" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrpn29jdtG4hQOgcHYjCQOAuExVaGB6hSHZuoYGv2-MT8YAtZxg6TZmFvWKUC84uXROKs7hrtWSG5dYEZfKdUUYl6gPJtyDgG0f4T3rsy-IgnaYBcZ5wGVjH9Aawkp33s7oDMJIZ_-T8GI/w640-h304/18.png" width="640" /></a></span></div><span style="font-size: small;"><br />Next step is to give access to the application user. As you could imagine, a user would need security roles in order to do CRUD ( Create, Read, Update, Delete)operations. </span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOtnQD-8_KvBG5WQsrmDp-4aQ3TwfvWDVpTeSBmrJVzPjyb5w5MEp7sqbUFed6I0u8ra7cFH2QkH7pyAlDK3MpjB0HEyQqGV9wlp4UbSYi2hu_N2f7m7P5nCWKLHaYTNeUmL-loEduFbqk/s1919/19.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="347" data-original-width="1919" height="116" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOtnQD-8_KvBG5WQsrmDp-4aQ3TwfvWDVpTeSBmrJVzPjyb5w5MEp7sqbUFed6I0u8ra7cFH2QkH7pyAlDK3MpjB0HEyQqGV9wlp4UbSYi2hu_N2f7m7P5nCWKLHaYTNeUmL-loEduFbqk/w640-h116/19.png" width="640" /></a></span></div><span style="font-size: small;"><br />So in this case let's assign system administrator role to this user.</span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxRQc8uAnt_5n8FydgBPmrWNfR6mpP7cXLQMqmUPTV116EjpchVLUAmKEH_5YkW4WycwS1RBo9mj8YEoFAg2viG4zJxXId9wzvUffEpuR2jqocbyPBChAE3C83a0X6ivh5ouYRtlh6Ksm5/s623/20.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="500" data-original-width="623" height="514" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxRQc8uAnt_5n8FydgBPmrWNfR6mpP7cXLQMqmUPTV116EjpchVLUAmKEH_5YkW4WycwS1RBo9mj8YEoFAg2viG4zJxXId9wzvUffEpuR2jqocbyPBChAE3C83a0X6ivh5ouYRtlh6Ksm5/w640-h514/20.png" width="640" /></a></span></div><span style="font-size: small;"><br />We need one more info from Dynamics CRM. Basically we need Crm web api base url also known as service root Url. Navigate to Developer resources as shown below. <br /></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;"></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM2dRByrJFvPw7MgZX0MVmTr6ybhml_hlw2t2puslGM-QBdqUcuIbAVIRknQMHuR6iY440-vQ8_lazGi4bfZTtgkqW6OFwdxm3IhQnYtXydHpJpshfVa1x1UTUgjbn059bTvCPKXqA-xYN/s1920/22.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="527" data-original-width="1920" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM2dRByrJFvPw7MgZX0MVmTr6ybhml_hlw2t2puslGM-QBdqUcuIbAVIRknQMHuR6iY440-vQ8_lazGi4bfZTtgkqW6OFwdxm3IhQnYtXydHpJpshfVa1x1UTUgjbn059bTvCPKXqA-xYN/w640-h176/22.png" width="640" /></a></span></div><span style="font-size: small;"><br />Copy the service root url. This is needed in our web api request for whoami.<br /></span><p></p><p><span style="font-family: arial;"><br /></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXCbFshxKMrvSv3lOjDHGb9m47YBnIr6sZfnaCDJQPVRsnLC4jlNzlZFWlJLBK5IDrxrHzoR8EmPuCnDncUlkkHBwK0RkfSHJYqpE0r3iPLAJ6e1lOEgAsFuh-njwe_06zFviduq1vTTUn/s681/21.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="447" data-original-width="681" height="420" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXCbFshxKMrvSv3lOjDHGb9m47YBnIr6sZfnaCDJQPVRsnLC4jlNzlZFWlJLBK5IDrxrHzoR8EmPuCnDncUlkkHBwK0RkfSHJYqpE0r3iPLAJ6e1lOEgAsFuh-njwe_06zFviduq1vTTUn/w640-h420/21.png" width="640" /></a></span></div><span style="font-family: arial;"><br /></span><p></p><p><span style="font-family: arial;"><span style="font-size: small;">I hope that you can relate all the steps with the architecture diagram now. Simple demo built on the above steps is given below. It is a simple Web API call. But you could expand it. For instance, create contact , lead etc. <br /></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">Sample azure function here is based on .Net Core 3.1 and has a timer trigger of 1 minute. This means it gets triggered every minute. You could run it locally easily.<br /></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">Azure functions have a settings file. It is handy to define all the config values there and retrieve when needed.<br /></span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">local.settings json file is here.</span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">Oranganization url is your crm url, Aad Instance is the valuei in the below screen shot. It is a generic value.<br /></span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw5yq-tx4A4wBof6kPFjqsaUabXGE_PBcfCBEeOMPyC6A-HTedySqQ1CHB63Vwk2YQR7jw10-lsnbP6HZ73pX6ZkWMs_8MXvjUumfdj2mdIqUQWH3lwDod3qHw3VgUw8b457Kq4WxYK7O5/s1018/1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="368" data-original-width="1018" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw5yq-tx4A4wBof6kPFjqsaUabXGE_PBcfCBEeOMPyC6A-HTedySqQ1CHB63Vwk2YQR7jw10-lsnbP6HZ73pX6ZkWMs_8MXvjUumfdj2mdIqUQWH3lwDod3qHw3VgUw8b457Kq4WxYK7O5/w640-h232/1.png" width="640" /></a></span></span></div><span style="font-family: arial;"><span style="font-size: small;"><br /><br /></span></span><p><span style="font-family: arial;"><span style="font-size: small;">Here is the full source code</span></span></p><p><span style="font-family: arial;"><span style="font-size: small;">using Microsoft.Azure.WebJobs;<br />using Microsoft.Extensions.Logging;<br />using Microsoft.IdentityModel.Clients.ActiveDirectory;<br />using System;<br />using System.Net.Http;<br />using System.Net.Http.Headers;<br />using System.Threading.Tasks;<br /><br />namespace AzureTimerTriggerFunD365WepApi.Core<br />{<br /> public class D365WebApiTokenDemo<br /> {<br /> private string _token;<br /> [FunctionName("D365WebApiTokenDemo")]<br /> public void Run([TimerTrigger("0 */1 * * * *")] TimerInfo myTimer, ILogger log)<br /> {<br /> log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");<br /> var tokenResponse = GenerateToken();<br /> _token = tokenResponse.Result;<br /> var whoAmI = WhoAmI();<br /> log.LogInformation($"Who am I? {whoAmI.Result}");<br /><br /> }<br /><br /> public async Task<string> GenerateToken()<br /> {<br /> var organizationUrl = Environment.GetEnvironmentVariable("OrganizationUrl");<br /> var aadInstance = Environment.GetEnvironmentVariable("AadInstance");<br /><br /> var applicationId = Environment.GetEnvironmentVariable("ApplicationId");<br /> var tenantId = Environment.GetEnvironmentVariable("TenantId");<br /> var clientSecret = Environment.GetEnvironmentVariable("ClientSecret");<br /><br /><br /> var clientCredentials = new ClientCredential(applicationId, clientSecret);<br /> var authenticationContext = new AuthenticationContext(aadInstance + tenantId);<br /> var authenticationResult = await authenticationContext.AcquireTokenAsync(organizationUrl, clientCredentials);<br /><br /> return authenticationResult?.AccessToken ?? throw new InvalidOperationException("No Token Received");<br /> }<br /><br /> public async Task<string> WhoAmI()<br /> {<br /> var crmWebApiBaseUrl = Environment.GetEnvironmentVariable("CrmWebApiBaseUrl");<br /> var httpClient = new HttpClient();<br /> httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));<br /> httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",<br /> _token);<br /><br /> var whoAmIResponse = await httpClient.GetAsync($"{crmWebApiBaseUrl}/WhoAmI()");<br /><br /> return await whoAmIResponse.Content.ReadAsStringAsync();<br /> }<br /> }<br />}<br /><br /></span></span></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com1tag:blogger.com,1999:blog-7483666954520465023.post-44238742712453053402020-12-22T23:30:00.012+00:002020-12-23T10:45:43.094+00:00RabbitMQ Trigger for Azure Functions<p><span style="font-size: small;"><span style="font-family: arial;">RabbitMQ is a popular message broker (<a href="https://www.rabbitmq.com/">https://www.rabbitmq.com/</a>). Azure functions support RabbitMQ triggers and bindings. In other words, azure function can listen to a RabbitMQ message queue and also possible to push a message to the RabbitMQ message queue.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><img height="276" src="data:image/png;base64,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AGCxCAEBAOicEBAAYLEIAQEAAABg4ISAAAAAADBwQkAAAAAAGDghIAAAAAAMnBAQAAAAAAZOCAgAAAAAAycEBAAAAICBEwICAAAAwMAJAQEAAABg4ISAAAAAADBwQkAAAAAAGDghIAAAAAAMnBAQAAAAAAZOCAgAAAAAAycEBAAAAICBEwICAAAAwMAJAQEAAABg4ISAAAAAADBwQkAAAAAAGDghIAAAAAAMnBAQAAAAAAZOCAgAAAAAAycEBAAAAICBEwICAAAAwMAJAQEAAABg4ISAAAAAADBwQkAAAAAAGDghIAAAAAAMnBAQAAAAAAZOCAgAAAAAAycEBAAAAICBEwICAAAAwMAJAQEAAABg4ISAAAAAADBwQkAAAAAAGDghIAAAAAAMnBAQAAAAAAZOCAgAAAAAAycEBAAAAICBW6kQ8AUveBEAADAD8772BwAmrVwIuGvXzwIAAD0SAgLA4hECAgAAnRICAsDiEQICAACdEgICwOIRAgIAAJ0SAgLA4hECAgAAnRICAsDiEQICAACdEgICwOIRAgIAAJ0SAgLA4hECAgAAnRICAsDiEQICAACdEgICwOIRAgIAAJ0SAgLA4hECAgAAnRICAsDiEQICAACdEgICwOIRAgIAAJ0SAgLA4hECAgAAnRICAsDiEQICAACdEgICwOIRAgIAAJ0SAgLA4hEC/oPt7e2wvb099wumlEsuORDG4/GE3btPn2tZ5l0nsd27T5+on71799fenksuOVC4nccf/7Idn+3du39inr179+/YP9m8qX2XSa03Xk88T591GG8XAEBbQkAAWDxCwF0/G44//mVhe3u7MPSZt0suOVA71OrS7t2nL2wwmqqj/M91gtLdu08vDL2y8C61/akQsE54VhQ4pmTtMS5v3+Hv3r3759LWAIBhEQICwOIRAu56ImRrEtLMkhCwXZ1V7cvt7e3C0Der81Svwr5DwL1798+13hexpycAsFyEgACweISAu372SA/A449/WbL3VdlQzrj3YLyM7e3tiWVkv4+Hepb1QCwLAeuuP+tZllpXXJash1xqe1NlieePg66qMsR1nKqLVIBWFpZVBadlvQDz82dli9fbZwhYd7h33Xpv2vb0BgQApiUEBIDFs/IhYNzbLQtOii5o4uCpTggX9ziLl5EKmvKmDQHz01xyyYGJdWeBUH7+bPtTPQHj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IuC6iIAAAABAMxGwXyLguoiAAAAAQDMRsF8i4LqIgAAAAEAzEbBfIuC6iIAAAABAs6urKzq29Hx/+PqLjh3734tDEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACCEwEBAAAAIDgREAAAAACC24uAH77+2gEAAAAA8aQI+C9hTb9vGkhxOgAAAABJRU5ErkJggg==" width="400" /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;">Microsoft Documentation and sample C# <br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-rabbitmq">https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-rabbitmq</a></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-rabbitmq-trigger?tabs=csharp">https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-rabbitmq-trigger?tabs=csharp</a><br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> <br /></span></span></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-8274561945439418622020-12-19T10:23:00.000+00:002020-12-19T10:23:12.950+00:00Changes (deprecations) coming in Power Apps, Power Automate, and customer engagement apps<p><span style="font-size: small;"><span style="font-family: arial;"> Changes for Power Apps, Power Automate and CE are listed in the below link.<br /><br /> I would recommend special attention to this part "Deprecation of Office365 authentication type and OrganizationServiceProxy class for connecting to Dataverse". Authentication type 'Office365' is commonly used. So be ready!<br /><br /> Effective April 2021, the authentication protocol will be retired for all new environments within a tenant.<br /> Effective April 2022, the authentication protocol will be retired for all new and existing environments within a tenant.<br /><br />For more details, please refer the below link<br /><br /><a href="https://docs.microsoft.com/en-us/power-platform/important-changes-coming#deprecation-of-office365-authentication-type-and-organizationserviceproxy-class-for-connecting-to-common-data-service" target="_blank">https://docs.microsoft.com/en-us/power-platform/important-changes-coming#deprecation-of-office365-authentication-type-and-organizationserviceproxy-class-for-connecting-to-common-data-service</a></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"> </span></span></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-37591997757092211472020-12-16T00:54:00.001+00:002020-12-17T08:58:03.738+00:00New Dynamics 365 exams <p><span style="font-family: arial;"> Exam Alert:</span></p><p><a href="https://techcommunity.microsoft.com/t5/microsoft-learn-blog/announcing-two-new-microsoft-dynamics-365-fundamentals/ba-p/1628148"><span style="font-family: arial;">https://techcommunity.microsoft.com/t5/microsoft-learn-blog/announcing-two-new-microsoft-dynamics-365-fundamentals/ba-p/1628148</span></a></p><p><span style="font-family: arial;"><br /></span></p><p><br /></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0tag:blogger.com,1999:blog-7483666954520465023.post-70765905048231548512020-12-10T23:00:00.002+00:002020-12-11T15:39:36.198+00:00ER Diagram for Dynamics 365 CRM Entities<p><span style="font-size: small;"><span style="font-family: arial;"> Needed to generate the ER diagram of Dynamics 365 CRM entities. After some research, found the below link and it was very useful! Good part is that it is generated from Dynamics CRM which is our source of truth.<br /></span></span></p><p><span style="font-size: small;"><span style="font-family: arial;"><a href="https://docs.microsoft.com/en-us/dynamics365/customerengagement/on-premises/developer/use-metadata-generate-entity-diagrams">https://docs.microsoft.com/en-us/dynamics365/customerengagement/on-premises/developer/use-metadata-generate-entity-diagrams</a> <br /></span></span></p>D. MANJALYhttp://www.blogger.com/profile/16122189495637340566noreply@blogger.com0