Connectivity Archives - Aric Levin's Digital Transformation Blog http://aric.isite.dev/tag/connectivity/ Microsoft Dynamics 365, Power Platform and Azure Thu, 12 May 2022 04:07:58 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.3 T-SQL Endpoint for Common Data Service http://aric.isite.dev/sql/post/t-sql-endpoint-common-data-service/ Tue, 02 Jun 2020 11:00:00 +0000 https://aric.isite.dev/index.php/2020/06/02/t-sql-endpoint-for-common-data-service/ Since the announcement by Microsoft at the Microsoft Business Applications Summit last month, and even before, I’ve been eager to take a look at the new SQL Connection for the Common Data Service Endpoint. What this means is that we can not write and execute SQL queries against the entity data.

The post T-SQL Endpoint for Common Data Service appeared first on Aric Levin's Digital Transformation Blog.

]]>
Since the announcement by Microsoft at the Microsoft Business Applications Summit last month, and even before, I’ve been eager to take a look at the new SQL Connection for the Common Data Service Endpoint. What this means is that we can not write and execute SQL queries against the entity data.

In order to get started, the first thing that has to be done is enabling the Endpoint, so that we can create a connection from SQL Server Management Studio (SSMS) to our Dynamics/CDS environment. As of now, there are two ways to enable this endpoint.

The first is by navigating to our environment in the Power Platform Admin Center. Click on the settings in the Command bar for the environment, expand the Product collapsed section and click on Features. On the features page change the toggle for TDS endpoint from Off to On.

TDS endpoint - Power Platform Admin Center

The other way to get the same results is by using the SQL 4 CDS Plugin for XrmToolBox by Mark Carrington (make sure that you have the latest version). Open the Plugin and connect to your environment. In the Object Explorer pane, under entities, you will see the T-SQL Endpoint tree option.

TDS endpoint (Xrm ToolBox - SQL 4 CDS)

Right click on the T-SQL Endoint (Disabled), and select Enable:

T-SQL endpoint - Xrm ToolBox - SQL 4 CDS - Enable endpoint

Making this change will allow you to make connections to your CDS environment using the new T-SQL endpoint.

The next thing is we need to connect using SQL Server Management Studio. I am using SQL v18.5, but you should be able to use it with some of the prior versions. The main thing is how we connect to our cloud database.

Within your SSMS, in Object Explorer, click on Connect and select Database Engine. This will pop up the Connect to Server window. In the Server name, enter the Organization Name following by the region and the port. The format would be as follows:
orgname.crm{region}.dynamics.com,5558

If your organization name is crmdemo and your are in North America, the Server name would be: crmdemo.crm.dynamics.com,5558

Next, we have to provide the authentication method. Based on your connection there might be a few different options for you to use. You will need to choose one of the three Azure Active Directory Authentication methods based on your connection settings.

I have tested this out with both Azure Active Directory – Password, which is used when you are connecting using a Username (email) and Password as well Azure Active Directory – Universal with MFA, which will user your organization’s MFA settings to connect.

In this post, I will be using the Azure Active Directory – Password. If you are the only one using the computer, you can check the Remember Password. The screen below (with a few blurs), shows how the connection dialog will look like.

T-SQL Endpoint - SSMS Connect to Server

Finally, our Object Explorer can be expanded, and we will be able to see all of the available tables that we can query on. The image below shows a partial list of the tables that are available:

T-SQL endpoint - SSMS Object Explorer

A few things to note.

  • This is still in preview and not available in all regions
  • The database is in Read-Only state, so no updates can be performed (I am not sure if and when that will change)
  • Only tables and table columns are provided, but there are no custom views or stored procedures. The tables also display the name attributes from related entities.
  • Although what we are seeing in our database shows under tables, these are actually the filtered views.
  • The supported SQL operations include: Batch operations, SELECT, aggregation functions, UNIONs, JOINs and Filtering

Finally, I tested a few queries out including JOIN and Filtering options and got the results just as expected. You can see the screenshot below.

T-SQL endpoint - SSMS Query and results

Hopefully you are excited about this great new enhancement.

The post T-SQL Endpoint for Common Data Service appeared first on Aric Levin's Digital Transformation Blog.

]]>
Get Record CDS action missing attributes in Government Cloud http://aric.isite.dev/flow/post/cds-get-record-missing-attributes-gcc/ Sun, 19 Jan 2020 03:57:00 +0000 https://aric.isite.dev/index.php/2020/01/19/get-record-cds-action-missing-attributes-in-government-cloud/ cds-get-record-missing-attributes-gcc

The post Get Record CDS action missing attributes in Government Cloud appeared first on Aric Levin's Digital Transformation Blog.

]]>
While most of you might not be experiencing this issue, it is still a good workaround for a situation that you might have. Recently we had a situation that when we tried to retrieve the account record using the Get record action in our Government Cloud instance, but the results did not retrieve all the attributes. The attribute that we were really having an issue with was the address1_name.

That did not make much sense, so we had to do some investigation regarding this issue. The first thing that we tried to do is see if we were getting the same behavior using List records, and the results were the same. The List records action provided us the same attributes as we had in the Get record action. Now remember this is in Government Cloud, so we are using the Common Data Service connector and not the Common Data Service current environment connector where we can specify our list of select attributes.

Now we had to see if this behavior was the same in Commercial Cloud. I created a simple flow using the Get record action on the Account record and passing an Id of a record, and all the attributes got returned. This issue did not occur in commercial cloud with an identical test flow and the same data in both environments.

Common Data Service Get Record (GCC)

Of course, first thoughts … bug. Let Microsoft know. The problem is we need a quick resolution, and this does not seem to be something that we would get a resolution quickly. We are still waiting for the CDS Current Environment connector in GCC.

Now, we are getting to the workaround. What do we do? Build a custom connector? Doesn’t make much sense. Should be a quick way to handle this, and there is. We were going to use an HTTP connector.

