Nav

Microsoft Dynamics 365 Connector

Select

The Microsoft Dynamics 365 connector for Anypoint platform enables integration with Microsoft Dynamics 365 Web API.

This connector lets you perform operations to:

  • Authorize or unauthorize server access.

  • Create, update, and delete entities.

  • Retrieve a single entity or query multiple entities.

  • Associate and disassociate entities.

  • Execute actions.

Prerequisites

This document assumes that you are familiar with Mule, Anypoint Connectors, Anypoint Studio essentials, elements in a Mule flow, and global elements.

Obtain a client ID and secret for your app by logging into the Microsoft Azure Active Directory portal at portal.azure.com.

Before starting:

  • You need access to a Microsoft Dynamics 365 instance (online or on-premise) leveraged by Azure Active Directory; that is, Azure Active Directory is the Identity Provider that provides access to an application.

About Connector Terminology

  • Actions - Operations that allow side effects, such as data modification, and cannot be further composed to avoid non-deterministic behavior.

  • Complex types - Keyless named structured types consisting of a set of properties. Complex types are commonly used as property values in model entities, or as parameters or return values for operations.

  • Entities - Instances of entity types, for example, an account or an opportunity.

  • Entity sets - Named collections of entities, for example, an account is an entity set containing account entities. An entity’s key uniquely identifies the entity within an entity set.

  • Entity types - Named structured types with a key. Entity types define the named properties and relationships of an entity, and may derive by single inheritance from other entity types.

  • Enumeration types or Enum types - Named primitive types whose values are named constants with underlying integer values.

  • Functions - Operations that do not have side effects and may support further composition, for example, with additional filter operations, functions or an action.

To Install and Configure the Connector

  1. In Anypoint Studio, click the Exchange icon in the Studio taskbar.

  2. Click Login in Anypoint Exchange.

  3. Search for the connector and click Install.

  4. Follow the prompts to install the connector.

When Studio has an update, a message displays in the lower right corner, which you can click to install the update.

To Create a New Mule Project Using the Anypoint Studio Visual Editor

  1. In Anypoint Studio, click File > New > Mule Project.

  2. Specify a Project Name and click Finish.

  3. Search for "http" and drag the HTTP connector to the canvas. Click the green plus sign next to Connector Configuration, and click OK in the menu to accept the default values.

  4. Search for "365" and drag the Microsoft Dynamics 365 connector to the canvas. Click the green plus next to Connector Configuration, and specify your access credentials.

  5. Click a connection strategy for authentication:

    • Microsoft Dynamics 365 OAuth 2.0 Connection

    • Microsoft Dynamics 365 OAuth 2.0 Username-Password

To Configure OAuth 2.0 Connection

This configuration provides access to the Microsoft Dynamics 365 Web API.

To Configure OAuth 2.0 Username-Password

  1. Click the green plus sign to the right of Connector Configuration.

  2. Provide the following credentials to enable access to your Microsoft Dynamics 365 server:

    • Under General tab

      • Client ID - The application ID assigned to your app when you registered it with Azure Active Directory. You can find this in the Azure Portal. Click Active Directory, click the directory, choose the application, and click Configure.

      • Client Secret - The application secret that you created in the app registration portal for your app. This should not be used in a native app, because client secrets cannot be reliably stored on devices. This is required for web apps and web APIs, which have the ability to store the client secret securely on the server side.

      • Username - Username used to initialize the session.

      • Password - Password used to authenticate the user.

      • Resource - The application ID URI of the web API (secured resource). This must be the root URI, without specifing the CRM version. Example: https://YOUR_ORG.crm.dynamics.com/

      • Token Request Endpoint - The token endpoint that is called to get the access token. Example: https://login.windows.net/TENANT_ID/oauth2/token where TENANT_ID is the Azure Active Directory ID.

    • Under Advanced tab

      • Read Timeout - The duration in milliseconds that the consumer waits for a response before timing out. Zero (0) means wait forever.

      • Connection Timeout - Specifies the duration in milliseconds that the consumer tries to establish a connection before timing out. Zero (0) means wait forever.

  3. Click Test Connection to ensure that your credentials are accepted at the server endpoint.

  4. If present, click Enable DataSense to let your application acquire metadata from the server.