In order to use an HTTP get action, we would be using a GET method passing the URI and Authentication information and calling the WebAPI directly. The screenshot below shows the required parameters in order to get this working.

HTTP Get Request - Get Missing Attributes GCC

We initialize the Authority, Tenant, Audience, Client Id and Client Secret of our instance in order to connect to the Web Api and then the results will allow us to get the address1_name value from the account entity as it is in our case.

The next action that we had was to create a lead. We use all the data from the Get record in addition to the address1_name field from the HTTPGetAddressName request. The screenshot below shows creating the new record from both the CDS Get Request and the HTTP Get Request.

Common Data Service Create Record + HTTP Response (GCC)

The Location is a formula containing body(‘HTTPGetAddressName’)[‘address1_name’]

Hope this is helpful to anyone, though it seems that the CDS Current Environment Connector will be arriving to GCC and GCC High sometime soon. I don’t have any official statement yet.

The post Get Record CDS action missing attributes in Government Cloud appeared first on Aric Levin's Digital Transformation Blog.

]]>
Configure Azure Service Bus to integrate between CDS and On-Premise SQL database http://aric.isite.dev/azure/post/configure-asb-integrate-cds-sql/ Mon, 06 Jan 2020 07:17:00 +0000 https://aric.isite.dev/index.php/2020/01/06/configure-azure-service-bus-to-integrate-between-cds-and-on-premise-sql-database/ In this blog post I will demonstrate how to use Azure Service Bus and a Listener application to integrate between the Common Data Service (Dynamics 365 or Power Apps Model Driven Application) and an On Premise SQL Service database.

The post Configure Azure Service Bus to integrate between CDS and On-Premise SQL database appeared first on Aric Levin's Digital Transformation Blog.

]]>
In this blog post I will demonstrate how to use Azure Service Bus and a Listener application to integrate between the Common Data Service (Dynamics 365 or Power Apps Model Driven Application) and an On Premise SQL Service database.

There are various other ways to implement this, with the combination of Azure products such as Azure functions, Azure Logic Apps, On-Premise Data Gateway and Microsoft Flow, but those are not always available, especially when working in non-commercial environments, or when IT restricts what resources are available to the different departments of the agencies.

In order to implement this, there are a few prerequisites that have to be completed. These are set up the database server, write the console application to act as the event listener, install the Azure Service Bus, create plugin code to call the Azure Service Bus when a particular event happens. The logic of this article will be as follows: When an account record gets created or updated, it will call the Azure Service Bus in order to update an On-Premise SQL database that a new record is created or an existing record got updated.

Configuring the SQL database

We will start with the first step which is the configuration of the database. You can set up the database with a single table (to use only for Accounts), or add some related tables if necessary. We will also create a couple of stored procedures to Insert and Update the Accounts table. Links to code files will be shared at the end of the post. The image below displays the database structure. For the purpose of this articles, the Contacts and Users tables will not be required.

Azure Staging SQL Database with Tables and Stored Procedures

Create the Azure Service Bus Namespace

We can now create the Azure Service Bus. Login to your Azure Portal and search for Service Bus under the list of available Resources. Click on the Add button to add a new service bus.

Add New Azure Service Bus Namespace

This will open the create namespace window. Enter a name for your service bus in the Create Namespace window. It will append servicebus.windows.net to the name that you specify. Select a pricing tier, your subscription, resource group and location where you want this hosted. If you do not have a resource group, you can create a new one from this window.

Azure Service Bus Create Namespace

It will take a couple of minutes (or less) to create your namespace, and then the Azure Service Bus will be visible on your screen. The first thing that we need to do is check the Shared access policy. There is a default Shared Access policy that is available with the new Azure Service Bus that was created, and includes the three available claims: Manage, Send, Listen.

Send we only need Send and Listen, we will create a new Shared access policy, naming it IntegrationSharedAccessKey (or any other name that you would like) and set the available claims to Send and Listen. After you create your shared access policy, click on it to see the Keys and the Connection Strings. You will need them for configuring CDS and your Console application.

Configure the Service Endpoint in CDS

Next, let’s add this to out CDS environment, by running the Plugin Registration Tool. We will be using the Plugin Registration Tool for version 9.1. Run the Plugin Registration Tool and Create a new connection to your CDS environment. Click on Register and Select a new Service Endpoint. Copy the Connection String from your Service Bug Resource in Azure, and paste it in the popup window. Make sure that the Let’s Start with the connection string from the Azure Service Bus Portal… option is selected (as shown below).

Add Service Bus Endpoint Connection String