To Run a Flow

  1. In Package Explorer, right click your project’s name, and click Run As > Mule Application.

  2. Check the console to see when the application starts. You should see messages such as these if no errors occur:


         
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
************************************************************
INFO  2017-05-14 22:12:42,003 [main] org.mule.module.launcher.DeploymentDirectoryWatcher:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Mule is up and kicking (every 5000ms)                    +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
INFO  2017-05-14 22:12:42,006 [main] org.mule.module.launcher.StartupSummaryDeploymentListener:
**********************************************************
*  - - + DOMAIN + - -               * - - + STATUS + - - *
**********************************************************
* default                           * DEPLOYED           *
**********************************************************

************************************************************************
* - - + APPLICATION + - -   * - - + DOMAIN + - -  * - - + STATUS + - - *
************************************************************************
* myapp                     * default             * DEPLOYED           *
************************************************************************

Example: Microsoft Dynamics 365

This example demonstrates the use of Microsft Dynamics 365 Connector.

To build and run this demo project, you need:

  • Anypoint Studio with at least the Mule 4.0 Runtime.

  • Microsft Dynamics 365 Connector v2.0.0 or higher.

  • Dynamics 365 leveraged by Azure Active Directory.

To Test the Flow

  1. Import the demo project into your workspace using Anypoint Exchange or using the Import command in the File menu.

  2. Specify your OAuth 2 credentials for OAuth 2 Username-Password configuration in the /src/main/app/mule-app.properties file:

    • dynamics365.username - Username used to initialize the session.

    • dynamics365.password - Password used to authenticate the user.

    • dynamics365.resource - The App ID URI of the web API, which is a secured resource. The resource must be a root URI that does not specify the CRM version. Example: https://YOUR_ORG.crm.dynamics.com/

    • dynamics365.clientId - The application ID assigned to your app when you registered it with Azure Active Directory. You can find this in the Azure Portal. Click Active Directory, click the directory, choose the application, and click Configure.

    • dynamics365.clientSecret - The application secret that you created in the app registration portal for your app. This should not be used in a native app, because a client secret cannot be reliably stored on a device. The client secret is required for web apps and web APIs, which have the ability to store the client secret securely on the server side.

    • dynamics365.tokenRequestEndpoint - The token endpoint to call to get an access token.
      Example: +https://login.windows.net/TENANT_ID/oauth2/token where TENANT_ID is the Azure Active Directory ID.

  3. Run the project in Studio.

  4. Type localhost:8081 in your browser to access the selection menu of the demo.

  5. Optionally you can configure the Connection Timeout and Read Timeout. The Connection Timeout is the timeout in making the initial connection with the server. The Read Timeout is the timeout on waiting to read data from the server.

You can use the selection menu from http://localhost:8081 to test the flows or you can POST JSONs using a tool like curl, or any other tool (Chrome/Mozilla Firefox extensions) that lets you POST a body when calling the URL.

Example XML Flow


          
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
<?xml version="1.0"?>

<mule xmlns:dynamics="http://www.mulesoft.org/schema/mule/dynamics"
        xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core"
        xmlns:http="http://www.mulesoft.org/schema/mule/http"
        xmlns="http://www.mulesoft.org/schema/mule/core"
        xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd
http://www.mulesoft.org/schema/mule/dynamics http://www.mulesoft.org/schema/mule/dynamics/current/mule-dynamics.xsd">

        <configuration-properties file="mule-artifact.properties" />
        <http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" doc:id="2e53345d-33af-42cc-9c35-737ef41266e4" >
                <http:listener-connection host="0.0.0.0" port="8081" />
        </http:listener-config>
        <dynamics:dynamics-config name="Dynamics_365_config" doc:name="Dynamics 365 Dynamics 365" doc:id="823ca5ed-f274-47d7-a054-25d8a8da3eb5" >
                <dynamics:oauth-user-pass-connection username="${config-oauth-user-pass.username}" password="${config-oauth-user-pass.password}"
                        resource="${config-oauth-user-pass.resource}" clientId="${config-oauth-user-pass.clientId}"
                        clientSecret="${config-oauth-user-pass.clientSecret}" tokenRequestEndpoint="${config-oauth-user-pass.tokenRequestEndpoint}" />
        </dynamics:dynamics-config>
        <flow name="PARSE_DEMO_TEMPLATE">
        <http:listener config-ref="HTTP_Listener_config" doc:name="HTTP" path="/"/>
        <parse-template location="form.html" doc:name="Parse Template"/>
    </flow>
    <flow name="CREATE_EMPTY_CONTACT_DEMO">
        <http:listener config-ref="HTTP_Listener_config" path="/createContact" doc:name="HTTP"/>
        <logger message="Requested 'Create Contact Operation'" level="INFO" doc:name="Logger"/>
                <dynamics:create config-ref="Dynamics_365_config" logicalName="contact" doc:name="Microsoft Dynamics 365">
                        <dynamics:attributes ><![CDATA[#[{}]]]></dynamics:attributes>
                </dynamics:create>

        <logger message="#['Received Response from &quot;Create Contact Operation&quot;:' ++ payload]" level="INFO" doc:name="Logger"/>
    </flow>
    <flow name="CREATE_EMPTY_OPPORTUNITY_DEMO">
        <http:listener config-ref="HTTP_Listener_config" path="/createOpportunity" doc:name="HTTP"/>
        <logger message="Requested 'Create Opportunity Operation'" level="INFO" doc:name="Logger"/>
                <dynamics:create config-ref="Dynamics_365_config" logicalName="opportunity" doc:name="Microsoft Dynamics 365">
                        <dynamics:attributes ><![CDATA[#[{}]]]></dynamics:attributes>
                </dynamics:create>
        <logger message="#['Received Response from &quot;Create Opportunity Operation&quot;: ' ++ payload]" level="INFO" doc:name="Logger"/>
    </flow>
    <flow name="CREATE_ACCOUNT_DEMO">
        <http:listener config-ref="HTTP_Listener_config" path="/createAccount" doc:name="HTTP"/>
        <logger message="Requested 'Create Account Operation'" level="INFO" doc:name="Logger"/>
        <ee:transform doc:name="Transform Message">
            <ee:message>
                    <ee:set-payload>
            <![CDATA[%dw 2.0
output application/java
---
{
        name: payload.AccountName,
        creditonhold: payload.CreditOnHold,
        creditlimit: payload.CreditLimit,
        "primarycontactid@odata.bind": "/contacts(" ++ payload.ContactID ++ ")"
}]]></ee:set-payload>
                        </ee:message>
                </ee:transform>
        <dynamics:create config-ref="Dynamics_365_config" logicalName="account" doc:name="Microsoft Dynamics 365">
            <dynamics:attributes>#[payload]</dynamics:attributes>
        </dynamics:create>
        <logger message="#['Received Response from &quot;Create Account Operation&quot; : ' ++ payload]" level="INFO" doc:name="Logger"/>
    </flow>
    <flow name="CREATE_MULTIPLE_ENTITIES_DEMO">
        <http:listener config-ref="HTTP_Listener_config" path="/createMultipleAccounts" doc:name="HTTP"/>
        <logger message="Requested 'Create Multiple Accounts Operation'" level="INFO" doc:name="Logger"/>
        <ee:transform doc:name="Transform Message">
            <ee:message>
                    <ee:set-payload><![CDATA[%dw 2.0
input payload application/json
output application/java
---
payload map {
      name: $.AccountName,
      creditlimit : $.CreditLimit,
      creditonhold : $.CreditOnHold
}]]></ee:set-payload>
                        </ee:message>
        </ee:transform>
        <dynamics:create-multiple config-ref="Dynamics_365_config" logicalName="account" doc:name="Microsoft Dynamics 365">
            <dynamics:entities-attributes>#[payload]</dynamics:entities-attributes>
        </dynamics:create-multiple>
        <logger message="Received Response from 'Create Multiple Entities Operation'" level="INFO" doc:name="Logger"/>
        <ee:transform doc:name="Response to JSON" doc:id="5be799cf-e01a-416b-a3bb-084f945f9da8" >
                        <ee:message >
                                <ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
payload]]></ee:set-payload>
                        </ee:message>
                </ee:transform>
    </flow>
    <flow name="UPDATE_ENTITY_DEMO">
        <http:listener config-ref="HTTP_Listener_config" path="/updateAccount" doc:name="HTTP"/>
        <logger message="Requested 'Update Entity Operation'" level="INFO" doc:name="Logger"/>
        <ee:transform doc:name="Transform Message">
            <ee:message>
                    <ee:set-payload><![CDATA[%dw 2.0
output application/java
---
{
        entityId: payload.EntityId,
        attributes: {
                creditlimit: payload.CreditLimit,
                name: payload.AccountName
        }
}]]></ee:set-payload>
                        </ee:message>
        </ee:transform>
        <dynamics:update config-ref="Dynamics_365_config" logicalName="account" doc:name="Microsoft Dynamics 365">
            <dynamics:attributes>#[payload]</dynamics:attributes>
        </dynamics:update>
        <logger message="'Update Entity Operation' has ended with success" level="INFO" doc:name="Logger"/>
        <ee:transform doc:name="Response to JSON" doc:id="9d1bc853-e9eb-4c4a-a323-f9b171583c76" >
                        <ee:message >
                                <ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
payload]]></ee:set-payload>
                        </ee:message>
                </ee:transform>
    </flow>
    <flow name="UPDATE_MULTIPLE_ENTITIES_DEMO">
        <http:listener config-ref="HTTP_Listener_config" path="/updateMultipleAccounts" doc:name="HTTP"/>
        <logger message="Requested 'Update Multiple Entities Operation'" level="INFO" doc:name="Logger"/>
        <ee:transform doc:name="Transform Message">
            <ee:message>
                    <ee:set-payload><![CDATA[%dw 2.0
input payload application/json
output application/java
---
payload map {
        entityId: $.EntityId,
        attributes: {
                name: $.AccountName
        }
}]]></ee:set-payload>
                        </ee:message>
        </ee:transform>
        <dynamics:update-multiple config-ref="Dynamics_365_config" logicalName="account" doc:name="Microsoft Dynamics 365">
            <dynamics:entities-attributes>#[payload]</dynamics:entities-attributes>
        </dynamics:update-multiple>
        <logger message="Received Response from 'Update Multiple Entities Operation'" level="INFO" doc:name="Logger"/>
        <ee:transform doc:name="Response to JSON" doc:id="b8d51b91-b280-42b4-8ed4-43004fd94afb" >
                        <ee:message >
                                <ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