In the next window, Service Endpoint Registration make the following changes:

  • In the namespace address, change sb to https
  • In the Designation Type change to Two Way (you can also do One Way if you prefer, but in this particular examples we are using two-way.
  • Enter a path for the Service Endpoint. This will be used by the console application to listen to where changes are being made.
  • The Authorization Type should be set to SASKey, with the SASKeyName as the name of your Shared Access policy in Azure, and the SAS Key copied from the Primary Key in the Shared Access policy.

Azure Service Bus Service Endpoint Registration

After we have created the Service Endpoint, we need to capture the Guid of the Service Endpoint as we will use it from the plugin that we will soon start developing. In order to get the Guid of the Service Endpoint, click on the Properties tab, and scroll down till you see ServiceEndpointId property. Copy the Guid from there. We can hard code this in our application, or add it as Environmental Variable inside of CDS.

Add Environmental Variable in CDS

Navigate to a solution inside of Power Apps, select the solution and click on the New button on the command bar. Your will see the option to add new environmental variable. Enter a display name, schema name (automatically populated), description and data type. As this is going to store a Guid, you should use Text as the data type. You can enter a default value for your new EndpointId or specify a new value. The screenshot below shows how this is added.

Common Data Service Environmental Variable

As the Environmental Variables are still a new feature and there are some issues that have to be dealt with, you can use the Portal Settings entity or another Configuration entity to store your variables.

Writing the Plugin Code

We can now start developing the plugin code. This is a simple plugin that will run on the Account Create and Account Update messages. Our Plugin includes three code files: Plugin.cs, Account.cs and AccountLogic.cs.

The Plugin.cs is the standard tool generated Plugin.cs file that implements the IPlugin interface. There are only a couple of changes that were done to this class, since we need to communicate with Azure Service Bus.

We added an internal property called CloudService of type IServiceEndpointNotificationService. In the LocalPluginContext constructor, we set the value for the CloudService property.

Add Property for Cloud Service

Get Service for Azure Service Bus Listener

The Account Class adds the Create and Update events to the RegisteredEvents collection, and adds two functions: ExecutePostAccountCreate and ExecutePostAccountUpdate which get the Account Id and call the CreateAccount or UpdateAccount of the logic class.

Account Entity Plugin Logic

The AccountLogic class has a construction that takes four parameters: the Plugin Execution Context, Organization Service, Tracing Service and the Service Endpoint Notification Service. These are all used for the different purposes of the plugin.

Both the CreateAccount and UpdateAccount functions have the exact same logic. The difference is in the message which is going to be passed to the Azure Service Bus as part of the context.

The CreateUpdateAccount function Retrieves all the data from the Account record, gets the Endpoint Id (from the Enviromental Variables Entities), adds the Account record to the Shared Variables of the Context and finally calls the Azure Service Bus passing the context, which includes the data from the Account entity.

Create and Update Account

After the plugin receives the response, it writes the response to a note within the account record. After the plugin is complete, make sure to sign and compile it, and then register it with the plugin registration tool. When the assembly is registered, add two messages (one for Create and one for Update of the Account entity).

Plugin Registration Tool Account Plugin

Writing the Listener Windows Service Application
The final step is to work on the Console Application. We can start by writing the helper class that will connect to SQL Server and Create a new Account record. The first thing that we need to do is add a connection string to the App.Config that is part of the Console Application. If an App.Config file does not exist, you can create one.

In the Connection String section enter the following code:

<add name=”AzureStaging” connectionString=”Data Source={LOCALDBSERVERNAME};Initial Catalog=AzureStaging;User ID=azureadmin;Password=Azur3Adm1n;Persist Security Info=False” />

We create a SqlDataManager class which will call the SQL server stored procedures to Create and Update the account records. The functions will receive the values of the different fields in SQL Server and add them as Stored Procedure parameters as shown below:

Listener Create Account (SQL Data Manager)

Next we create the class to listen and process the incoming requests from Azure Service Bus. The class has a default public function called Execute which accepts a RemoteExecutionContext parameter. This parameters contains the Shared Variables that we passed from our plugin as well as the execution context that allows us to retrieve the message name to know if this is a create or an update.

Azure Service Bus Listener Entry Point

The CreateAccount and UpdateAccount functions receive the Account entity, take the necessary attributes and call the CreateAccount function of the SqlDataManager class in order to store the data in SQL Server.

Azure Service Bus Listener Create Account

We added the Service class to the project, which contains an eventlog component that will write errors to the Event Log. The OnStart Event will listen to events and the OnStop Event will stop listening to the Azure Service Bus.

Azure Service Bus Windows Service Start/Stop

The Console application will run as a Windows Service. The solution includes the Project Installer class which allows us to install this as a Windows Service class. The Main entry point of the application provides us with some testing capabilities as well as installation or uninstallation of the Windows Service.

We added a Program class that allows us to install and uninstall the Windows Service from within our Visual Studio debugger.

Install or Uninstall Windows Service from Visual Studio Debugger

Once the Windows Service is installed by running the VS application with the –install parameter, you will see the results in Services. Verify the Service is running, and depending whether you are testing this on your Local machine or on a Server, determine if to use the Local System account or the Network Service account.

Azure Service Bus Installed Windows Service

Now that we have done installing all the components, it is time to test all the parts working together. We tried running the first test, and the test did not have all the required fields. The description field was missing, so the result was a new note added to the timeline returning the error of a missing field from SQL Server.

Azure Service Bus Integration (End to End - First Try)

We then tried again, providing the Description field as well. This time we saw the success message in the timeline.

Azure Service Bus Integration (End to End - Second Try)

We wanted to verify that the data existed in SQL Server, so we ran a SQL Statement to validate the data, and received the following results:
New Record created in SQL Server. Results successful

Hope this will be a benefit for you. All the Plugin Source, Database Source and Listener Console Application Source Code is available on Github.
https://github.com/ariclevin/Integration/tree/master/ASBListener

The post Configure Azure Service Bus to integrate between CDS and On-Premise SQL database appeared first on Aric Levin's Digital Transformation Blog.

]]>
Eventbrite to CDS Integration – Part 3 (Custom Connector) http://aric.isite.dev/flow/post/eb-cds-integration-iii/ Sun, 29 Dec 2019 23:30:00 +0000 https://aric.isite.dev/index.php/2019/12/29/eventbrite-to-cds-integration-part-3-custom-connector/ In the third post will create our custom connector in order to connect with Eventbrite. The custom connector will allow us to call the Eventbrite api to retrieve the required information about the Events and the Attendees that have not been provided by the Webhook.

The post Eventbrite to CDS Integration – Part 3 (Custom Connector) appeared first on Aric Levin's Digital Transformation Blog.

]]>
In the third post will create our custom connector in order to connect with Eventbrite. The custom connector will allow us to call the Eventbrite api to retrieve the required information about the Events and the Attendees that have not been provided by the Webhook.

Inside of your Power Apps solution, click on the New button on the command bar, select Other and then Choose Custom Connector. In the Custom Connector page, upload an image for use with the connector, specify a background color (if you would like), enter a description and specify the host and base url of the host.

The Host url is www.eventbriteapi.com, and the base url is /v3/.

Eventbrite Integration - Custom Connector General Tab

On the security tab, select API Key as the method of authentication. This will pull up the API key dialog where you will enter the parameters for the API key. Enter API Key in the Parameter label, and Authorization in the Parameter name. The parameter location should stay as Header.

Eventbrite Integration - Custom Connector Security Tab (Api Key Authentication)
Click on the Definition step to continue. We will need to specify two Actions for the Definition. The first action is to get the event information and the second action is to get the attendee information. On the left hand side of the screen click on the New Action link to add the first action. The table below shows the values for each of the properties for the new Action Link:

Field Name Value
Summary Retrieve Event
Description Retrieve Event Information from Eventbrite
Operation ID RetrieveEvent
Visibility none
Verb GET
URL https://www.eventbriteapi.com/v3/events/{event_id}/
Query
Headers
Body
Response 200

Eventbrite Integration - Custom Connector Retrieve Event Definition

Field Name Value
Summary Retrieve Event
Description Retrieve Event Information from Eventbrite
Operation ID RetrieveEvent
Visibility none
Verb GET
URL https://www.eventbriteapi.com/v3/events/{event_id}/attendees/{attendee_id}/
Query
Headers
Body
Response 200

Eventbrite Integration - Custom Connector Retrieve Attendee Definition

You can now Save your Custom Connector.

1 – PREREQUISITES | 2 – EVENTBRITE SETTINGS | 3 – CUSTOM CONNECTOR | 4 – EVENT FLOW | 5 – ATTENDEE FLOW | 6 – TESTING

The post Eventbrite to CDS Integration – Part 3 (Custom Connector) appeared first on Aric Levin's Digital Transformation Blog.

]]>
Eventbrite to CDS Integration – Part 4 (Event Flow) http://aric.isite.dev/flow/post/eb-cds-integration-iv/ Sun, 29 Dec 2019 23:30:00 +0000 https://aric.isite.dev/index.php/2019/12/29/eventbrite-to-cds-integration-part-4-event-flow/ In this fourth post we will update the original flow that we created for when a new event is created in Eventbrite. The flow should have a couple of steps as the baseline. The steps include When a HTTP request is received, and the Initialize Variable action.

The post Eventbrite to CDS Integration – Part 4 (Event Flow) appeared first on Aric Levin's Digital Transformation Blog.

]]>
In this fourth post we will update the original flow that we created for when a new event is created in Eventbrite. The flow should have a couple of steps as the baseline. The steps include When a HTTP request is received, and the Initialize Variable action.

When the Webhook calls the flow, there are certain values that are being passed. One of those values is the action that is being performed (under the config section of the json file).

In our Initialize Variable action, we previously specified the following Action: Action Type, of type String. We did not specify the Value, which we left for now. The value should be as follows (based on the json schema that we provided):

first(split(triggerBody()?[‘config’]?[‘action’],’.’))

Eventbrite Integration - Event Flow Initialize Variable Action Type

The next action will allow us to get the Event Number. We need this number to verify if the Event already exists in our CDS environment and we need to update it, or if we need to create a new event in our environment. This action will also be an Initialize Variable action as shown in the image below.

Eventbrite Integration - Event Flow Initialize Variable Event Number

The value of the Initialize Variable action is: last(take(split(triggerBody()?[‘api_url’],’/’),6)), which will return the event number from the api url.

We now need to verify if the action type corresponds to an event. We will add a condition action that will compare the action type to “event”. If the result will be valid, we will retrieve additional data from the event by calling the custom connector, or terminate the flow if the result is not valid.

Eventbrite Integration - Event Flow Condition Action Type = Event?
If the results from the condition action is No (not valid), we terminate the flow with a status of cancelled. I the results from the condition action is Yes (valid) we will perform a few additional steps which include:

  • Retrieve Event (from Custom Connector)
  • List Events (to check if I already have an event)
  • Condition to check if I have existing Events
    • If yes, Update event
    • If no, Create new event

Eventbrite Integration - Event Flow Condition Results

The Retrieve Event action, calls the custom connector and expects a single string variable containing the event id that we want to retrieve. The Event Number has been provided for the Initialize Variable action prior to the conditions.

Eventbrite Integration - Event Flow Custom Connector Retrieve Event

You will need to make sure that you specify the Api Key to your custom connector before the follow can execute. When you Edit the connection and the Api key prompt shows up, make sure that you enter Bearer before the Api key. For example, if your Private Token (API key) in Eventbrite is ICE1MDAC3YBZKOAIDS1W then you will have to enter Bearer ICE1MDAC3YBZKOAIDS1W in the popup window.

Eventbrite Integration - Custom Connector Authentication Key

Next we retrieve any events from CDS that already have this Event Number. We can retrieve this done by using a Filter Query or a Fetch Xml Query in the List Records action of the Common Data Service (Current Environment) connector. For our purpose we used the Filter Query, but the Fetch Xml can be used as well.

Eventbrite Integration - Event Flow List Events

We can now add a condition to check if an event exists with that number by checking the length of the results from the List Events action: length(body(‘List_Events’)?[‘value’])

Eventbrite Integration - List Events Condition

The results of the condition are simple. If it does exist, we call an Apply to each that will update all the records (there should be only one), and if it does not exist we create a new event record. You will notice in the screenshots below we use the results from the Retrieve Event from the custom connector and use those parameters in our Create and Update actions.

Eventbrite Integration - List Event Condition Results (Yes/No)

1 – PREREQUISITES | 2 – EVENTBRITE SETTINGS | 3 – CUSTOM CONNECTOR | 4 – EVENT FLOW | 5 – ATTENDEE FLOW | 6 – TESTING

The post Eventbrite to CDS Integration – Part 4 (Event Flow) appeared first on Aric Levin's Digital Transformation Blog.

]]>
Eventbrite to CDS Integration – Part 5 (Attendee Flow) http://aric.isite.dev/flow/post/eb-cds-integration-v/ Sun, 29 Dec 2019 23:30:00 +0000 https://aric.isite.dev/index.php/2019/12/29/eventbrite-to-cds-integration-part-5-attendee-flow/ In this fifth post we will update the original flow that we created for when a new attendee is registered in Eventbrite. Your flow should have a couple of steps as the baseline. The steps include When a HTTP request is received, and the Initialize Variable action.