payload]]></ee:set-payload>
                        </ee:message>
                </ee:transform>
    </flow>
    <flow name="DELETE_ENTITY_DEMO">
        <http:listener config-ref="HTTP_Listener_config" path="/deleteAccount" doc:name="HTTP"/>
        <logger message="Requested 'Delete Entitiy Operation'" level="INFO" doc:name="Logger"/>
        <dynamics:delete config-ref="Dynamics_365_config" logicalName="account" doc:name="Microsoft Dynamics 365">
                        <dynamics:id>#[payload.EntityId]</dynamics:id>
                </dynamics:delete>
        <logger message="'Delete Entity Operation' has ended with success" level="INFO" doc:name="Logger"/>
    </flow>
    <flow name="RETRIEVE_ENTITY_DEMO">
        <http:listener config-ref="HTTP_Listener_config" path="/retrieveAccount" doc:name="HTTP"/>
        <logger message="Requested 'Retrieve Entitiy Operation'" level="INFO" doc:name="Logger"/>
        <dynamics:retrieve config-ref="Dynamics_365_config" logicalName="account" doc:name="Microsoft Dynamics 365">
                        <dynamics:id>#[payload.EntityId]</dynamics:id>
                </dynamics:retrieve>
        <logger message="Received Response from 'Retrieve Entitiy Operation'" level="INFO" doc:name="Logger"/>
        <ee:transform doc:name="Response to JSON" doc:id="3da385b1-b9fe-4f25-b8b0-a0e0521cc0cf" >
                        <ee:message >
                                <ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