The post Eventbrite to CDS Integration – Part 5 (Attendee Flow) appeared first on Aric Levin's Digital Transformation Blog.

]]>
In this fifth post we will update the original flow that we created for when a new attendee is registered in Eventbrite. Your flow should have a couple of steps as the baseline. The steps include When a HTTP request is received, and the Initialize Variable action.

When the Webhook calls the flow, there are certain values that are being passed. One of those values is the action that is being performed (under the config section of the json file). We start by initializing the variables based on the data that is provided from the HTTP Request. The three variables that we are able to initialize are the Action Type, Event Number and Attendee Number (as shown below):

Eventbrite Integration - Attendee Flow Initialize Variables 1

The following tables shows the values of the three variables that we initialized:

Variable Name

Value

Action Type

first(split(triggerBody()?[‘config’]?[‘action’],’.’))

Event Number

first(split(last(split(triggerBody()?[‘api_url’],’events/’)),’/’))

Attendee Number

first(split(last(split(triggerBody()?[‘api_url’],’attendees/’)),’/’))

We next initialize the Event Id and Contact Id variables. These variables do not have a value at this point, and they are retrieved from the Common Data Service connector when looking for matching events and attendees.

Eventbrite Integration - Attendee Flow Initialize Variables 2

The next step is to validate the action type and make sure that the action type is Attendee. Since this flow is only called from the webhook directly, we probably can bypass this, but this is still good practice.

Eventbrite Integration - Attendee Flow Condition Validate Action Type is Attendee

The no condition will just terminate the flow, while the yes condition will go through the steps of retrieving the attendee information from Eventbrite, and retrieving any attendees that match the attendee number from CDS. We then call an additional condition action to check for the number of results from the retrieval of contact records from CDS. The flow looks like this:

Eventbrite Integration - Attendee Flow Condition Action Type = Attendee Results

The condition expression to check for the number of results is: length(body(‘Retrieve_contacts_matching_Attendee_Number’)?[‘value’])

The results of this condition will determine if we update the existing Contact record or create a new contact record. The yes condition result will call the Update Contact, while the no condition result will retrieve the eventid, and create a new attendee (contact) record.

Eventbrite Integration - Attendee Flow - Has Attendee = Yes

Eventbrite Integration - Attendee Flow - Has Attendee = No

1 – PREREQUISITES | 2 – EVENTBRITE SETTINGS | 3 – CUSTOM CONNECTOR | 4 – EVENT FLOW | 5 – ATTENDEE FLOW | 6 – TESTING

The post Eventbrite to CDS Integration – Part 5 (Attendee Flow) appeared first on Aric Levin's Digital Transformation Blog.

]]>
Configuring oAuth authentication for CDS http://aric.isite.dev/dynamics/post/configuring-oauth-cds/ Mon, 11 Nov 2019 02:37:00 +0000 https://aric.isite.dev/index.php/2019/11/11/configuring-oauth-authentication-for-cds/ It has been quite some time since Microsoft announced the use of oAuth to connect between Server environments, but many organizations are still using username and password to connect to Dynamics 365 or the Command Data Service (CDS).

The post Configuring oAuth authentication for CDS appeared first on Aric Levin's Digital Transformation Blog.

]]>
It has been quite some time since Microsoft announced the use of oAuth to connect between Server environments, but many organizations are still using username and password to connect to Dynamics 365 or the Command Data Service (CDS).

I recently had to work on a migration project, and while this customer was using legacy credentials to authenticate, they had no problems doing so with all of their environments. After they provisioned a new environment, suddenly they started receiving authentication exceptions from their data migration tool (using Kingswaysoft and SSIS).

When trying different methods of authentications, we received several different errors, but the basic error was Authentication Failed:
Authentication Failed to CDS
George Doubinski from crmtipoftheday.com pointed me out to checking if I was blocked by conditional access. Check his blog post here.
After going through several posts on Microsoft, I set up Server to Server connection using an App Registration and Azure Active Directory. Below are the step by step instructions on how to implement this.
We start by logging in to Azure Active Directory using the Url and logging in with an Azure Admin account below:
The first thing that we want to do is register an Application. We do this by clicking on the Azure Active Directory (1) and then selecting App Registrations (2), and in the App registrations section, click on New Registration (3).
Fill out the registration information by entering the name of the App and selecting Accounts in this organization directory only (Single tenant). You can ignore the Redirect URI for this purpose now.
Azure AD - Register an Application
After you click on the register button, you will see the new registered app in your list of App registrations.
Azure AD - Registered Applications
Click on the hyperlink of the App that you just created. This will navigate you to the properties of the application so that you can configure it. In the App overview page you will see the information about your app which includes the Application (client) ID, Directory (tenant) ID and Object Id as well as additional settings. You will also see a button that says View API permissions under the Call APIs section.
Click on the View API permissions button to allow this new app to delegate to Dynamics 365/CDS.
Azure AD App Registration - Call APIs
In the API permissions section, click on Add a permission to Add a permission to Dynamics 365. By default you will see in that window that there is Read permissions to the Microsoft Graph API.
Azure AD App Registration - Add a permission
This will pop up the Request API permissions area. In there look for Dynamics CRM under the Microsoft APIs. Click on the Dynamics CRM API, to request access to that API.
Azure AD App Registration - Select an API
The Dynamics CRM API will allow you to only choose Delegated permissions, and the only available permission is user_impersonation. Select the user_impersonation check box and click on the Add permissions button.
Azure AD App Registration - Request API permissions
This will bring back the previous screen, but you will not see both the Dynamics CRM and Microsoft Graph permissions on the list. At the bottom of the screen, click on the Grant admin consent. This will ask you if you are sure. Click Yes to finish granting the consent.
Azure AD App Registration - Grant Consent
At this point you will finalize the App permissions. We will not need to provide a Client Secret, as this value is required for Server to Server connectivity.
Click on the Certificates & secrets in the navigation, and in the new area, click on the New client secret button.
Azure AD App Registration - Certificates and secrets
In the Add a client secret popup enter a description and expiration option (1 year, 2 years or never expires). When done, click the Add button
Azure AD App Registration - Add a client secret
The newly created Client secret will be displayed in the Client Secret section, with a copy button. Copy the Client secret, and store in a location where you have access to it. You will not be allowed to copy it again after you navigate away, and you will need it to connect to your environment.
Azure AD App Registration - Client Secret
The next step is to create an application user. This user will be added to Dynamics 365 and will have access to run as an Application User.
Click on the Users link on the left hand side (under Azure Active Directory), and the click on the New User button. You can also click on the User link from within Azure Active Directory if Users is not available under your favorites.
Azure AD - Add New User
In the New user window select the Create User option, and then provide the identity information: Username, Name, First Name, Last Name, and the click on the Create button.
Azure AD - New User Registration
Once you are done adding the user, the new user will appear in the All Users list. You can click on Reset password to change the password for this user.
Azure AD - New User Added
The final step is to add this user to Dynamics 365 (or your CDS environment). Login to your Dynamics 365 environment and navigate to the Users entity, by click on Advanced Settings from the Settings area.
Common Data Service - Advanced Settings
Navigating to Settings -> Security, and click on the Users group.
Common Data Service - Select Users
Change the selected view from Enabled Users to Application Users, and click on the + New button.
Common Data Service - New Application User
The new User: Application User form will open up. Specify the User Name (Email Address from Azure AD), the Application ID, the User Full Name and the Primary Email of the User that you created. When you save the record, the Application ID URI and the Azure AD Object ID should be automatically filled out.
Common Data Service - Newly Added Application User
Finally, once you have completed these steps, you should be able to re-authenticate with Kingswaysoft using oAuth as shown below. You are not going to need to enter user credentials, but just the Client Id, Client Secret and the organization url as shown below.
Kingswaysoft to CDS Server to Server oAuth Connection
Clicking on the Test Connection button will now allow you to Connect to your CDS or Dynamics 365 environment and start moving your data.

The post Configuring oAuth authentication for CDS appeared first on Aric Levin's Digital Transformation Blog.

]]>
Connecting to Dynamics CRM from Console Application – Part II http://aric.isite.dev/dynamics/post/connect-crm-online-console-ii/ Fri, 22 Dec 2017 17:28:00 +0000 https://aric.isite.dev/index.php/2017/12/22/connecting-to-dynamics-crm-from-console-application-part-ii/ In a recent article I explained how to establish a connection from a Console application to Microsoft Dynamics CRM On-Premise. In this post, I will cover the same steps on how to connect a Console application to Microsoft Dynamics CRM/365 Online using the Microsoft.Xrm.Sdk and Microsoft.Xrm.Tooling.Connector namespaces

The post Connecting to Dynamics CRM from Console Application – Part II appeared first on Aric Levin's Digital Transformation Blog.

]]>
In a recent article I explained how to establish a connection from a Console application to Microsoft Dynamics CRM On-Premise. In this post, I will cover the same steps on how to connect a Console application to Microsoft Dynamics CRM/365 Online using the Microsoft.Xrm.Sdk and Microsoft.Xrm.Tooling.Connector namespaces

The first thing that we need is to download the Microsoft Dynamics SDK from the Microsoft web site. Based on your version of CRM (or Dynamics 365), this url, might be different, but you can download the SDK from here. After you download and install the SDK, you will need to add references to the Microsoft.Xrm.Sdk and Microsoft.Xrm.Tooling.Connector assemblies to your Visual Studio Console application. These can be found in the SDKbin directory.

Once the references have been added, add the following lines of code to your namespace declaration in the Program.cs code window:

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Tooling.Connector;

When using the Xrm.Tooling.Connector namespace, we connect to Microsoft Dynamics CRM using the CrmServiceClient, but if you still require or want to use the OrganizationService you can use that after we establish connectivity to Dynamics CRM using the CrmServiceClient. We are going to show how to use the CrmServiceClient to connect using both a connection string, and individual settings.

To connect using a Connection String we will store the connection string in the App.Config file. The connection string will look as such:

  <connectionStrings>
    <add name="Office365"
         connectionString="Url=https://contoso.crm.dynamics.com; Username=crmadmin@contoso.onmicrosoft.com; Password=abcdef1234; authtype=Office365"/>
  </connectionStrings>

After we added the connection string to the App.Config file, we need to add code to our Main method that will establish the connection using the supplied string. We will perform this logic as follows:

string ConnectionString = ConfigurationManager.ConnectionStrings["Office365"].ConnectionString;
CrmServiceClient conn = new Microsoft.Xrm.Tooling.Connector.CrmServiceClient(connectionString);

if (conn.IsReady)
{
   // Perform Additional Actions Here
}

Another way to connect to Microsoft Dynamics CRM using CrmService Client is by providing parameters for credentials, organization url and organization name. The following is the Application Settings section within the App.Config file which we used to store the credentials and connection information. Note that password is not encrypted in the App Settings, but it should be encrypted one way or another. The following shows the AppSettings section in the App.Config file:

  <appSettings>
    <add key="UserName" value="crmadmin@contoso.onmicrosoft.com"/>
    <add key="Password" value="abcdef1234" />
    <add key="InternalUrl" value="contoso.crm.dynamics.com"/>
    <add key="OrgName" value="contosocrm"/>
    <add key="Region" value="NorthAmerica"/>
  </appSettings>

We can then read the application settings from our Program.cs Main function and establish a connection the same way we did with the connection string as follows:

string userName = ConfigurationManager.AppSettings["UserName"].ToString();
string password = ConfigurationManager.AppSettings["Password"].ToString();
string internalUrl = ConfigurationManager.AppSettings["InternalUrl"].ToString();
string orgName = ConfigurationManager.AppSettings["OrgName"].ToString();
string region = ConfigurationManager.AppSettings["Region"].ToString();