payload]]></ee:set-payload>
                        </ee:message>
                </ee:transform>
    </flow>
    <flow name="RETRIEVE_ENTITIES_BY_URL_DEMO">
        <http:listener config-ref="HTTP_Listener_config" path="/retrieveAccountsByURL" doc:name="HTTP"/>
        <logger message="Requested 'Retrieve Multiple Operation'" level="INFO" doc:name="Logger"/>
        <dynamics:retrieve-multiple config-ref="Dynamics_365_config" doc:name="Microsoft Dynamics 365">
                <dynamics:data-query-url>${config-oauth-user-pass.resource}/api/data/v8.2/accounts?$select=name,accountnumber&amp;$top=3</dynamics:data-query-url>
        </dynamics:retrieve-multiple>

        <logger message="Received Response from 'Retrieve Multiple Operation'" level="INFO" doc:name="Logger"/>
        <ee:transform doc:name="Response to JSON" doc:id="708cf0f5-14e5-47d9-9e2a-0e8c656898e6" >
                        <ee:message >
                                <ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
payload]]></ee:set-payload>
                        </ee:message>
                </ee:transform>
    </flow>
    <flow name="RETRIEVE_ENTITIES_BY_QUERY_DEMO">
        <http:listener config-ref="HTTP_Listener_config" path="/retrieveAccountsByQuery" doc:name="HTTP"/>
        <logger message="Requested 'Retrieve Multiple By Query Operation'" level="INFO" doc:name="Logger"/>
        <dynamics:retrieve-multiple-by-query config-ref="Dynamics_365_config" doc:name="Microsoft Dynamics 365">
                <dynamics:query>dsql:SELECT accountid,accountnumber,name FROM accounts LIMIT 2</dynamics:query>
        </dynamics:retrieve-multiple-by-query>

        <logger message="Received Response from 'Retrieve Multiple By Query Operation'" level="INFO" doc:name="Logger"/>
                <ee:transform doc:name="Response to JSON" doc:id="c6d79b71-1667-44b9-b39b-7a4ce2c6638d">
                        <ee:message>
                                <ee:set-payload><![CDATA[%dw 2.0
output application/json
---
payload]]></ee:set-payload>
                        </ee:message>
                </ee:transform>
    </flow>
    <flow name="DISASSOCIATE_ENTITIES_DEMO">
        <http:listener config-ref="HTTP_Listener_config" path="/disassociateEntities" doc:name="HTTP"/>
        <logger level="INFO" doc:name="Logger" message="Requested 'Dissasociate Entities Operation'"/>
        <ee:transform doc:name="Transform Message">
            <ee:message>
                    <ee:set-payload><![CDATA[%dw 2.0
output application/java
---
{
        entityId: payload.EntityId,
        attributes: payload.EntityLinkKeys
}]]></ee:set-payload>
                        </ee:message>
        </ee:transform>
        <dynamics:disassociate config-ref="Dynamics_365_config" logicalName="account" doc:name="Microsoft Dynamics 365">
            <dynamics:attributes>#[payload]</dynamics:attributes>
        </dynamics:disassociate>
        <logger level="INFO" doc:name="Logger" message="Finished 'Dissasociate Entities Operation' with success"/>
    </flow>
    <flow name="DO_ACTION_DEMO">
        <http:listener config-ref="HTTP_Listener_config" path="/doAction" doc:name="HTTP"/>
        <logger message="Requested 'Do Action Operation'" level="INFO" doc:name="Logger"/>

                <ee:transform doc:name="Transform Message">
            <ee:message>
                    <ee:set-payload><![CDATA[%dw 2.0
output application/java
---
{
        OpportunityClose: {
                subject: payload.Subject,
                "opportunityid@odata.bind": "/opportunities(" ++ payload.OpportunityId ++ ")"
        },
        Status: payload.Status
}]]></ee:set-payload>
                        </ee:message>
        </ee:transform>
        <dynamics:do-action config-ref="Dynamics_365_config" actionName="WinOpportunity" doc:name="Microsoft Dynamics 365"/>
        <logger message="Finished 'Do Action Operation'" level="INFO" doc:name="Logger"/>
    </flow>
</mule>