// Notice Authentication Type below is set to Office 365
NetworkCredential creds = new NetworkCredential(userName, ConvertToSecureString(password));
Microsoft.Xrm.Tooling.Connector.AuthenticationType authType = Microsoft.Xrm.Tooling.Connector.AuthenticationType.Office365;
CrmServiceClient conn = new Microsoft.Xrm.Tooling.Connector.CrmServiceClient(userName, ConvertToSecureString(password), region, orgName, isOffice365: true);

if (conn.IsReady)
{
   // Perform Additional Actions Here
}

As mentioned in the beginning, we are now able to use the CRMServiceClient class to perform actions against CRM. If we need to use the OrganizationService interface, we can use that as well, by adding the following line of code after setting the CrmServiceClient connection or after checking if the connection is ready as shown here:

IOrganizationService _orgService = (IOrganizationService)conn.OrganizationWebProxyClient != null ? (IOrganizationService)conn.OrganizationWebProxyClient : (IOrganizationService)conn.OrganizationServiceProxy;

At this point you can perform actions against the CRM Organization using either the Organization Service or Crm Service Client. In the next article, we will replicate the same example, but connect to Microsoft Dynamics CRM Online using the same methods.

The post Connecting to Dynamics CRM from Console Application – Part II appeared first on Aric Levin's Digital Transformation Blog.

]]>
Connecting to Dynamics CRM from Console Application – Part I http://aric.isite.dev/dynamics/post/connect-crm-onpremise-console-i/ Fri, 22 Dec 2017 03:14:00 +0000 https://aric.isite.dev/index.php/2017/12/22/connecting-to-dynamics-crm-from-console-application-part-i/ Recently I have seen a lot of posts on the CRM Community of how to establish connection to CRM using a Console application. In this post I will review the steps of establish a connection. I will focus on CRM On-Premise using ADFS/Claims/IFD, and will provide additional samples on connecting to Dynamics CRM Online in a separate blog article.

The post Connecting to Dynamics CRM from Console Application – Part I appeared first on Aric Levin's Digital Transformation Blog.

]]>
Recently I have seen a lot of posts on the CRM Community of how to establish connection to CRM using a Console application. In this post I will review the steps of establish a connection. I will focus on CRM On-Premise using ADFS/Claims/IFD, and will provide additional samples on connecting to Dynamics CRM Online in a separate blog article.

The first thing that we need is to download the Microsoft Dynamics SDK from the Microsoft web site. Based on your version of CRM (or Dynamics 365), this url, might be different, but you can download the SDK from here. After you download and install the SDK, you will need to add references to the Microsoft.Xrm.Sdk and Microsoft.Xrm.Tooling.Connector assemblies to your Visual Studio Console application. These can be found in the SDKbin directory.

Once the references have been added, add the following lines of code to your namespace declaration in the Program.cs code window:

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Tooling.Connector;

When using the Xrm.Tooling.Connector namespace, we connect to Microsoft Dynamics CRM using the CrmServiceClient, but if you still require or want to use the OrganizationService you can use that after we establish connectivity to Dynamics CRM using the CrmServiceClient. We are going to show how to use the CrmServiceClient to connect using both a connection string, and individual settings.

To connect using a Connection String we will store the connection string in the App.Config file. The connection string will look as such:

  <connectionStrings>
    <add name="Server=contoso.com, organization=advworks, user=crmadmin@contoso.local"
         connectionString="Url=https://internal.contoso.com/advworks/XRMServices/2011/Organization.svc; Username=contosocrmadmin; Password=abcdef1234; authtype=IFD"/>
  </connectionStrings>

After we added the connection string to the App.Config file, we need to add code to our Main method that will establish the connection using the supplied string. We will perform this logic as follows:

string connectionString = ConfigurationManager.ConnectionStrings[0].ConnectionString;
CrmServiceClient conn = new Microsoft.Xrm.Tooling.Connector.CrmServiceClient(connectionString);

if (conn.IsReady)
{
   // Perform Additional Actions Here
}

Another way to connect to Microsoft Dynamics CRM using CrmService Client is by providing parameters for credentials, organization url and organization name. The following is the Application Settings section within the App.Config file which we used to store the credentials and connection information. Note that password is not encrypted in the App Settings, but it should be encrypted one way or another. The following shows the AppSettings section in the App.Config file:

  <appSettings>
    <add key="UserName" value="contosocrmadmin"/>
    <add key="Password" value="abcdef1234" />
    <add key="InternalUrl" value="internal.contoso.com"/>
    <add key="OrgName" value="advworks"/>
  </appSettings>

We can then read the application settings from our Program.cs Main function and establish a connection the same way we did with the connection string as follows:

string userName = ConfigurationManager.AppSettings["UserName"].ToString();
string password = ConfigurationManager.AppSettings["Password"].ToString();
string internalUrl = ConfigurationManager.AppSettings["InternalUrl"].ToString();
string orgName = ConfigurationManager.AppSettings["OrgName"].ToString();

NetworkCredential creds = new NetworkCredential(userName, ConvertToSecureString(password));
                Microsoft.Xrm.Tooling.Connector.AuthenticationType authType = Microsoft.Xrm.Tooling.Connector.AuthenticationType.IFD;
CrmServiceClient conn = new Microsoft.Xrm.Tooling.Connector.CrmServiceClient(creds, authType, internalUrl, "443", orgName, true, true, null);

if (conn.IsReady)
{
   // Perform Additional Actions Here
}

As mentioned in the beginning, we are now able to use the CRMServiceClient class to perform actions against CRM. If we need to use the OrganizationService interface, we can use that as well, by adding the following line of code after setting the CrmServiceClient connection or after checking if the connection is ready as shown here:

IOrganizationService _orgService = (IOrganizationService)conn.OrganizationWebProxyClient != null ? (IOrganizationService)conn.OrganizationWebProxyClient : (IOrganizationService)conn.OrganizationServiceProxy;

At this point you can perform actions against the CRM Organization using either the Organization Service or Crm Service Client. In the next article, we will replicate the same example, but connect to Microsoft Dynamics CRM Online using the same methods.

The post Connecting to Dynamics CRM from Console Application – Part I appeared first on Aric Levin's Digital Transformation Blog.

]]>
Choosing CRM Connection Option http://aric.isite.dev/dynamics/post/choosing_crm_connection_option/ Sat, 02 Feb 2013 20:39:00 +0000 https://aric.isite.dev/index.php/2013/02/02/choosing-crm-connection-option/ Many CRM application that are written for Microsoft Dynamics CRM require to authenticate a user with any Microsoft Dynamics CRM deployment. This sample in this article demonstrates how to connect and authenticate a user with Microsoft Dynamics CRM On-Premise or Microsoft Dynamics CRM Online (using both Windows Live Id and Office 365 credentials).

The post Choosing CRM Connection Option appeared first on Aric Levin's Digital Transformation Blog.

]]>
Many CRM application that are written for Microsoft Dynamics CRM require to authenticate a user with any Microsoft Dynamics CRM deployment. This sample in this article demonstrates how to connect and authenticate a user with Microsoft Dynamics CRM On-Premise or Microsoft Dynamics CRM Online (using both Windows Live Id and Office 365 credentials).

The code example below contains three methods.
A public class method that establishes the connection, and two private methods to retrieve the Authentication Credentials and retrieve the Organization Service Proxy.

Many CRM application that are written for Microsoft Dynamics CRM require to atuneticate a user with any Microsoft Dynamics CRM deployment. This sample in this article demonstrates how to connect and authenticate a user with Microsoft Dynamics CRM On-Premise or Microsoft Dynamics CRM Online (using both Windows Live Id and Office 365 credentials).

The code example below contains three methods.
A public class method that establishes the connection, and two private methods to retrieve the Authentication Credentials and retrieve the Organization Service Proxy.

The following is the list of references, variables and properties that are required for this implementation to work.

using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Client.Services;

public static OrganizationServiceProxy service;
private static string UserName { get; set; }

private static string Password { get; set; }

The ConnectToCRM creates a new OrganizationServiceProxy class that allows performing operations against all of the Microsoft Dynamics CRM environments.
The method retrieves the specified credentials and established the OrganizationServiceProxy class connection by calling the GetProxy method.

The serviceUrl contains the Uri of the CRM Services and the provider contains the type of provider that is going to be used to connect to CRM.
There are 5 options for the AuthenticationProviderType: Active Directory (1), Federation (2), Live Id (3), Online Federation (4) and None (0).

public static void ConnectToCRM(Uri serviceUrl, AuthenticationProviderType provider)
{
IServiceManagement<IOrganizationService> orgServiceManagement =
ServiceConfigurationFactory.CreateManagement<IOrganizationService>(serviceUrl);

AuthenticationCredentials credentials = GetCredentials(provider);
service = GetProxy<IOrganizationService, OrganizationServiceProxy>
(orgServiceManagement, credentials);
service.EnableProxyTypes();
}

The GetCredentials method returns an AuthenticationCredentials class contains the credentials of the CRM user based on the environment that they are connecting to. This method shows the implementation for Active Directory, CRM Online using Windows Live Id and CRM Online using Office 365.   

private static AuthenticationCredentials GetCredentials(AuthenticationProviderType provider)
{
AuthenticationCredentials credentials = new AuthenticationCredentials();
switch (provider)
{
case AuthenticationProviderType.ActiveDirectory: // Active Directory
credentials.ClientCredentials.Windows.ClientCredential =
new NetworkCredential(UserName, Password);
break;
case AuthenticationProviderType.LiveId: // CRM Online using Live Id             
credentials.ClientCredentials.UserName.UserName = UserName;

credentials.ClientCredentials.UserName.Password = Password;
credentials.SupportingCredentials = new AuthenticationCredentials();
credentials.SupportingCredentials.ClientCredentials =

Microsoft.Crm.Services.Utility.DeviceIdManager.LoadOrRegisterDevice();

         break;
case AuthenticationProviderType.OnlineFederation: // CRM Online using Office 365
credentials.ClientCredentials.UserName.UserName = UserName;
credentials.ClientCredentials.UserName.Password = Password;
break;
default:
credentials.ClientCredentials.UserName.UserName = UserName;
credentials.ClientCredentials.UserName.Password = Password;
break;
   }
   return credentials;
}

The following is a generic method that is used to obtain the discovery and organization service proxy.
The TService parameter is used to set the IDiscoveryService or IOrganizationService type to request the resepective service proxy instance.
The method will finally return either the DiscoveryServiceProxy or the OrganizationServiceProxy based on the TService type.

private static TProxy GetProxy<TService, TProxy>
(IServiceManagement<TService> serviceManagement,
AuthenticationCredentials authCredentials)
where TService : class           
where TProxy : ServiceProxy<TService>
{
Type classType = typeof(TProxy);
// Obtain service proxy for Windows LiveId and Office 365 environments.
if (serviceManagement.AuthenticationType != AuthenticationProviderType.ActiveDirectory)
{
AuthenticationCredentials tokenCredentials = serviceManagement.Authenticate(authCredentials);
return (TProxy)classType
.GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(SecurityTokenResponse) })
.Invoke(new object[] { serviceManagement, tokenCredentials.SecurityTokenResponse });
   }

// Obtain service proxy for ActiveDirectory environment.
return (TProxy)classType
.GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(ClientCredentials) })
.Invoke(new object[] { serviceManagement, authCredentials.ClientCredentials });
}

Once the connection to Microsoft Dynamics CRM is established, you can call any of the CRM WCF Service methods calls.
This example was created using the CRM 2011 SDK version 5.0.13 (published 1/7/2013).

The post Choosing CRM Connection Option appeared first on Aric Levin's Digital Transformation Blog.

]]>