APDevFundamentals Studentmanual
APDevFundamentals Studentmanual
Development:
Fundamentals
Student Manual
1
Table of Contents
2
PART 2: BUILDING APPLICATIONS WITH ANYPOINT STUDIO ................................. 195
MODULE 6: ACCESSING AND MODIFYING MULE MESSAGES ................................... 196
Walkthrough 6-1: Set and log message data .................................................................................... 197
Walkthrough 6-2: Debug a Mule application ..................................................................................... 201
Walkthrough 6-3: Read and write message properties using MEL expressions .............................. 207
Walkthrough 6-4: Read and write variables ...................................................................................... 210
3
Walkthrough 11-5: Coerce and format strings, numbers, and dates ................................................ 367
Walkthrough 11-6: Use DataWeave operators ................................................................................. 375
Walkthrough 11-7: Define and use custom data types ..................................................................... 379
Walkthrough 11-8: Call MEL functions and other flows .................................................................... 382
4
Introducing the Course
Objectives:
5
Walkthrough: Set up your computer for class
In this walkthrough, you make sure your computer is set up correctly so you can complete the class
exercises. You will:
• Download the course files from the MuleSoft Training Learning Management System.
• Make sure you have JDK 1.8 and that it is included in your PATH environment variable.
• Make sure Anypoint Studio starts successfully.
• Install Postman (if you did not already).
• Make sure you have an active Anypoint Platform account.
• Make sure you have a Salesforce developer account and an API security token.
3. Log in to your MuleSoft training account using the email that was used to register you for class.
Note: If you have never logged in before and do not have a password, click the Forgot your
password link, follow the instructions to obtain a password, and then log in.
Note: If you do not see your event, locate the Current and Completed buttons under the My
Learning tab, click the Completed button, and look for your event here.
6
5. Click the event's View Details button.
6. Locate the list of course materials on the right side of the page.
Note: Keep this file open. You will copy and paste text from it during class.
java –version
7
14. Look at the output and check if you have Java 1.8.
Note: If you have an older version of the JDK installed or have no version at all, go to
http://www.oracle.com/technetwork/java/javase/downloads/index.html and download the correct
version of JDK 1.8 for your operating system. Install and then confirm with java -version in a
command-line interface again.
• Mac: $PATH
• Windows: %PATH%
16. After installing the correct JDK version, add or update an environment variable named
JAVA_HOME that points to the installation location and then add JAVA_HOME/bin to your
PATH environment variable.
Note: For instructions on how to set or change environment variables, see the following
instructions for PATH: http://docs.oracle.com/javase/tutorial/essential/environment/paths.html.
Note: If you do not have Anypoint Studio, you can download it from
https://www.mulesoft.com/lp/dl/studio.
18. In the Workspace Launcher dialog box, look at the location of the default workspace; change
the workspace location if you want.
19. Click OK to select the workspace; Anypoint Studio should open.
Note: If you cannot successfully start Anypoint Studio, make sure the JDK and Anypoint Studio
are BOTH 64-bit or BOTH 32-bit and that you have enough available memory (at least 4GB
available) to run Anypoint Studio.
8
20. If you get a Welcome Page, click the X on the tab to close it.
21. If you get an Updates Available pop-up in the lower-right corner of the application, click it and
install the available updates.
Open Postman
22. Open Postman.
Note: If you do not have Postman or another REST API client installed, download Postman now
from https://www.getpostman.com and install it.
Note: You can use a trial account or your company account (if you already have one). If you do
not have an account, sign up for a free, 30-day trial account now.
9
25. Click the menu button located in the upper-left in the main menu bar.
Note: This will be called the main menu from now on.
27. In the left-side navigation, click the Runtime Manager link under Subscription.
28. Check your subscription level and if it is a trial account, make sure it is not expired.
Note: If your trial is expired or will expire during class, sign out and then sign up for a new trial
account now.
10
Make sure you have a Salesforce developer account and an API security token
29. In the same or another web browser tab, navigate to http://salesforce.com and log in.
Note: If you did not sign up for a free developer account yet, go to
http://developer.salesforce.com/ and sign up for one now. You will want to use a free developer
account and not your company account (if you already have one) for class. You will use the API
to add new fictitious accounts to it and will probably not want to add those to your real data.
30. In Salesforce, click your name at the top of the screen and select My Settings.
31. In the left-side navigation, select Personal > Reset My Security Token.
32. If you did not already request a security token, click the Reset Security Token button.
Note: A security token will be sent to your email in a few minutes. You will need this token to
make API calls to Salesforce from your Mule applications.
11
PART 1: Building Application
Networks with Anypoint
Platform
• Describe and explain the benefits of application networks & API-led connectivity.
• Use Anypoint Platform as a central repository for the discovery and reuse of assets.
• Use Anypoint Platform to build applications to consume assets and connect systems.
• Use Anypoint Platform to take an API through its complete development lifecycle.
12
Module 1: Introducing Application
Networks and API-Led
Connectivity
13
Walkthrough 1-1: Explore an API directory and an API reference
In this walkthrough, you make calls to a RESTful API. You will:
14
3. Browse the list of popular APIs.
Note: If Twitter is no longer displayed on the main page, search for it.
15
5. In the Specs section, click the API Portal / Home Page link.
6. In the new browser tab that opens, click Tweets in the left-side navigation.
7. In the left-side navigation, click Post, retrieve and engage with Tweets.
16
10. Review the information for POST statuses/update including parameters, example request, and
example response.
17
Walkthrough 1-2: Make calls to an API
In this walkthrough, you make calls to a RESTful API. You will:
18
6. Click the Send button; you should get a response.
7. Locate and click the return HTTP status code of 200.
8. Review the response body containing flights to SFO, LAX, and CLE.
19
12. Click the X next to the parameter to delete it.
13. Change the request URL to use a uri parameter to retrieve the flight with an ID of 3:
http://training-american-ws.cloudhub.io/api/flights/3
14. Click the Send button; you should see only the flight with that ID returned.
Note: The database is not actually modified so that its data integrity can be retained for class.
20
18. Click the Send button; you should get a 405 response with a message of method not allowed.
21
27. Return to Postman and paste the code in the body text area.
28. Click the Send button; you should see a 201 response with the message Flight added (but not
really).
29. Return to the request body and remove the plane field and value from the request body.
30. Remove the comma after the emptySeats key/value pair.
31. Send the request; the message should still post successfully.
22
32. In the request body, remove the emptySeats key/value pair.
33. Delete the comma after the destination key/value pair.
34. Send the request; you should see a 400 response with the message Bad request.
23
39. Send the request; you should see the response Flight updated (but not really).
Note: The -ws in the URL has been changed to -api and the /api removed.
42. Click the Send button; you should get a message about a missing client_id.
43. Return to the course snippets.txt file and copy the value for the American Flights API client_id.
44. Return to Postman and add a request parameter called client_id.
45. Set client_id to the value you copied from the snippets.txt file.
46. Return to the course snippets.txt file and copy the value for the American Flights API
client_secret.
47. Return to Postman and add a request parameter called client_secret.
24
48. Set client_secret to the value you copied from the snippets.txt file.
49. Click the Send button; you should get data for flight 3 again.
Note: The API service level agreement (SLA) for the application with this client ID and secret
has been set to allow three API calls per minute.
50. Click the Send button three more times; you should get a 429 response and an API calls
exceeded message.
Note: The API service level agreement (SLA) for the application with this client ID and secret
has been set to allow three API calls per minute.
25
Module 2: Introducing Anypoint
Platform
26
Walkthrough 2-1: Explore Anypoint Platform and Anypoint
Exchange
In this walkthrough, you get familiar with the Anypoint Platform web application. You will:
Note: If you closed the browser window or logged out, return to https://anypoint.mulesoft.com
and log in.
2. Click the menu button located in the upper-left in the main menu bar.
27
3. In the menu that appears, select Anypoint Platform; this will return you to the home page.
Note: This will be called the main menu from now on.
28
10. In the left-side navigation, click MuleSoft; you should see all the content in the public Exchange.
11. In the left-side navigation, click the name of your organization beneath MuleSoft (Training in the
screenshots); you should now see only the content in your private Exchange, which is currently
empty.
29
14. Click one of the connectors and review its information.
15. In the left-side navigation, click the Assets list link.
16. Select the Salesforce connector (or search for it if it is not shown) and review its details.
30
Discover and review the API portal for the Training: American Flights API
21. Locate and click the Training: American Flights API.
23. In the left-side navigation, expand and review the list of available resources.
24. Click the GET link for the /flights resource.
31
25. On the /flights: Get all flights page, review the information for the optional query parameter.
26. Scroll down and locate the type and details for the data returned from a call.
32
27. Select the Examples tab; you should see an example response.
Use the API console to make calls to the Training: American Flights API
28. Scroll up and locate the API console on the right-side on the page.
29. Select to show optional query parameters and select a value.
30. Select a destination and click Send; you should get the example data returned using the
mocking service.
31. In the API console, change the API instance from Mocking Service to RAML Base URI.
33
32. Click Send again; you should get results from the actual API implementation for the destination
you selected.
34
Walkthrough 2-2: Create a Mule application with flow designer
In this walkthrough, you build, run, and test a basic Mule application with flow designer. You will:
4. In the New Mule Application dialog box, set the project name to American Flights App.
35
5. Click Create; flow designer should open.
8. In the Design Center project list, click the row containing the American Flights App; you should
see information about the project displayed on the right side of the page.
36
9. Click the Open button or click the American Flights App link in the project list; the project should
open in flow designer.
37
14. In the Trigger card, select HTTP Listener.
15. In the HTTP Listener dialog box, set the path to flights.
16. Click the Edit link for the CloudHub HTTP configuration.
17. In the HTTP Listener Configuration dialog box, review the information and click Cancel.
38
18. In the HTTP Listener dialog box, click the close button in the upper-right corner.
Add a Logger
19. Click the add button next to the HTTP Listener card.
39
21. In the Logger dialog box, set the message to test.
25. Locate the application status in the main menu bar; it should say Ready to deploy.
40
26. Look at the generated URL for the application.
Note: The application name is appended with a four-letter suffix to guarantee that it is unique
across all applications on CloudHub.
Note: If your application fails to deploy, look at the messages in the Logs panel. If there is no
message about incorrect syntax, try restarting the workspace by clicking the options menu in the
application status area and selecting Restart workspace.
29. Click the options menu in the application status area and select Copy link.
31. Add /flights to the path and click Send; you should get a 200 response with no body.
41
32. Click Send again to make a second request.
33. Return to flow designer.
34. Notice that there are now green lines across both cards.
35. Look at the logs; you should see your Logger message displayed twice.
42
37. In the new browser tab that opens with Runtime Manager, review the application log file; you
should see your test log messages.
43
Walkthrough 2-3: Create an integration application with flow
designer that consumes an API
In this walkthrough, you build an integration application to consume an API from Anypoint Exchange.
You will:
44
6. Locate your two calls to the application in the History panel; there should be no message
payload for either call.
7. Change the Show drop-down menu to Attributes.
8. Review the attributes for the Mule event leaving the HTTP Listener processor.
13. Click the Output tab and review the payload and attributes values for the calls.
45
Delete a card
14. Click the Remove button at the top of the card.
Use the American Flights API in Anypoint Exchange to get all flights
15. Click the Add button next to the HTTP Listener card.
16. In the Select a component dialog box, select the American Flights API.
17. In the American Flights API > Select an operation dialog box, select Get All Flights.
46
18. In the Get All Flights dialog box, click the Edit link for the American Flights API configuration.
47
Test the application
22. Return to Postman and click Send; you should see flight data.
48
Add and configure a component to transform the data
28. Click the add button in the flow.
29. In the Select a component dialog box, select Transform.
30. In the Transform card, look at the Mule event structure in the input section.
31. In the output section, click the Create new Data Type button.
49
32. In the New Type dialog box, set the following values:
• Name: Flights
• Format: JSON
• Type: From example
33. In the computer's file explorer, return to the student files folder and locate the flights-
example.json file in the examples folder.
34. Open the file in a text editor and copy the code.
35. Return to flow designer and paste the code in the section to add your JSON example.
50
37. In the input section, expand the plane object.
51
Create the transformation
38. Map fields with the same names by dragging them from the input section and dropping them on
the corresponding field in the output section.
• price to price
• departureDate to departureDate
• plane > totalSeats to totalSeats
• emptySeats to emptySeats
52
39. Map fields with different names by dragging them from the input section and dropping them on
the corresponding field in the output section.
40. In the output section, click the options menu for the airline field and select Set Expression.
53
41. Change the value from null to "american" and click OK.
42. Click the Script tab at the bottom of the card; you should see the DataWeave expression for the
transformation.
Note: You learn to write DataWeave 1.0 expressions later in this course. You can also learn to
write DataWeave expressions in the Flow Design course and the DataWeave course.
54
45. Open the file in a text editor and copy the code.
46. Return to flow designer and paste the code in the sample data for payload section.
47. Look at the preview section, you should see a sample response for the transformation.
48. Close the card.
55
Locate the data type and configuration definitions
49. Locate the connector configurations and the new Flight data type in the project explorer.
56
54. Select the row with your application; you should see information about the application displayed
on the right side of the window.
55. Click the drop-down menu button next to Started and select Stop; the status should change to
Undeployed.
Note: You can deploy it again from flow designer when or if you work on the application again.
57
Module 3: Designing APIs
58
Walkthrough 3-1: Use API designer to define an API with RAML
In this walkthrough, you create an API definition with RAML using API designer. You will:
3. In the New API Specification dialog box, set the project name to American Flights API.
59
4. Select Start with API designer and click Create; API designer should open.
5. In API designer, review the three sections of API designer: the file browser, the editor, and the
API console.
60
View the API console
8. Look at the API console on the right side of the window; you should see summary information
for the API.
Note: If you do not see the API console, click the arrow located in the upper-right of the right
edge of the web browser window.
Note: If you don’t see the API designer shelf, it is either minimized or there is an error in your
code. To check if it is minimized, go to the bottom of the web browser window and look for an
arrow. If you see the arrow, click it to display the shelf.
10. Indent by pressing the Tab key; the contents in the API designer shelf should change.
61
12. Look at the API console; you should see a GET method for the flights resource.
13. In the editor, backspace so you are indented the same amount as the get method.
14. Click the post method in the shelf.
15. Look at the API console; you should see GET and POST methods for the flights resource.
/{ID}:
62
Add an optional query parameter
21. In the editor, indent under the /flights get method (not the /flights/{ID} get method).
22. In the shelf, click the queryParameters parameter.
23. Add a key named destination.
24. Indent under the destination query parameter and look at the possible parameters in the shelf.
25. In the shelf, click the required parameter.
26. In the shelf, click false.
27. Go to a new line of code; you should be at the same indent level as required.
28. In the shelf, click the enum parameter.
29. Set enum to a set of values including SFO, LAX, and CLE.
63
31. Review the information.
32. Click the Try it button; you should get a message that the Request URL is invalid; a URL to call
to try the API needs to be added to the RAML definition.
64
Walkthrough 3-2: Use the mocking service to test an API
In this walkthrough, you test the API using the Anypoint Platform mocking service. You will:
65
Test the /flights:get resource
5. In API console, click the Send button for the flights GET method; you should get a 200 status
code, a content-type of application/json, and a general RAML message placeholder.
66
10. Click Try it; you should see a message next to the Send button that the request URL is invalid.
67
Test the /flights:post resource
14. Click the back arrow at the top of API console twice to return to the resource list.
15. Click the POST method.
16. Click Try it.
17. Select the Body tab; it should not have any content.
68
Walkthrough 3-3: Add request and response details
In this walkthrough, you add information about each of the methods to the API specification. You will:
69
3. Click the Add button.
4. In the Consume API Fragment dialog box, select the Training: American Flight Data Type and
the Training: American Flights Example.
70
7. Click the Files button (above the Exchange dependencies button).
8. Expand the exchange_modules section until you see AmericanFlightDataType.raml.
9. Click AmericanFlightDataType.raml and review the code.
10. In the file browser, click the options menu button next to AmericanFlightsDataType.raml and
select Copy path to clipboard.
Note: You can also add the path by navigating through the exchange_modules folder in the
shelf.
71
Specify the /flights:get method to return an array of AmericanFlight objects
15. Go to a new line of code at the end of the /flights get method and indent to the same level as
queryParameters.
16. In the shelf, click responses > 200 > body > application/json > type > AmericanFlight.
72
19. In the file browser, click the options menu next to AmericanFlightsExample.raml and select
Copy path to clipboard.
20. Return to american-flights-api.raml.
21. In the editor, go to a new line after the type declaration in the /flights:get 200 response (at the
same indentation as type).
22. In the shelf, click example.
23. Add the !include keyword and then paste the path you copied.
Note: You can also add the path by navigating through the exchange_modules folder in the
shelf.
73
26. Click the Examples tab; you should see the example array of AmericanFlight objects.
27. Click the Try it button and click Send; you should now see the example response with two flights.
74
Define an example response for the /flights:get method in a new folder
30. In the file browser, click the add button and select New folder.
31. In the Add new folder dialog box, set the name to examples and click Create.
32. In the file browser, click the menu button and select Import.
33. In the Import dialog box, leave File or ZIP selected and click the Choose File button.
34. Navigate to your student files and select the AmericanFlightExample.raml file in the examples
folder.
35. In the Import dialog box, click Import; you should see the new file in API designer.
36. Review the code.
37. In the file browser, drag AmericanFlightExample.raml into the examples folder.
75
40. In the shelf, click example.
41. Add an include statement and include the example in examples/AmericanFlightExample.raml.
43. Select the Examples tab; you should see the example AmericanFlightExample data.
76
44. Click the Try it button, enter an ID, and click Send; you should now see the example flight data
returned.
77
49. In the Add new file dialog box, set the following values:
78
57. Add a 201 response of type application/json.
79
61. Look at the request information; you should now see information about the body - that it is type
AmericanFlight and it has an example.
62. Click the Try it button and select the Body tab again; you should now see the example request
body.
80
63. Click the Send button; you should now see a response with a 201 status code and the example
message.
65. Click Send again; you should get a 400 Bad Request message.
81
Walkthrough 3-4: Add an API to Anypoint Exchange
In this walkthrough, you make an API discoverable by adding it to Anypoint Exchange. You will:
82
4. In the Publish API specification to Exchange dialog box, leave the default values:
83
12. In the main menu, select Exchange; you should see your American Flights API.
13. In the types drop-down menu, select REST APIs; you should still see your API.
14. In the left-side navigation, click MuleSoft; you should not see your American Flights API in the
public Exchange (just the Training: American Flights API).
84
15. In the left-side navigation, click the name of your organization (Training in the screenshots); you
should see your American Flights API in your private Exchange.
85
19. Locate the API version (v1) next to the name of the API at the top of the page.
20. Locate the asset versions for v1; you should see one version (1.0.0) of this API specification (v1)
has been published and there is one API instance for it and that uses the mocking service.
21. In the left-side navigation, click API instances; you should see information for the API instance
generated from the API specification using the mocking service.
86
23. Click AmericanFlight and review the information.
87
27. Click Send; you should get a 200 response and the example data displayed – just as you did in
API console in API designer.
88
32. Select the words american table and click the strong button (the B).
33. Select the words training database and click the emphasis button (the I).
34. Select the words Supported operations and click the heading button four times (the H).
35. Select Get all flights and click the bulleted list button.
36. Repeat for the other operations.
89
37. Click the Visual tab in the editor toolbar and view the rendered markdown.
38. Click the Save as draft button; you should now see buttons to exit the draft or publish it.
90
39. Click the Publish button; you should now see the new information about the API in the API
portal.
91
45. Click the Publish to Exchange button.
46. In the Publish API specification to Exchange dialog box, look at the asset version.
92
52. Click Save as draft and then Publish.
93
Walkthrough 3-5: Share an API
In this walkthrough, you share an API with both internal and external developers to locate, learn about,
and try out the API. You will:
94
3. In the Share American Flights API dialog box, you should see that you are an admin for this API.
4. Open the Viewer drop-down menu located next to the user search field; you should see that you
can add additional users to be of type Viewer, Contributor, or Admin.
Note: In the future, you will also be able to share an asset with an entire business group.
5. Click Cancel.
6. In the left-side navigation, click Assets list.
7. In the left-side navigation, click the name of your organization.
8. Click your American Flights API.
Note: This is how users you share the API with will find the API.
95
Create a public API portal
9. Click the American Flights API.
10. Click the Share button for the API again.
11. In the Share American Flights API dialog box, click Add to the public portal.
96
16. Review the public portal that opens in a new browser tab.
17. Look at the URL for the public portal.
18. Click your American Flights API and review the auto-generated public API portal.
19. In the left-side navigation, click the POST method for the flights resource.
20. Review the body and response information.
97
21. In the API Reference section, click Send; you should get a 201 response with the example data
returned from the mocking service.
98
24. Change the text to Welcome to your MuleSoft Training portal!
99
30. Review the new logo and banner in the preview.
100
36. Navigate to the portal URL you copied; you should see the public portal (without the customize
button).
Note: As an anonymous user, you can make calls to an API instance that uses the mocking
service but not managed APIs.
101
Module 4: Building APIs
102
Walkthrough 4-1: Create a Mule application with Anypoint Studio
In this walkthrough, you build a Mule application. You will:
5. Click Finish.
103
Create an HTTP connector endpoint to receive requests
6. In the Mule Palette, select the Connectors tab.
104
10. In the Global Element Properties dialog box, look at the default values and click OK.
13. Click the Apply Changes button; the errors in the Problems view should disappear.
105
Display data
14. In the Mule Palette, select the Transformers tab.
15. Drag a Set Payload transformer from the Mule Palette into the process section of the flow.
106
17. Click the Configuration XML link at the bottom of the canvas and examine the corresponding
XML.
107
21. Watch the Console view; it should display information letting you know that both the Mule
runtime and the training-american-ws application started.
108
Walkthrough 4-2: Connect to data (MySQL database)
In this walkthrough, you connect to a database and retrieve data from a table that contains flight
information. You will:
Note: The database information you see may be different than what is shown here; the values in
the snippets file differ for instructor-led and self-study training classes.
109
4. In the Mule Palette, select the Connectors tab.
5. Drag a Database connector to the process section of the flow.
Option 1: Configure a MySQL Database connector (if you have access to port 3306)
6. Double-click the Database endpoint.
7. In the Database properties view, click the Add button next to connector configuration.
8. In the Choose Global Type dialog box, select Connector Configuration > MySQL Configuration
and click OK.
110
9. In the Global Element Properties dialog box, set the server, port, user, password, and database
values to the values listed in the course snippets.txt file.
10. Under Required dependencies, click the Add File button next to MySQL Driver.
11. Navigate to the student files folder, select the MySQL JAR file located in the jars folder, and
click Open.
111
12. Back in the Global Element Properties dialog box, click the Test Connection button; you should
get a successful test dialog box.
Note: If the connectivity test fails, make sure you are not behind a firewall restricting access to
port 3306. If you cannot access port 3306, use the instructions in the next section for option 2.
Note: Replace X.X.X with the version of the JAR file, for example 1.5.0.
Note: The application uses ports 1527, 9090, 9091, and 61616. If any of these ports are already
in use, you can change them when you start the application as shown in the following code.
112
17. Look at the output and make sure all the services started.
Note: When you want to stop the application, return to this window and press Ctrl+C.
18. In the computer's file explorer, return to the student files folder and locate the derbyclient.jar file
in the jars folder.
19. Copy and paste or drag this JAR file into the src/main/app/lib folder of the project in Anypoint
Studio.
113
20. Right-click the JAR file and select Build Path > Add to Build Path; you should now see the JAR
file in the project's Referenced Libraries.
24. In the Global Element Properties dialog box, select Configure via spring-bean.
25. Click the Add button next to DataSource Reference.
114
26. On the Bean page of the Global Element Properties dialog box, set the ID and name to
DerbyDB.
27. Click the Browse for Java class button next to class.
28. In the Class browser dialog box, start typing StandardDataSource and select the matching item
for StandardDataSource – org.enhydra.jdbc.standard.
• Name: driverName
• Value: org.apache.derby.jdbc.ClientDriver
Note: You can copy this value from the course snippets.txt file.
115
32. Click Finish.
33. Click the Add button under Bean Subelements again and select Add Property.
34. In the Property dialog box, set the following values:
• Name: url
• Value: jdbc:derby://localhost:1527/memory:training
Note: You can copy this value from the course snippets.txt file.
Note: If you changed the database port when you started the mulesoft-training-services
application, be sure to use the new value here.
37. On the Derby Configuration page of the Global Element Properties dialog box, click Test
Connection; you should get a successful test dialog box.
116
38. Click OK to close the dialog box.
39. Click OK to close the Global Element Properties dialog box.
SELECT *
FROM american
117
44. Watch the console, and wait for the application to start.
45. Once it has started, return to Postman.
46. In Postman, make another request to http://localhost:8081/flights; you should get some garbled
plain text displayed – the tool's best representation of Java objects.
118
Walkthrough 4-3: Transform data
In this walkthrough, you transform and display the account data into JSON. You will:
119
4. In Postman, send the same request; you should see the American flight data represented as
JSON.
Note: If you are using the local Derby database, the properties will be uppercase instead.
7. Notice that the structure of the JSON being returned by the Mule application does not match this
JSON.
120
Add a Transform Message component
8. Return to Anypoint Studio and stop the project.
9. Right-click the Object to JSON transformer and select Delete.
10. In the Mule Palette, select the Components tab.
11. Drag a Transform Message component from the Mule Palette and drop it after the Database
endpoint.
121
13. In the Transform Message properties view, look at the input section and review the payload
metadata; it should match the data returned by the Database endpoint.
20. Click the browse button and navigate to the course student files.
122
21. Select american-flights-example.json in the examples folder and click Open; you should see the
example data for the metadata type.
22. Click Select; you should now see output metadata in the output section of the Transform
Message properties view.
123
Create the transformation
23. Map fields with the same names by dragging them from the input section and dropping them on
the corresponding field in the output section.
• ID to ID
• price to price
• totalSeats to plane > totalSeats
24. Map fields with different names by dragging them from the input section and dropping them on
the corresponding field in the output section.
• toAirport to destination
• takeOffDate to departureDate
• fromAirport to origin
• seatsAvailable to emptySeats
• planeType to plane > type
124
25. Concatenate two fields by dragging them from the input section and dropping them on the same
field in the output section.
• code1 to code
• code2 to code
125
28. Look at the input section, you should see a new tab called payload with sample data generated
from the input metadata.
29. Look at the output section, you should see a sample response for the transformation.
30. In the input section, replace all the ???? with sample values.
31. Look at the output section, you should see the sample values in the transformed data.
126
Test the application
32. Run the project.
33. In Postman, make another request to http://localhost:8081/flights; you should see all the flight
data as JSON again but now with a different structure.
127
Walkthrough 4-4: Create a RESTful interface for a Mule
application
In this walkthrough, you continue to create a RESTful interface for the application. You will:
128
Rename the flows
5. Double-click the name of the first flow.
6. In the Properties view, change its name to getFlightsFlow.
7. Change the name of the second flow to getFlightsByIDFlow.
Note: If you want, change the name of the message source and message processors.
SELECT *
FROM american
WHERE ID = 1
129
13. In Postman, make another request to http://localhost:8081/flights/3; you should see details for
the flight with an ID of 1.
SELECT *
FROM american
WHERE ID = #[message.inboundProperties.'http.uri.params'.ID]
Note: You learn about reading and writing properties and variables in a later module in the
Development Fundamentals course.
130
18. In Postman, make another request to http://localhost:8081/flights/3; you should now see the info
for the flight with an ID of 3.
131
26. Drag out a Set Payload transformer from the Mule Palette and drop it in the process section of
the flow.
29. Return to Anypoint Studio and in the Set Payload properties view, set value to the value you
copied.
Note: This flow is just a stub. For it to really work and add data to the database, you would need
to add logic to insert the request data to the database.
132
33. Send the request; you should now see the message the flight was added – even though you did
not send any flight data to add.
133
Walkthrough 4-5: Use Anypoint Studio to create a RESTful API
interface from a RAML file
In this walkthrough, you generate a RESTful interface from the RAML file. You will:
4. On the Authentication page, make sure your username is listed and selected.
5. Click OK.
134
Add an API from Design Center to the Anypoint Studio project
6. In the Package Explorer, locate the src/main/api folder; it should not contain any files.
7. Right-click the folder (or anywhere in the project in the Package Explorer) and select Anypoint
Platform > Import from Design Center.
8. In the Browse Design Center for APIs dialog box, select the American Flights API and click OK.
135
Examine the XML file created
11. Examine the generated american-flghts-api.xml file and locate the following five flows:
• get:/flights
• get:/flights/{ID}
• post:/flights
• delete:/flights/{ID}
• put:/flights/{ID}
136
12. In the get:/flights flow, double-click the Set Payload transformer and look at the value in the Set
Payload properties view.
13. In the get:/flights/{ID} flow, double-click the Set Payload transformer and look at the value in the
Set Payload properties view.
14. In the post:/flights flow, double-click the Set Payload transformer and look at the value in the Set
Payload properties view.
Examine the main flow and the new HTTP Listener endpoint
15. Locate the american-flights-api-main flow.
16. Double-click its HTTP Listener endpoint.
137
17. In the HTTP properties view, notice that the path is set to /api/*.
18. Click the Edit button for the connector configuration; you should see that the same port 8081 is
used as the HTTP listener you created previously.
19. Click OK.
138
24. Delete the other two HTTP Listener endpoints.
Note: If you want to use the APIkit Consoles view, you need to add a baseUri to the RAML file in
order for the Try-it functionality of the API console to work.
139
Test the web service using Postman
28. In Postman, make a GET request to http://localhost:8081/flights; you should get a 404 response
with a message that the resource was not found because there is no longer a listener for that
endpoint.
29. Change the URL to http://localhost:8081/api/flights and send the request; you should see the
example data returned.
30. Make a request to http://localhost:8081/api/flights/3; you should see the example data returned.
31. Return to Anypoint Studio and stop the project.
140
Walkthrough 4-6: Implement a RESTful web service
In this walkthrough, you wire the RESTful web service interface up to your back-end logic. You will:
141
7. In the Mule Palette, select the Components tab.
8. Drag a Flow Reference component from the Mule Palette and drop it into the process section of
the flow.
9. In the Flow Reference properties view, select getFlightsFlow for the flow name.
142
12. In the Flow Reference properties view, select getFlightsByIDFlow for the flow name.
WHERE ID = #[flowVars.ID]
Note: You learn about the different types of variables in later modules in the Development
Fundamentals course.
143
Test the web service using Postman
16. Run the project.
17. In Postman, make a request to http://localhost:8081/api/flights; you should now get the data for
all the flights from the database instead of the sample data.
18. Make a request to http://localhost:8081/api/flights/3; you should now get the data that flight from
the database instead of the sample data.
19. Return to Anypoint Studio and stop the project.
144
Module 5: Deploying and
Managing APIs
145
Walkthrough 5-1: Prepare an API for deployment using properties
In this walkthrough, you introduce properties into your API implementation. You will:
146
4. In the Global Elements view, click Create.
5. In the Choose Global Type dialog box, select Component configurations > Property Placeholder
and click OK.
6. In the Global Element Properties dialog box, set the location to american-DEV.properties and
click OK.
147
8. Create a property called http.port and set it to 8081.
148
15. Return to american-DEV.properties and paste the values.
Note: If your connection fails, click OK and then go back and make sure you saved
american-DEV.properties.
149
Test the application
24. Run the project.
25. In Postman, make a request http://localhost:8081/api/flights and confirm you still get data.
150
Walkthrough 5-2: Deploy an application to CloudHub
In this walkthrough, you deploy and run your application on CloudHub. You will:
Note: If you do not have a working application at this point, import the training-american-ws-
WT5.1 solution into Anypoint Studio and work with that project.
151
4. At the top of the Anypoint Platform dialog box, set the application name to
training-american-ws-{your-lastname} so it is a unique value.
Note: This name will be part of the URL used to access the application on CloudHub. It must be
unique across all applications on CloudHub. The availability of the domain is instantly checked
and you will get a green check mark if it is available.
5. Make sure the runtime version is set to the version your project is using.
Note: If you don’t know what version it is using, look at the Package Explorer and find a library
folder with the name of the server being used, like Mule Server 3.9.0 EE.
7. Click the Properties tab; you should see the env variable set to DEV.
152
9. Click the Open in Browser button.
10. In the Anypoint Platform browser window that opens, locate the status of your deployment in the
Runtime Manager.
153
13. Watch the logs as the application is deployed.
14. Wait until the application starts (or fails to start).
Note: If your application did not successfully deploy, read the logs to help figure out why the
application did not deploy. If you had errors when deploying, troubleshoot them, fix them, and
then redeploy.
17. Click the link; a request will be made to that URL in an new browser tab and you should get a
message that there is no listener for that endpoint.
154
18. Modify the path to http://training-american-ws-{lastname}.cloudhub.io/api/flights; you should see
the flights data.
Note: If you are using the local Derby database, your application will not return results when
deployed to CloudHub. You will update the application with a version using the MySQL
database in the next section so it works.
19. Add a query parameter called destination to the URL and set it equal to SFO.
20. Send the request; you should still get all the flights.
Note: You did not add logic to the application to search for a particular destination. You will
deploy an application with this additional functionality implemented next.
Note: If you wanted to test this API implementation from Exchange, you could by either 1)
setting the baseUri in the API specification to the URL of the API implementation and then
republishing the API specification or 2) clicking API instances in Exchange and adding a new
API instance with this URL. Typically, however, you want to govern and manage access to an
API. You will create a proxy to do this in the next walkthrough.
155
Update the API implementation deployed to CloudHub
22. Return to the browser tab with Runtime Manager.
23. In the left-side navigation, click Settings for the training-american-ws-{lastname} application.
24. Click the Choose file button.
25. Browse to the resources folder in the course student files.
26. Select training-american-ws-v2.zip and click Open.
Note: This updated version of the application adds functionality to return results for a particular
destination. You will learn to do this later in the Development Fundamentals courses.
28. Wait until the application is uploaded and then redeploys successfully.
Note: Because this can take some time for trial accounts, your instructor may move on with the
next topic and then come back to test this later.
156
Test the updated application
30. Return to the browser tab making a request to the API implementation on CloudHub with a
destination of SFO and refresh it; you should now get only flights to SFO.
157
Walkthrough 5-3: Create and deploy an API proxy
In this walkthrough, you create and deploy an API proxy for your API implementation on CloudHub. You
will:
158
3. Click the Manage API button and select Manage API from Exchange.
4. For API name, start typing American in the text field and then select your American Flights API
in the drop-down menu that appears.
5. Set the rest of the fields to the following values:
• API version: v1
• Asset version: 1.0.1
• Managing type: Endpoint with Proxy
• Implementation URI: http://training-american-ws-{lastname}.cloudhub.io/api
• Proxy deployment target: CloudHub
6. Click Save.
159
7. In the Deployment Configuration section, set the following values:
8. Click Deploy.
9. In the Deploying to CloudHub dialog box, click the Click here link to watch the logs.
10. In the new browser tab that opens, watch the logs in Runtime Manager.
11. Wait until the proxy application starts.
Note: If it does not successfully deploy, read the logs to help figure out why the application did
not deploy. If you had errors when deploying, troubleshoot them, fix them, and then redeploy.
160
12. In the left-side navigation, click Applications; you should see the proxy application.
13. Click the row for the proxy and review its information in the right section of the window.
161
17. In the left-side navigation, click the API Administration link; you should now see your American
Flights API listed.
18. Click in the row for the v1 version – but not on the v1 link.
19. Review the API version info that appears on the right side of the window; you should see there
are no policies, SLA tiers, or client applications.
20. In the API list, click the v1 link for the API; you should be returned to the Settings page for the
API.
21. Locate and review the links on the right side of the page.
22. Click the View configuration details link.
162
24. On the Settings page, look at the requests graph; you should not see any API requests yet.
163
30. In the left-side navigation, click API instances; you should see that the new proxy instance does
not have a URL.
164
36. Click the Add consumer endpoint link.
41. In the left-side navigation, click the name of the API to return to its main page.
165
42. Locate the API instances now associated asset version 1.0.1; you should see the new label for
the API instance.
166
47. Make several more calls to this endpoint.
48. Make calls to different methods.
167
57. In the API console, change the API instance from Mocking Service to Sandbox - No policy.
58. Click Send; you should get data.
168
62. Click the View Analytics Dashboard link located in the upper-right corner.
63. Review the data in the dashboard.
169
Walkthrough 5-4: Restrict API access with policies and SLAs
In this walkthrough, you govern access to the API proxy. You will:
170
4. In the Select Policy dialog box, select Rate limiting.
• # of Reqs: 3
• Time Period: 1
• Time Unit: Minute
• Methods & Resource conditions: Apply configurations to all API methods & resources
171
7. Click Apply; you should see the policy listed for your API.
Note: You may need to refresh the page to see the new label for the API instance.
172
13. Press Send until you get a 429 Too Many Requests response.
173
17. In the Add SLA tier dialog box, set the following values:
• Name: Free
• Approval: Automatic
• # of Reqs: 1
• Time Period: 1
• Time Unit: Minute
• Name: Silver
• Approval: Manual
• # of Reqs: 1
• Time Period: 1
• Time Unit: Second
174
Change the policy to rate limiting – SLA based
20. In the left-side navigation, click the Policies link.
21. Expand the Rate limiting policy.
22. Click the Actions button and select Remove.
175
27. On the Apply Rate limiting – SLA based policy page, look at the expressions and see that a
client ID and secret need to be sent with API requests as query parameters.
176
33. Click Send; you should get a 401 response with a message that a client_id could not be
retrieved from the message.
Note: Other internal users that you shared the API with that do not have Edit permissions will
see a different menu.
177
36. In the Request API access dialog box, click the Create a new application link.
37. In the Create new application dialog box, set the name to Training internal app and click Create.
178
38. In the Request API access dialog box, set the API instance to Sandbox – Rate limiting SLA -
based policy.
39. Set the SLA tier to Free.
179
Request access to the API as an external consumer
43. Return to the public portal in the private/incognito window.
44. Refresh the page for the American Flights API; you should now see a Request access button.
45. Click the Request access button; you should get a page to sign in or create an Anypoint
Platform account.
46. Enter your existing credentials and click Sign in.
Note: Instead of creating an external user, you will just use your existing account.
47. Back in the public portal, click the Request access button again.
48. In the Request API access dialog box, click the Create a new application button
180
49. In the Create new application dialog box, set the name to Training external app and click
Create.
181
55. In the portal main menu bar, right-click My applications and select to open it in a new tab; you
should see the two applications you created.
56. Click the link for Training external app; you should see what APIs the application has access to,
values for the client ID and secret to access them, and request data.
57. Leave this page open in a browser so you can return to it and copy these values.
182
59. In the left-side navigation, click Client Applications; you should see the two applications that
requests access to the API.
60. Click the Approve button for the application requesting Silver tier access.
61. Expand the Training external app row and review its information.
Try to test the rate limiting – SLA based policy from an API portal
62. Return to the browser window and tab with the API console in the public portal.
63. Try again to make a call to the Sandbox – Rate limiting – SLA based policy; you should still get
a 401 response with a message that a client_id could not be retrieved from the message.
Note: There is currently no way to pass the client authentication parameters needed to call this
API from an API portal; you will add this in the next walkthrough. You could, however, use
183
another tool like Postman to make calls to the API, explicitly passing client_id and client_secret
query parameters as you did in module 2.
184
Walkthrough 5-5: Make calls to an API with a client ID based
policy from API portals
In this walkthrough, you add the ability to make calls to APIs with client ID enforcement policies form
internal and public API portals. You will:
4. In the RAML snippet for Rate limiting – SLA based dialog box, select RAML 1.0.
185
5. Copy the value for the traits.
6. Click Close.
7. Return to the browser tab with your API in Design Center.
8. Go to a new line after the types declaration and paste the traits code you copied.
186
9. Go to a new line after the flights resource declaration and add is: [].
10. Place the cursor inside the array brackets and in the shelf, click client-id-required.
11. Repeat this process so the trait is applied to all methods of the {ID} resource as well.
187
14. Enter any values for the client_id and client_secret and click Send; you should get a 200
response with the example results.
188
17. In the Publish API specification to Exchange dialog box, note the asset version and click
Publish.
18. After the API is published, click Done in the Publish API specification to Exchange dialog box.
Update the managed API instance to use the new version of the API specification
19. Return to browser tab with American Flights API (v1) in API Manager.
20. Locate the asset version displayed at the top of the page; you should see 1.0.1.
21. Click the Actions button in the upper-right corner and select Change API Specification.
189
22. In the Change Specification dialog box, select the latest asset version, 1.0.2.
23. Click Change.
24. Wait until the API Status is green again indicating that the new proxy application has been
redeployed.
Test the rate limiting – SLA based policy in an API portal with random client
authentication values
25. Return to the browser tab with Exchange.
26. Return to the home page for the API; you should see the new asset version listed.
190
27. Click the GET method for the flights resource; you should now see required text boxes to enter
the required client_id and client_secret values.
28. With the Mocking Service endpoint selected, enter any values for the client_id and client_secret.
29. Click Send; you should get results.
191
30. Change the API instance to Sandbox – Rate limiting – SLA based policy and leave the random
values for the authentication parameters.
31. Click Send; you should now get a 410 response with a message that the client ID is invalid.
Test the rate limiting – SLA based policy in an API portal with assigned client
authentication values
32. In the left-side navigation, click Assets list.
33. In the left-side navigation, click Public Portal.
34. In the main menu, select My applications.
35. Click the Training internal application.
192
36. Copy the value of its client ID.
37. Right-click Home in the main menu bar and select to open the link in a new browser tab.
38. In that new tab, click the American Flights API.
39. Click the GET method for the flights resource.
40. In the API console, change the API instance to Sandbox – rate limiting – SLA based policy.
41. In the client_id field, paste the value of the client ID.
42. Return to the other browser tab and copy the value of the client secret.
43. Return to the other browser tab and paste the value of the client secret.
44. Click Send; you should now get a 200 response with live results.
193
Review request data
46. Return to the other browser tab with the application information.
47. Change the date selection to Last Day; you should see data about your requests.
194
PART 2: Building Applications
with Anypoint Studio
195
Module 6: Accessing and
Modifying Mule Messages
196
Walkthrough 6-1: Set and log message data
In this walkthrough, you create a new project to use in the next two modules for learning about Mule
messages and Mule applications. You will:
197
9. Set the allowed methods to GET.
13. In the Properties view for the Property transformer, select Set Property.
14. Set the name to qpname and the value to max.
198
Add a Logger
15. Drag a Logger component from the Mule Palette and drop it at the end of the flow.
Note: You are adding a new tab so that you can keep the request to your American API saved
in another tab for later use. Optionally, you could also save it to a Postman collection.
18. In the new tab, make a GET request to http://localhost:8081/hello; you should see Hello world
displayed.
19. Click the Headers link in the response; you should see the qpname property.
199
View message data in the Anypoint Studio console
20. Return to Anypoint Studio and look at the console.
21. Locate the data displayed by using the Logger.
22. Find where the data type of the payload is specified.
23. Review the message inbound properties.
24. Review the message outbound properties.
25. Locate the other two scopes of properties that have no values set.
200
Walkthrough 6-2: Debug a Mule application
In this walkthrough, you debug and step through the code in a Mule application. You will:
201
Note: If you know you have another program using port 6666 like McAfee on Windows, change
this to a different value. Otherwise, you can test the debugger first and come back and change
the value here later if there is a conflict.
5. Click Close.
Note: You can also select Run > Debug or click the Debug button in the main menu bar.
8. If you get an Accept incoming network connections dialog box, click Allow.
9. If you get a Confirm Perspective Switch dialog box, select Remember my decision and click
Yes.
202
10. In the Debug perspective, close the MUnit view.
Note: You will not use MUnit in this course. MUnit is covered in the Anypoint Platform
Development: Advanced course.
11. Look at the console and wait until the application starts.
12. In Postman, make another request to http://localhost:8081/hello.
203
Step through the application
17. Click the Next processor button.
18. Look at the new value of the payload; it should be Hello world.
19. Look at the inbound and outbound properties; you should see they have not changed.
20. Click the Next processor button; you should now see the outbound property qpname.
204
25. Return to the Mule Debugger view and locate your query parameters.
27. Enter the following expression and press the Enter key.
#[message.inboundProperties.'http.query.params']
28. Expand the results; you should see the query parameters.
205
Switch perspectives
32. Click the Mule Design tab in the upper-right corner of Anypoint Studio to switch perspectives.
Note: In Eclipse, a perspective is a specific arrangement of views in specific locations. You can
rearrange the perspective by dragging and dropping tabs and views to different locations. Use
the Window menu in the main menu bar to save and reset perspectives.
206
Walkthrough 6-3: Read and write message properties using MEL
expressions
In this walkthrough, you manipulate message properties. You will:
#['Hello world']
#['Hello world'.toUpperCase()]
207
7. Click the Apply Changes button in the upper-right corner of the Properties view to redeploy the
application.
8. In Postman, send the same request; the return string should now be in upper case.
#[message.inboundProperties.'http.query.params']
#[message.inboundProperties.'http.query.params'.name]
208
17. Return to the console; you should now see the value of the parameter displayed.
#[message.inboundProperties.'http.query.params'.name]
19. Modify the Logger to display the value of this outbound property.
#[message.outboundProperties.qpname]
209
Walkthrough 6-4: Read and write variables
In this walkthrough, you create flow and session variables. You will:
#[message.inboundProperties.'http.query.params'.type]
210
5. Modify the Logger to also display the value of this new variable.
14. In the Session Variable Properties view, select Set Session Variable.
211
15. Set the name to color and give it any value, static or dynamic.
Note: You will explore the persistence of these variables in the next module.
212
Module 7: Structuring Mule
Applications
213
Walkthrough 7-1: Create and reference flows and subflows
In this walkthrough, you continue to work with apdev-examples.xml. You will:
Create a subflow
1. Return to apdev-examples.xml in Anypoint Studio.
2. Drag a Sub Flow scope from the Mule Palette and drop it beneath the existing flow in the
canvas.
3. Select the Set Payload and Property transformers in apdev-examplesFlow and drag them into
the subflow.
4. Change the name of the subflow to subflow1.
214
Reference a subflow
5. Drag a Flow Reference component from the Mule Palette and drop it into the apdev-
examplesFlow between the HTTP Listener endpoint and the Variable transformer.
6. In the Flow Reference properties view, set the flow name to subflow1.
7. Add a breakpoint to the subflow1 Flow Reference.
215
12. Drag subflow2 below subflow1 in the canvas.
216
Reference a flow
24. In apdev-examplesFlow, add a Flow Reference component between the subflow2 Flow
Reference and the Logger.
25. In the Flow Reference Properties view, set the flow name to flow2.
217
Walkthrough 7-2: Pass messages between flows using the Java
Virtual Machine (VM) transport
In this walkthrough, you continue to work with the apdev-examplesFlow. You will:
218
8. In the HTTP properties view, set the connector configuration to the existing
HTTP_Listener_Configuration.
9. Set the path to /flow2 and the allowed methods to GET.
10. Add a breakpoint to the Set Payload transformer in flow2.
11. Add an HTTP Request endpoint after the flow2 reference in apdev-examplesFlow.
12. Delete the flow2 reference.
13. In the HTTP properties view, set the connector configuration to HTTP_Request_Configuration.
14. Set the path to /flow2 and the method to GET.
15. Add a breakpoint to the Logger.
219
19. Locate the qpname property in the inbound properties.
20. Look at the outbound properties, the flow variables, and the session variables.
Note: Session variables are persisted across some but not all transport barriers. As you see
here, they are not propagated across the HTTP transport barrier.
21. Step through the flow until the message returns to apdev-examplesFlow.
Note: If the application times out, debug it again and this time use the Resume button to quickly
step to the breakpoint in flow2 and then step through until the message returns to apdev-
examplesFlow.
22. Look at the inbound and outbound properties and the flow and session variables.
220
26. Drag a VM connector from the Mule Palette into the source section of flow2.
29. In apdev-examplesFlow, add a VM connector endpoint after the HTTP Request endpoint.
30. Delete the HTTP Request endpoint.
221
36. Look at the inbound and outbound properties and the flow and session variables.
Note: Session variables are persisted across some but not all transport barriers. As you see
here, they are propagated across the VM transport barrier.
37. Step through the flow until the message returns to apdev-examplesFlow.
38. Look at the inbound and outbound properties and the flow and session variables.
222
Walkthrough 7-3: Encapsulate global elements in a separate
configuration file
In this walkthrough, you refactor your apdev-examples project. You will:
• Create a new configuration file with an endpoint that uses an existing global element.
• Create a configuration file global.xml for just global elements.
• Move the existing global elements to global.xml.
223
8. Change the name of the existing flow to getSFDCAccountsFlow.
Note: You will use this flow in a later module to retrieve data from Salesforce.
9. Switch to the Global Elements view; you should not see any global elements.
224
16. Select and cut the two configuration elements defined before the flows.
Note: If you delete the global elements from the Global Elements view instead, the config-ref
values are also removed from the connector endpoints and you need to re-add them.
20. Switch to the Global Elements view; you should see the two configurations.
225
Close the project
26. Return to Anypoint Studio.
27. Stop the project.
28. In the Package Explorer, right-click apdev-examples and select Close Project.
226
Walkthrough 7-4: Create a well-organized Mule project
In this walkthrough, you create a new project for the Mule United Airlines (MUA) flights application that
you will build during the course and then review and organize its files and folders. You will:
227
7. Explore the API; be sure to look at what resources are defined and the structure of the Flight
data type.
228
13. In the Browse API Design Center for APIs dialog box, select MUA Flights API and click OK.
229
17. Open mua-flights-api.raml and review the file.
230
29. In the New File dialog box, set the file name to flights-DEV.properties and click Finish.
30. Add a property called http.port equal to 8081.
231
37. Confirm you now have two global elements defined in the global.xml file.
Review src/main/resources
44. In src/main/resources, open log4j2.xml.
45. Review and then close the file.
232
49. Open the Flight.java file.
50. Review the code and then close the file.
233
56. In the Export dialog box, select Mule > Anypoint Studio to Mule Deployable Archive and click
Next.
57. Set the Zip file to a location that you can find and click Finish.
58. In your computer's file browser, locate the ZIP file and expand it.
59. Open the resulting apdev-flights-ws folder.
234
60. Expand the classes folder and examine the contents.
235
Module 8: Consuming Web
Services
236
Walkthrough 8-1: Consume a RESTful web service
In this walkthrough, you consume a RESTful web service that returns a list of all United flights as
JSON. You will:
237
5. Look at the destination values; you should see SFO, LAX, CLE, PDX, and PDF.
6. Copy the host name from the URL; this should be something like mu.mulesoft-training.com.
238
14. Change the HTTP Request endpoint display name to United REST Request.
239
21. In the Global Element Properties dialog box, set the following values and click OK.
• Name: United_REST_Request_Configuration
• Host: ${united.host}
• Port: 80
• Base Path: Leave blank
240
27. Add a Logger after the United REST Request endpoint.
241
Add metadata for the United REST Request response
35. Return to Anypoint Studio and switch perspectives.
36. In the Properties view for the United REST Request, click the Output tab; you should see the
payload is of type unknown.
41. In the Select metadata type dialog box, click the Add button.
42. In the Create new type dialog box, set the type id to united_flights_json.
43. Click Create type.
44. In the Select metadata type dialog box, set the type to JSON.
45. Change the Schema selection to Example.
46. Click the browse button and navigate to the projects's src/test/resources folder.
242
47. Select united_flights-example.json and click Open; you should see the example data for the
metadata type.
243
Review the structure for the desired JSON response
51. Open flights-example.json in src/test/resources and review the sample.
54. Look at the input section; you should see metadata for the output from the United REST
Request.
244
Add output metadata for the transformation
55. In the output section of the Transform Message properties view, click the Define metadata link.
56. In the Select metadata type dialog box, click the Add button.
57. In the Create new type dialog box, set the type id to flights_json.
58. Click Create type.
59. In the Select metadata type dialog box, set the type to JSON.
60. Change the Schema selection to Example.
61. Click the browse button and navigate to the projects's src/test/resources folder.
62. Select flights-example.json and click Open; you should see the example data for the metadata
type.
Note: Be sure to select the JSON file with flights plural, not singular.
245
63. Click Select; you should now see output metadata in the output section of the Transform
Message properties view.
246
Test the application
65. Debug the project.
66. In Postman, make another request to http://localhost:8081/united.
67. In the Mule Debugger, step to the Logger; you should see the payload is now a DataWeave
ByteArraySeekableStream.
70. Return to Anypoint Studio, stop the project, and switch to the Mule Design perspective.
247
Walkthrough 8-2: Pass arguments to a RESTful web service
In this walkthrough, you retrieve United flights for a specific destination by setting the destination as a
URI parameter. You will:
• Modify the HTTP Request endpoint to use a URI parameter for the destination.
• Set the destination to a static value.
• Create a flow variable to store the value of a query parameter with an airport code value.
• Set the destination to the dynamic value of this flow variable.
Note: The API you are building for flights.raml has a query parameter called code for the
destination; this existing United web service uses a URI parameter for the destination.
248
3. Send the request; you should see JSON data for only the flights to CLE.
249
Test the application
13. Run the project.
14. In Postman, return to the tab with the localhost requests.
15. Make a request to http://localhost:8081/united/; you should only get the flights to SFO.
16. Add a query parameter called code and set it to LAX.
17. Send the request; of course, you should still get only flights to SFO.
20. In the Variable Properties view, change the display name to Set airport code variable.
250
Set the operation to Set Variable and the name to code.
21. Set the value to a query parameter called code.
#[message.inboundProperties.'http.query.params'.code]
#[flowVars.code]
251
25. Change the code to PDX and make the request; you should now see flights to PDX.
26. Remove the code parameter and make the request; you should get a 500 responses and an
exception.
Modify the set airport code flow variable to assign a default value
27. Return to Anypoint Studio.
28. Modify the Set variable transformer to use a ternary expression to assign a default value of SFO
if no query parameter is passed to the flow.
#[(message.inboundProperties.'http.query.params'.code == empty) ?
'SFO' : message.inboundProperties.'http.query.params'.code]
252
Test the application
29. Save and redeploy the application.
30. In Postman, send the same request again with no query parameter; this time you should get
flights to SFO instead of an exception.
253
Walkthrough 8-3: Consume a RESTful web service that has a
RAML definition
In this walkthrough, you consume the American flights RESTful web service that you built and deployed
to the cloud. You will:
• Create a new flow to call a RESTful web service that has a RAML definition.
• Select the web service resource from the list provided by Anypoint Studio from the RAML file.
• Use DataWeave to transform the JSON response into JSON specified by an API.
254
Add a new flow with an HTTP Listener endpoint
3. Return to implementation.xml.
4. Drag out another HTTP connector and drop it in the canvas.
5. Rename the flow to getAmericanFlightsFlow.
6. In the Properties view, set the connector configuration to the existing
HTTP_Listener_Configuration.
7. Set the path to /american.
8. Set the allowed methods to GET.
Add an HTTP Request endpoint for a web service with a RAML definition
9. Drag out another HTTP connector and drop it in the process section of the new flow.
10. Change the endpoint display name to American REST Request.
255
14. In the Global Element Properties dialog box, change the name to
American_HTTP_Request_Configuration.
15. Click the Search in Exchange link next to REST API Location.
16. In the Exchange window that opens, locate your American Flights RAML and click it.
Note: If you do not have a functional API implementation for the American Flights API, you can
select the Training: American Flights API instead.
17. Click the Open button; the Exchange window should close.
256
18. Back in the Global Element Properties dialog box, wait for the RAML to be parsed and the host,
port, and base path fields to be populated and then click OK.
257
24. Look at the method drop-down menu; you should see DELETE, GET, and PUT.
28. Scroll down and check to see if a query parameter called code has been added.
29. If the destination parameter was not automatically created, create it.
30. Set the value to a flow variable called code; you will add this to the flow next.
#[flowVars.code]
258
Extract the Set airport code variable processor into a subflow and use it
31. Right-click the Set airport code variable processor in getUnitedFlightsFlow and select Extract to
> Sub Flow.
32. In the Extract Flow dialog box, set the flow name to setCodeSubflow and click OK.
33. Double-click the new Flow Reference in getUnitedFlightsFlow; the display name should update.
34. Locate the new subflow.
Note: If you do not see the subflow in the canvas, switch to the Configuration XML view and
then back to the Message Flow view.
35. Drag a Flow Reference component from the Mule Palette before the American REST Request
in getAmericanFlightsFlow.
36. In the Flow Reference properties view, set the flow name to setCodeSubflow.
259
Test the application
37. Save all the files to redeploy the application.
38. In Postman, return to the tab with the local requests.
39. Make a request to http://localhost:8081/american; you should get the American flights to SFO.
40. Add a query parameter called code with a value of CLE.
41. Send the request; you should get just the flights to CLE.
260
49. Map fields (except ID and airline) by dragging them from the input section and dropping them on
the corresponding field in the output section.
261
Walkthrough 8-4: Consume a SOAP web service
In this walkthrough, you consume a SOAP web service that returns a list of all Delta flights as XML.
You will:
262
Create a new flow with an HTTP Listener connector endpoint
5. Return to Anypoint Studio.
6. Drag out another HTTP connector and drop it in the canvas after the existing flows.
7. Rename the flow to getDeltaFlightsFlow.
8. In the Properties view for the endpoint, set the connector configuration to the existing
HTTP_Listener_Configuration.
9. Set the path to /delta.
10. Set the allowed methods to GET.
263
Configure the Web Service Consumer connector
13. Return to global.xml.
14. Click Create.
15. In the Choose Global Type dialog box, select Connector Configuration > Web Service
Consumer and click OK.
16. In the Global Element Properties dialog box, change the name to
Delta_Web_Service_Consumer.
17. Set the WSDL location to the value you copied from the course snippets.txt file.
18. Wait for the service, port, and address fields to populate.
Note: If the fields do not populate, click the Reload WSDL button. If the fields still do not auto-
populate, select TicketServiceService from the service drop-down menu and select
TicketServicePort from the port drop-down menu.
264
21. In the Delta SOAP Request properties view, set the connector configuration to the existing
Delta_Web_Service_Consumer.
22. Click the operation drop-down menu button; you should see all of the web service operations
listed.
265
29. In the Mule Debugger, step to the Logger and look at the payload; it should be of type
DepthXMLStreamReader.
266
33. In getDeltaFlightsFlow, add a Transform Message component after the Delta SOAP Request
endpoint.
34. Look at the input section of the Transform Message properties view; you should see metadata
already defined.
35. In the output section of the Transform Message properties view, click the Define metadata link.
36. In the Define metadata type dialog box, select User Defined > flights_json.
37. Click Select; you should now see output metadata in the output section of the Transform
Message properties view.
267
38. Map fields by dragging them from the input section and dropping them on the corresponding
field in the output section.
41. Add a query parameter called code and set it equal to LAX.
42. Send the request; you should still get all flights.
268
Walkthrough 8-5: Pass arguments to a SOAP web service using
DataWeave
In this walkthrough, you modify the Delta flow to return the flights for a specific destination instead of all
the flights. You will:
• Change the web service operation invoked to one that requires a destination as an input
argument.
• Set a flow variable to the desired destination.
• Use DataWeave to pass the flow variable to the web service operation.
269
4. In Postman, send the same request with the query parameter; you should get a 500 response
with a message about unknown parameters.
10. In the Pass code properties view, look at the input and output sections.
11. Drag the code flow variable in the input section to the destination element in the output section.
270
Test the application
12. Redeploy the application.
13. In Postman, make the same request; you should get a 200 status code with an exception
message.
14. Examine the exception message and figure out what is wrong with the transformation.
271
20. In Postman, make the same request; you should now get all the flights to LAX.
272
Module 9: Handling Errors
273
Walkthrough 9-1: Handle a messaging exception
In this walkthrough, you handle an exception thrown by the Delta flow when a destination with no flights
is used. You will:
274
6. Click the Resume button.
275
13. Make sure there is a breakpoint on the transformer inside the catch exception.
14. Add a Logger after the transformer.
276
Set the http status code
20. Return to getDeltaFlightsFlow in the Mule Design perspective.
21. In the catch exception strategy, add a Property transformer after the Set Payload transformer.
277
29. Delete the Pass code processor.
278
Walkthrough 9-2: Handle different types of messaging exceptions
In this walkthrough, you handle multiple types of exceptions thrown by the Delta flow. You will:
Note: You cannot it directly to getDeltaFlightsFlow because that flow already contains an
exception strategy, so you are adding it to getAmericanFlightsFlow temporarily.
279
3. Drag the catch exception strategy from getDeltaFlightsFlow and drop it in the choice exception
strategy in getAmericanFlightsFlow.
4. Drag getDeltaFlightsFlow and drop it above getAmericanFlightsFlow.
Note: If you must scroll to see all the flows on the canvas, it is difficult to drag-and-drop
elements near the bottom of the canvas.
280
6. Drag a second Catch Exception Strategy from the Mule Palette and drop it in the choice
exception strategy.
Note: If you are having difficulty adding it, try dropping it on the catch exception strategy already
there.
7. Add a Set Payload transformer, a Property transformer, and a Logger to the new catch
exception strategy.
8. In the Set Payload properties view, set the value the following MEL expression:
281
Configure the choice exception strategy
11. In the Properties view for the first catch exception strategy, set the display name to No flights –
DW exception.
12. Set the execute when value to an expression for when a com.mulesoft.weave.* exception is
thrown; use the causeMatches() method.
#[exception.causeMatches('com.mulesoft.weave.*')]
13. In the Properties view for the second catch exception strategy, set the display name to Data
unavailable – all other exceptions.
14. Leave the execute when value blank.
282
17. In the Mule Debugger, step through the application; the exception should be handled by the
second catch block.
283
22. In the Transform Message properties view, drag the code flow variable in the input section to
the destination element in the output section.
284
Move a catch exception strategy to the calling flow
34. Expand the error handling section of getFlightsFlow.
35. Move the choice exception strategy from getDeltaFlightsFlow to getFlightsFlow.
36. Test the application Make sure there is a breakpoint on each of the Set Payload transformers in
the catch exception strategies.
37. Debug the project.
38. In Postman, make a request to http://localhost:8081/flights?code=FOO.
Note: Call the new /flights endpoint; not the /delta one.
285
39. In the Mule Debugger, step through the application; you should see the exception thrown by the
Delta flow is caught by the calling flow.
40. Step through the rest of the application and then stop the project and switch perspectives.
286
Walkthrough 9-3: Create and use global exception strategies
In this walkthrough, you create a global exception handler for the project. You will:
287
7. In the choice-exception-strategy tag, change doc:name to name and replace the spaces in the
name with underscores; the problem should go away
8. Switch to the Message Flow view; you should see the choice exception strategy.
288
11. Drag a Reference Exception Strategy from the Mule Palette and drop it in the error handling
section.
12. In the Reference Exception Strategy properties view, set the global exception strategy to the
existing Choice_Exception_Strategy.
13. Expand the error handling section of getUnitedFlightsFlow.
14. Drag a Reference Exception Strategy from the Mule Palette and drop it in the error handling
section.
15. In the Properties view, set the global exception strategy to
Choice_Exception_Strategy.
Note: You could add a reference exception strategy to the rest of the flows, but instead, you will
create a global default exception strategy in the next walkthrough.
289
Test the application
16. Run the project.
17. In Postman, make the same request to http://localhost:8081/flights?code=FOO; you should get
the same NO FLIGHTS to FOO message.
18. Make a request to http://localhost:8081/united?code=FOO; you should see the same message.
19. Make a request to http://localhost:8081/delta?code=FOO; you should NOT see the same
message because the exception is not being handled.
290
Walkthrough 9-4: Specify a global default exception strategy
In this walkthrough, you change the default exception handling for the application. You will:
291
5. In the Global Element Properties dialog box, set the default exception strategy to
Choice_Exception_Strategy and click OK.
292
8. Delete the reference exception strategy in getUnitedFlightsFlow.
293
Walkthrough 9-5: Review a mapping exception strategy
In this walkthrough, you review the mapping exception strategy that was created automatically by APIkit
for the interface. You will:
294
Review a mapping exception strategy
4. In interface.xml, locate the mua-flights-apiKitGlobalExceptionMapping Mapping exception
strategy.
5. Double-click the 404 exception mapping and look at the settings in the 404 properties view.
295
6. Double-click the Property transformer in the 404 exception mapping and look at the settings in
the Set Payload properties view.
7. Double-click the Set Payload transformer in the 404 exception mapping and look at the settings
in the Set Payload properties view.
8. Look at the values for the Set Payload transformers in the other exception mappings.
296
Module 10: Controlling Message
Flow
297
Walkthrough 10-1: Route messages based on conditions
In this walkthrough, you modify getFlightsFlow to route messages to either the United, Delta, or
American flows based on the value of an airline query parameter. You will:
298
Test the application
5. In Postman, make a request to http://localhost:8081/flights?code=CLE; you should see only
Delta flights to CLE.
6. Add a query parameter called airline and set it equal to united.
7. Send the request again; you should still only see the Delta flights.
299
Add a Choice router
11. Drag a Choice flow control element from the Mule Palette and drop it in getFlightsFlow before
getDeltaFlightsFlow.
12. Drag the getDeltaFlightsFlow flow reference into the router.
13. Add two additional Flow Reference components to the Choice router.
14. In the Properties view for the first flow reference, set the flow name to getUnitedFlightsFlow.
15. In the Properties view for the second flow reference, set the flow name to
getAmericanFlightsFlow.
16. Drag a Logger component from the Mule Palette and drop it in the default branch.
300
Store the airline query parameter in a flow variable
17. Add a Variable transformer before the Choice router.
18. Change its display name to Set airline variable.
19. Set the flow variable name to airline and set it equal to a query parameter called airline.
#[message.inboundProperties.'http.query.params'.airline]
#[flowVars.airline == "delta"]
22. Set a similar expression for the United route, routing to it when flowVars.airline is equal to
united.
301
23. Set a similar expression for the American route, routing to it when flowVars.airline is equal to
american.
26. In getDeltaFlightsFlow, delete the HTTP Listener endpoint and the setCodeSubflow flow
reference.
302
27. In getAmericanFlightsFlow, delete the HTTP Listener endpoint and the setCodeSubflow flow
reference.
303
32. Step through the rest of the application; you should see the message passed to
getUnitedFlightsFlow and then back to getFlightsFlow.
33. Return to Postman; you should see only United flights to CLE returned.
304
38. In Postman, remove both parameters and make a request to http://localhost:8081/flights.
39. In the Mule Debugger, step through the application; you should see the Choice router pass the
message to the default branch.
Note: If the next walkthrough, you will change this behavior so that if no airline is specified,
flights for all airlines will be returned.
42. Return to Anypoint Studio, stop the project, and switch to the Mule Design perspective.
305
Walkthrough 10-2: Multicast a message
In this walkthrough, you create a flow that calls each of the three airline services and combines the
results. You will:
306
6. Set the flow name of the second Flow Reference to getUnitedFlightsFlow.
7. Set the flow name of the third Flow Reference to getAmericanFlightsFlow.
8. Add a Logger after the router.
307
Test the application
12. Debug the project.
13. In Postman, make the same request to http://localhost/flights.
14. In the Mule Debugger, step through the application to the default branch of the Choice router,
then into the Scatter-Gather, and then into each of the airline flows.
15. Stop at the Logger back in getFlightsFlow and look at the payload.
Note: You get three different DataWeave stream objects. You want to combine the three
collections and then sort them by price and return them as JSON. Because the airline flight
flows were written first and already return JSON, you can just flatten the collections into one and
then order by price. More typically, however, you would have each of the airline flows return
data of a common canonical format – in this case, a collection of Flight Java objects – and then
flatten, order, and transform that data to the JSON specified by the API.
308
19. Add a Transform Message component before the Logger.
20. In the Properties view, set the DataWeave expression to flatten the payload.
flatten payload
Note: You will learn about DataWeave operators in the later module Writing DataWeave
Transformations.
309
23. In the Mule Debugger, step through the application to the Logger after the Choice router; you
should see the payload is now one ArrayList of HashMaps.
24. Step through the rest of the application and stop the project.
25. In Postman, you should get a representation of Java objects returned.
310
28. In the Transform Message properties view, change the output to application/json.
29. Change the transformation expression to order the payload by price.
Note: You will learn about DataWeave operators in the next module, Writing DataWeave
Transformations.
32. Add an airline parameter equal to united and send the request:
http://localhost:8081/flights?airline=united; you should get united flights to SFO sorted by price.
311
33. Add a code parameter equal to PDF and send the request:
http://localhost:8081/flights?airline=united&code=PDF; you should get one united flight to PDF.
35. Remove the airline parameter and send the request: http://localhost:8081/flights?code=PDF;
you should get the one United flight to PDF, but instead you get the message that there are no
flights.
312
36. Return to Anypoint Studio and stop the project.
40. Continue to step through the application until you reach the Transform Message component in
getAllAirlineFlightsFlow; you should see different types of objects returned.
313
41. Step to the Transform Message component in getFlightsFlow; you should see the payload still
contains the error message in addition to the valid flight results to PDF.
42. Step to the end of the application; you should not get the United results to PDF.
Note: You could write a custom aggregation strategy for the Scatter-Gather router with Java to
handle this situation, but instead you will use the simpler approach of filtering out the exception
messages in the next walkthrough.
43. Return to Anypoint Studio, stop the project, and switch to the Mule Design perspective.
314
(Optional) Modify the airline flows to return Java Flight objects instead of JSON
Note: The rest of the walkthrough is optional. It contains steps to modify each of the airline flows
to return data of a common canonical format – in this case, a collection of Flight Java objects.
Change the United airline flows to return Java Flight objects instead of JSON
44. Return to getUnitedFlightsFlow in implementation.xml.
45. In the Transform Message properties view, right-click List <Json> in the output section and
select Clear Metadata.
46. Click the Define metadata link.
47. In the Select metadata type dialog box, click the Add button.
48. In the Create new type dialog box, set the name to Flight_pojo and click Create type.
49. In the Select metadata type dialog box, change the type to Java.
50. In the Data structure section, click the Click here to select an option link.
315
52. In the dialog box that opens, type fli and then in the list of classes that appears, select Flight –
com.mulesoft.training.com.
316
56. In the Transform Message properties view, replace the current transformation expression with
an empty object.
Change the American flow to return Java Flight objects instead of JSON
58. Return to getAmericanFlightsFlow.
59. In the Transform Message properties view, right-click List <Json> in the output section and
select Clear Metadata.
60. Click the Define metadata link.
61. In the Select metadata type dialog box, select Flight_pojo.
317
62. Select the Wrap element in a collection checkbox in the lower-left corner.
318
Change the Delta flow to return Java Flight objects instead of JSON
68. Return to getDeltaFlightsFlow.
69. In the Transform Message Properties view for the component after the Delta SOAP Request,
right-click List <Json> in the output section and select Clear Metadata.
70. Click the Define metadata link.
71. In the Select metadata type dialog box, select Flight_pojo.
72. Select the Wrap element in a collection checkbox in the lower-left corner.
73. Click Select.
74. In the Transform Message properties view, replace the current transformation expression with
an empty object.
75. Use the graphical editor to map the fields appropriately.
319
79. Step to the Logger; the payload should now be one ArrayList of Flight objects.
320
83. Add an airline parameter equal to united and send the request:
http://localhost:8081/flights?airline=united; you should get united flights to SFO sorted by price.
84. Add a code parameter equal to PDF and send the request:
http://localhost:8081/flights?airline=united&code=PDF; you should get one united flight to PDF.
321
86. Remove the airline parameter and send the request: http://localhost:8081/flights?code=PDF;
you should get the one United flight to PDF, but instead you get the message that there are no
flights.
Note: The American flow also throws an exception that is handled by this choice exception
strategy.
322
91. Continue to step through the application until you reach the Transform Message component
in getFlightsFlow; you should see the payload still contains the error messages in addition to the
valid flight results to PDF.
92. Step to the end of the application; you should not get the United results to PDF.
Note: You could write a custom aggregation strategy for the Scatter-Gather router with Java to
handle this situation, but instead you will use the simpler approach of filtering out the exception
messages in the next walkthrough.
93. Return to Anypoint Studio, stop the project, and switch perspectives.
323
Walkthrough 10-3: Filter messages
In this walkthrough, you filter the results in the multicast to ensure they are ArrayLists and not exception
strings. You will:
324
Add a filter
3. Return to getAllAirlineFlightsFlow.
4. Drag out a Payload filter from the Mule Palette and drop it after the getDeltaFlightsFlow
reference in the Scatter-Gather.
6. Add a Payload filter after the getAmericanFlightsFlow reference and set its expected type to
java.util.ArrayList.
325
Test the application
7. Debug the project.
8. In Postman, make the same request to PDF and all airlines.
9. In the Mule Debugger, step to the Transform Message component after the Scatter-Gather; this
time you should see the payload does not contain the error strings.
326
12. Change the code parameter to FOO and send the request.
13. Click Resume until you step through to the end of the application.
14. In Postman, view the response; you should see an error message.
327
20. In the Global Elements dialog box, set the name to Filter_Not_ArrayList.
21. Set the expected type to java.util.ArrayList and click OK.
24. In the Filter Reference properties view, set the global reference to Filter_Not_ArrayList.
328
28. In the Filter Reference properties view, set the global reference to Filter_Not_ArrayList.
329
31. In Postman, make a request to http://localhost:8081/flights?code=FOO; you should correctly get
the message that there are no flights to FOO.
330
Walkthrough 10-4: Validate messages
In this walkthrough, you modify the application to require a destination code be sent to it as a query
parameter and then use a validator to make sure a value is sent and to throw an exception if it is not.
You will:
#[message.inboundProperties.'http.query.params'.code]
331
Test the application
4. Run the project.
5. In Postman, make a request to http://localhost:8081/flights; you should get an incorrect
message that there are no flights to null.
Add a validator
7. Return to getFlightsFlow.
8. Drag out a Validation component from the Mule Palette and drop it after the setCodeSubflow
flow reference.
332
Configure the validator
9. In the Validation properties view, set the validator to Is Not Empty.
10. Set the value to #[flowVars.code].
11. Set the message to You must pass the destination as a query parameter called code.
12. Set the Exception class to java.lang.IllegalArgumentException.
333
16. In the Mule Debugger, step to the Validation component and look at the exception it throws.
17. Step again; you should move into the Data unavailable catch exception strategy in global.xml.
334
20. Drag a Catch Exception Strategy form the Mule Palette and drop it in the choice exception
strategy.
21. In the Properties view for this catch strategy, set the display name to No destination code set.
22. Specify to execute this catch strategy when the exception is of type
java.util.IllegalArgumentException.
#[exception.causedBy(java.lang.IllegalArgumentException)]
335
23. Add a Set Payload transformer to the catch strategy and set the value to the message property
of the exception.
24. Add a Property transformer and set a property with the name http.status and a value of 400.
25. Add a Logger component.
336
27. Move this catch exception strategy so it is the first strategy in the choice exception strategy.
28. Return to the Message Flow view; the default catch exception strategy should now be at the
bottom.
337
31. In the Mule Debugger, step past the Validation component into the exception strategy; this time,
you should move into the No destination code set strategy.
34. Return to Anypoint Studio, stop the project, and switch perspectives.
35. Close the project.
338
Module 11: Writing DataWeave
Transformations
• Write DataWeave expressions for basic XML, JSON, and Java transformations.
• Store DataWeave transformations in external files.
• Write DataWeave transformations for complex data structures with repeated elements.
• Coerce and format strings, numbers, and dates.
• Use DataWeave operators.
• Define and use custom data types.
• Call MEL functions and Mule flows from DataWeave transformations.
339
Walkthrough 11-1: Write your first DataWeave transformation
In this walkthrough, you work with JSON data for a flight posted to a flow. You will:
340
8. Add a breakpoint to it.
9. In the Transform Message properties view, locate the drop-down menu at the top of the view
that sets the output type; it should be set to Payload.
10. Beneath it, locate the directive that sets the output to application/java.
11. Delete the existing DataWeave expression (the curly braces) and set it to payload.
341
19. In the Mule Debugger, you should see the payload has a mime-type of application/json and is of
type BufferInputStream.
20. Look at the inbound properties; you should see the content-type is set to application/json.
21. Step to the Logger; you should see the payload now has a mime-type of application/java and is
a LinkedHashMap.
342
27. Step to the end of the application.
343
Add HTTP Listener output metadata
35. In the HTTP Listener Properties view, select Metadata and click the Add metadata button.
36. Select Output:Payload and click the Edit button.
42. In the Transform Message Properties view, you should now see metadata for the input.
344
Preview sample data and sample output
43. In the transform section, change the output type from application/xml back to application/json.
44. Click the Preview button.
45. Click the Create required sample data to execute preview link.
46. Look at the input section; you should see a new tab called payload and it should contain the
sample data.
47. Click the Show Source With Trees button to the left of the Preview button.
48. Look at the preview section; you should see the sample output there of type JSON.
51. In the transform section, change the output type from application/java to application/xml.
345
52. Locate the warning icons indicating that there is a problem.
53. Mouse over the icon located to the left of the code; you should see a message that there was an
exception trying to output the second root <flightCode>.
54. Click the icon above the code; a List of errors dialog box should open.
Note: You will learn how to successfully transform to XML in the next walkthrough.
346
60. In the Transform Message Properties view, click the Edit current target button (the pencil) above
the code.
61. In the Selection dialog dialog box, change the source code selection from inline to file.
62. Set the file name to json_flight_playground.
347
66. In the Package Explorer, expand src/main/resources.
348
Walkthrough 11-2: Transform basic Java, JSON, and XML data
structures
In this walkthrough, you continue to work with the JSON flight data posted to the flow. You will:
349
4. Change the DataWeave expression to data: payload.price.
8. Add a field called code and set it to the toAirportCode property of the payload.
9. Add a field called airline and set it to the airline property of the payload.
350
Create a second transformation with the same component
10. Click the Add new target button.
11. In the Selection dialog dialog box, leave the output set to variable.
12. Set the variable name to xml.
351
20. Look at the preview; you should now see XML.
21. In the output section menu bar, click the drop-down arrow next to FlowVar – xml and select
Payload.
22. Copy the DataWeave expression.
23. Switch back to FlowVar – xml and replace the DataWeave expression with the one you just
copied.
24. Modify the expression so the code and airline properties are child elements of a new element
called flight.
352
25. Modify the expression so the airline is an attribute of the flight element.
353
Walkthrough 11-3: Transform complex data structures with arrays
In this walkthrough, you work with JSON data for multiple flights posted to a flow. You will:
• Create a new flow that receives POST requests of a JSON array of objects.
• Transform a JSON array of objects to Java.
354
Transform the payload to Java
6. Add a Transform Message component and a Logger to the flow.
7. In the Transform Message properties view, set the DataWeave expression to payload.
8. Click the Preview button.
13. In the Transform Message Properties view, you should now see metadata for the input.
355
Preview sample data and sample output
14. In the preview section, click the Create required sample data to execute preview link.
15. Look at the preview section; the sample output should be an ArrayList of LinkedHashMaps.
356
20. Change the DataWeave expression to payload.price; you should get the same result.
21. Change the DataWeave expression to return a collection of prices and available seats; in the
preview section, you should see an ArrayList with two ArrayLists.
[payload.price, payload.emptySeats]
Use the map operator to return object collections with different data structures
22. Change the DataWeave expression to payload map $; in the preview section, you should see
two ArrayList of two LinkedHashMaps again.
23. Change the DataWeave expression to set a property called flight for each object that is equal to
its index value in the collection.
357
24. Change the DataWeave expression to create a property called destination for each object that is
equal to the value of the toAirportCode field in the payload collection.
25. Change the DataWeave expression to dynamically add each of the properties present on the
payload objects.
358
26. Change the DataWeave expression so the name of each object is flight+index and you get
flight0, flight1, and flight2.
Note: If you want to test the application, change the output type to application/json and then in
Postman, change the request URL to http://localhost:8081/multipleflights and replace the
request body with JSON from the flights-example.json file, .
359
29. Look at the error message.
360
Walkthrough 11-4: Transform to and from XML with repeated
elements
In this walkthrough, you continue to work with the JSON data for multiple flights posted to the flow. You
will:
361
4. Remove the flight property.
5. Modify the expression so the flights object has a single property called flight.
7. In the Close Sample Data dialog box, click Close tab and Keep file.
8. In the input section, right-click Payload: List<Json> and select Clear Metadata.
9. In the HTTP Listener Properties view, select Metadata and click the Edit button.
10. In the Select metadata type dialog box, click Add.
11. In the Create new type dialog box, set the type id to flights_xml and click Create type.
12. In the Select metadata dialog box, set the type to XML.
362
13. Select Example and browse to and select the flights-example.xml file in src/test/resources.
363
18. Review the transformation expression.
19. Look at the preview section; you should see all the flights are children of the flight element.
364
22. Change the DataWeave expression use * to loop over the XML repeated return elements.
23. Change the DataWeave expression to return flight elements with dest and price elements that
map to the corresponding destination and price input values.
Note: If you want to test the application with Postman, be sure to change the content-type
header to application/XML and replace the request body with XML from the flights-example.xml
file.
365
26. In the DataWeave expression, remove the {( }) around the map expression.
27. Change the DataWeave expression to remove the flight property.
28. Look at the preview; you should see flights is an ArryaList with five LinkedHashMaps.
366
Walkthrough 11-5: Coerce and format strings, numbers, and dates
In this walkthrough, you continue to work with the XML flights data posted to the flow. You will:
367
3. In the left-side navigation, navigate to Mule Runtime > Reference > DataWeave > Operators.
6. In the right-side navigation, click the Type Coercion using as link again.
368
7. In the page, locate and click the type coercion table link.
369
Format a string
9. Return to Anypoint Studio.
10. In the Anypoint Studio dialog box, click OK.
11. Navigate to the Transform Message Properties view for the transformation in
postMultipleFlightsFlow.
12. Change the DataWeave expression to return objects that also have a property called plane
equal to the value of the input planeType values.
13. Use the upper operator to return the value in uppercase.
14. Look at the preview; you should see the uppercase plane fields.
17. Look at the preview; you should see the prices are now either Integer or Double objects.
370
Coerce a string to a specific type of number object
18. Change the DataWeave expression to use the class metadata key to coerce the prices to
java.lang.Double objects.
19. Look at the preview; you should see the prices are now all Double objects.
Format a number
20. Use the format schema property in the DataWeave expression to format the prices to zero
decimal places.
21. Remove the coercion to a java.lang.Double.
23. Change the DataWeave expression to format the prices to two decimal places.
371
24. Look at the preview; the prices should be formatted differently.
25. Change the DataWeave expression to format the prices to two minimal decimal places.
26. Look at the preview; all the prices should be formatted to two decimal places.
Note: If you are not a Java programmer, you may want to look at the Java documentation for the
DecimalFormatter class to review documentation on patterns.
https://docs.oracle.com/javase/8/docs/api/java/text/DecimalFormat.html
date: $.departureDate
372
28. Look at the preview; you should see the date property is a String.
29. Change the DataWeave expression to use the as operator to convert departureDate to a date
object; you should get an exception.
Note: If you are not a Java programmer, you may want to look at the Java documentation for the
DateTimeFormatter class to review documentation on pattern letters.
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
373
33. Look at the preview; you should see date is now a Date object.
Format a date
34. Use the as operator to convert the dates to strings, which can then be formatted.
35. Look at the preview section; the date is again a String – but with a different format.
36. Use the format schema property with any pattern letters and characters to format the date
strings.
37. Look at the preview; the dates should now be formatted according to the pattern.
374
Walkthrough 11-6: Use DataWeave operators
In this walkthrough, you continue to work with the flights JSON posted to the flow. You will:
375
Order data
6. In the preview section, look at the flight prices; the flights should not be ordered by price.
7. Change the DataWeave expression to use the orderBy operator to order the objects by price.
payload.listAllFlightsResponse.*return map {
…
} orderBy $.price
9. Look at the PDX flights; they should be ordered by date in addition to price.
10. Change the DataWeave expression to first sort by date and then by price.
payload.listAllFlightsResponse.*return map {
…
} orderBy $.date orderBy $.price
11. Look at the preview; the flights should now be ordered by price and flights of the same price
should be sorted by date.
376
Remove duplicate data
12. Use the distinctBy operator in the DataWeave expression to remove any duplicate objects.
payload.listAllFlightsResponse.*return map {
…
} orderBy $.date orderBy $.price distinctBy $
13. Look at the preview; you should now get only four flights instead of five.
14. Add a seats field that is equal to the emptySeats field and coerce it to a number.
15. Look at the preview section; you should get five flights again.
377
Filter data
16. In the preview section, look at the values of the seats properties; you should see some are
equal to zero.
17. Add a filter to the DataWeave expression that removes any objects that have availableSeats
equal to 0.
payload.listAllFlightsResponse.*return map {
…
} orderBy $.date orderBy $.price distinctBy $ filter ($.seats !=0)
18. Look at the preview; you should no longer get the flight that had no available seats.
378
Walkthrough 11-7: Define and use custom data types
In this walkthrough, you continue to work with the flight JSON posted to the flow. You will:
379
7. Look at the preview; the prices should still be formatted as strings to two decimal places.
380
11. In the DataWeave expression, set the map objects to be of type flight.
payload.listAllFlightsResponse.*return map {
…
} as :flight orderBy $.date orderBy $.price distinctBy $ filter
($.seats !=0)
destination: $.destination,
13. Change the other keys to match the names of the Flight class properties:
• plane to planeType
• date to departureDate
• seats to availableSeats
payload.listAllFlightsResponse.*return map {
…
} as :flight orderBy $.departureDate orderBy $.price distinctBy $
filter ($.availableSeats !=0)
15. Look at the preview; you should now get an ArrayList of Flight objects.
381
Walkthrough 11-8: Call MEL functions and other flows
In this walkthrough, you continue to work with the DataWeave transformation in getMultipleFlightsFlow.
You will:
4. Place the expression-language tags on different lines and place the cursor between them.
5. Type <g, press Ctrl+Space, and select global-functions; a global-functions tag set should be
added.
382
6. Place the global-functions tags on different lines and place the cursor between them.
7. Use the def keyword to define a function called getNumSeats with an argument called type.
def getNumSeats(type){
}
8. Inside the function, add an if/else block that checks to see if type contains the string 737.
if (type.contains('737')){
}
if (type.contains('737')){
return 150;
} else {
return 300;
}
383
12. Locate the exception in the console.
13. Return to global.xml and delete the http:config tag inside the configuration tag set.
<http:config useTransportForUris="false"/>
totalSeats: getNumSeats($.planeType)
20. Look at the issue you get; the Flight class does not have a totalSeats property assigned.
21. Remove as :flight from the DataWeave expression.
Note: You can also go add a new property to the Flight class.
384
22. Look at the preview; you should see the Flight objects now have a totalSeats property equal to
150 or 300.
if (payload.type.contains('737')){
385
30. Change the two return statements to set the payload with the values instead.
if (payload.type.contains('737')){
payload = 150;
} else {
payload = 300;
}
//totalSeats: getNumSeats($.planeType)
33. Add another property called totalSeats inside the transformation function.
34. Set totalSeats equal to the return value from the DataWeave lookup() function.
totalSeats: lookup()
35. Pass to lookup() an argument that is equal to the name of the flow to call: "getTotalSeatsFlow".
36. Pass an object to lookup() as the second argument.
37. Give the object a field called type (to match what the flow is expecting) and set it equal to the
value of the planeType field.
386
38. Look at the preview; the value for totalSeats can only be assigned by calling the flow at runtime.
387
44. Send the request; you should get JSON flight data returned and each flight should have a
totalSeats property equal to 150 or 300.
388
Module 12: Connecting to
Additional Resources
389
Walkthrough 12-1: Connect to a SaaS application (Salesforce)
In this walkthrough, you retrieve account records from Salesforce. You will:
Note: To complete this walkthrough, you need a Salesforce Developer account. Instructions for
creating a Salesforce developer account and getting an API access token are included in the
first walkthrough at the beginning of this student manual.
390
4. Look at the existing account data; a Salesforce Developer account is populated with some
sample data.
5. Notice that countries and postal codes are not displayed by default.
6. Click the Create New View link next to the drop-down menu displaying All Accounts.
7. Set the view name to All Accounts with Postal Code.
8. Locate the Select Fields to Display section.
9. Select Billing Zip/Postal Code as the available field and click the Add button.
10. Add the Billing Country field.
11. Use the Up and Down buttons to order the fields as you prefer.
12. Click the Save button; you should now see all the accounts with postal codes and countries.
391
Review the starting flow in the examples project
13. Return to Anypoint Studio.
14. Open the apdev-examples project.
15. Open accounts.xml and review the HTTP Listener endpoint.
17. In the Package Explorer, locate the new Salesforce library that was added.
20. In the Package Explorer, right-click src/main/resources and select New > File.
392
21. In the new File dialog box, set the file name to examples-DEV.properties and click Finish.
22. In examples-DEV.properties, create properties for your Salesforce username, password, and
security token.
Note: Instructions for creating a Salesforce Developer account and getting a security token are
included in the first walkthrough at the beginning of this student manual.
393
30. In the Global Element Properties dialog box, set the following values and click OK.
• Username: ${sfdc.username}
• Password: ${sfdc.password}
• Security Token: ${sfdc.token}
31. Click the Validate configuration button; you will get a Test Connection dialog box letting you
know if the connection succeeds or fails.
Note: If it failed, check to see if you have any extra whitespace in your entries.
394
Write the query
38. Click the Query Builder button.
39. In the Query Builder dialog box, select a type of Account (Account).
40. Select fields BillingCity, BillingCountry, BillingPostalCode, BillingState, BillingStreet, and Name.
395
48. Enter the following expression and press the Enter key.
#[payload.next()]
49. Expand the results; you should see the account data for the first account.
396
57. In Postman, make another request to http://localhost:8081/sfdc; you should see the Salesforce
accounts displayed.
397
62. Click OK.
63. Examine the generated query.
398
Walkthrough 12-2: Connect to a file (CSV)
In this walkthrough, you load data from a local CSV file. You will:
• Add and configure a File endpoint to watch an input directory, read the contents of any added
files, and then rename and move the files.
• Use DataWeave to convert a CSV file to a string.
• Add a CSV file to the input directory and watch it renamed and moved.
• Restrict the type of file read.
• Add metadata to a file endpoint.
399
7. Rename the flow to getCSVAccountsFlow.
400
12. In the Transform Message properties view, look at the metadata for the input; there should be
no metadata for the payload but there should be metadata for variables and properties.
401
15. In the Logger properties view, set the message to display the payload.
23. Drag it back into the input folder; it will be read again and then moved to the output folder.
24. Leave this folder open.
402
25. Return to Anypoint Studio and look at the console; you should see the file contents displayed.
Note: You can do this in your computer's file browser or in Anypoint Studio. If you use Anypoint
Studio, you will need to right-click the project and select Refresh to see the file.
403
35. In the File Name Regex Filter dialog box, set the pattern to .*csv (not *.csv) and uncheck case
sensitive.
#[message.inboundProperties.originalFilename].backup
40. Move the accounts.csv.backup file from the output folder back to the input folder; it should not
be processed and moved to the output folder.
404
41. Return to Anypoint Studio and stop the project.
42. In the Package Explorer, right-click the src/main/resources/input folder and select Refresh.
43. Expand the src/main/resources/input folder.
44. Right-click accounts.csv.backup and select Refactor > Rename.
45. In the Rename Resource dialog box, set the new name to accounts.csv and click OK.
46. In the File Properties view, delete the move to pattern.
Note: This will make it easier to test the application because you won’t have to keep renaming
the file as you move it back to the input directory.
50. In the drop-down menu that appears, make sure Output: Payload is selected.
51. Click the Edit button next to the drop-down menu.
52. In the Select metadata type dialog box, click the Add button.
53. In the Create new type dialog box, set the name to accounts_csv and click Create type.
405
54. In the Select metadata dialog box, change the type to CSV.
55. Make sure CSV includes header row is checked.
56. Click the Load from example button (the folder icon).
57. In the Load CSV fields from file dialog box, click the Browse button next to Example.
58. Browse to the project’s src/main/resources/input folder, select accounts.csv and click Open.
59. In the Load CSV fields from file dialog box, click OK.
406
60. In the Select metadata type dialog box, click Select.
61. In the File Properties view, click the Output tab of the metadata explorer again; the payload
should now have associated metadata and be shown to be a List <CSV>.
62. In the Transform Message Properties view, look at the payload metadata in the input section;
the payload should now have associated metadata.
63. Save the file.
407
Walkthrough 12-3: Poll a resource
In this walkthrough, you poll a database. You will:
• Use a form to add accounts for a specific postal code to an accounts table in a database.
• Create a flow with a Poll scope as the message source.
• Poll a database every 5 seconds for records with a specific postal code.
• Use a poll watermark to track the ID of the latest record retrieved.
• Use the watermark to only retrieve new records with that postal code from the database.
408
4. Click the Create More Accounts button.
5. Add a new record with a specific postal code; you will retrieve this record in this walkthrough
and insert it into your Salesforce account in the next module.
11. Drag a Database connector from the Mule Palette to the poll scope.
12. Add a Logger to the process section of the flow.
409
13. In the Logger properties view, set the message to display the payload.
Note: Instead of polling the database directly, you could use the poll scope to make periodic
requests to an API that governs access to the database.
• Host: ${db.host}
• Port: ${db.port}
• User: ${db.user}
• Password: ${db.password}
• Database: ${db.database}
21. Under Required dependencies, click the Add File button next to MySQL Driver.
22. Navigate to the student files folder, select the MySQL JAR file located in the resources folder,
and click Open.
23. Back in the Global Element Properties dialog box, click the Test Connection button; you should
get a successful test dialog box.
410
24. Click OK to close the dialog box.
25. Click OK to close the Global Element Properties dialog box.
SELECT *
FROM accounts
WHERE postal = '94108'
Note: Right now, all records with matching postal code are retrieved – over and over again.
Next, you will modify this so only new records with the matching postal code are retrieved.
411
34. Set the watermark to store the max accountID returned by setting the following values.
412
39. In the processing strategy drop-down menu, select synchronous.
46. Resume the application multiple times; the same records should still be selected over and over
again.
47. Stop the project and switch perspectives.
413
Modify the database query to use the watermark
48. In the Database properties view, modify the query so it only returns records for your postal code
and with accountID values greater than the watermark lastAccountID value.
Note: By default, the watermark is stored in a persistent object store so its value is retained
between different executions of the application.
414
53. Make sure your apdev-examples project is selected and then on the General tab, scroll down
and change Clear Application Data from Never to Prompt.
54. Click Run; you should be prompted to clear the application data.
55. In the Clear Application Data dialog box, click Yes.
415
Test the application
56. Look at the console; you should see the latest matching records retrieved from the database
again – but this time, only once.
57. Watch the console and see that all subsequent polling events retrieve no records.
416
Walkthrough 12-4: Connect to a JMS queue (ActiveMQ)
In this walkthrough, you read and write messages from a JMS topic. You will:
5. In the JMS properties view, leave the exchange pattern set to one-way.
417
6. Select topic and set it to apessentials.
Note: If you do not have access to port 61616, set jms.broker equal to vm://localhost instead.
418
15. In the Global Element Properties dialog box, change the broker URL to the property
${jms.broker}.
16. Set the Specification to v1.1.
419
23. Copy and paste or drag the JAR file into the lib folder.
24. Right-click the JAR file in the Package Explorer and select Build Path > Add to Build Path; you
should now see it under Referenced Libraries.
Note: Adding activemq-all.jar can create conflicts with other dependencies in projects, so it is
recommended that you only add only the JAR files you need in relation to what you need
ActiveMQ for. For more details, see the documentation at https://docs.mulesoft.com/mule-user-
guide/v/3.8/activemq-integration.
420
31. In the form, enter your name and a message and click Send.
421
Display names with the messages
41. In the Logger properties view, change the message to use an expression to display the name
and message.
49. Drag out a JMS connector from the Mule Palette and drop it into the process section of the flow.
422
50. In the JMS Properties view, select topic and set it to apessentials.
51. Set the connector configuration to the existing Active_MQ.
Set a message
52. Add a Set Payload transformer between the HTTP and JMS connector endpoints.
53. In the Set Payload Properties view, change the display name to Set JMS message.
54. Set the value to a message query parameter.
#[message.inboundProperties.'http.query.params'.message]
57. Select Set Property and set the name to name and the value to your name.
Note: You can set this to a query parameter instead if you prefer.
423
Test the application and post messages
58. Save the file to redeploy the project.
59. Make a request to http://localhost:8081/jms?message=Hello.
60. Look at the console; you should see your name and message displayed – along with those of
your classmates.
424
Walkthrough 12-5: Find and install not-in-the-box connectors
In this walkthrough, you learn how to add a new connector to Anypoint Studio. You will:
425
Review the Salesforce connector details
4. Search for just the select connectors.
426
9. Review the versions and see if the latest version is installed or not; you should see Installed or
Install above the versions at the top of the window.
10. Select an older version in the versions list; you should now see a clickable Install button.
11. To return to the assets list, click the Assets list link on the left side of the page.
427
13. Search for and select the Slack Connector (or any other connector you're interested in).
14. Select it and review its documentation; you should see this is a community connector and not
supported by MuleSoft.
428
16. Wait until an Install dialog box appears in Anypoint Studio.
Note: You can also install connector’s directly from Anypoint Studio. From the main menu bar,
select Help > Install New Software. In the Install dialog box, click the Work with drop-down
button and select Anypoint Connectors Update Site. Drill-down into Community and select the
Slack Connector (or some other connector).
429
Locate the new connector in Anypoint Studio
22. After Anypoint Studio restarts, locate the new connector in the Connectors section of the Mule
Palette.
430
Module 13: Processing Records
431
Walkthrough 13-1: Process items in a collection individually
In this walkthrough, you split a collection and process each item in it. You will:
• Use the For Each scope element to process each item in a collection individually.
• Look at the thread used to process each record.
432
9. In the Mule Debugger view, look at the payload value.
10. Step to the For Each scope; the payload should be an ArrayList of LinkedHashMaps.
11. Step into the For Each scope; the payload should be a LinkedHashMap.
12. Look at the console; you should see the data for the first record.
13. Step through the application; you should see each record displayed.
14. Step through to the Logger after the For Each scope; the payload should be an ArrayList again.
15. Step to the end of the application.
16. Stop the project and switch perspectives.
433
Look at the processing threads
17. In the console, locate the thread number used to process each record in the collection; the
same thread should be used for each: apdev-examples.getCSVAccountsFlow.stage1.02.
434
Walkthrough 13-2: Create a batch job for records in a file
In this walkthrough, you create a batch job to process records in a CSV file. You will:
435
6. Add a Variable transformer at the end of input phase.
7. In the Variable properties view, change the display name to Set size flow variable and select Set
Variable.
8. Set the name to size and the value to #[payload.size()].
436
19. Add a Logger to the second batch step.
20. Set its message to #[recordVars.rname].
21. Add a Logger to the on complete phase.
Stop the other flow watching the same file location from being executed
22. Double-click getCSVAccountsFlow.
23. In the getCSVAccountsFlow properties view, set the initial state to stopped.
437
30. Step to the Logger in the first batch step.
31. Click the Record tab; you should see the rname flow variable.
32. Step through the rest of the records in the first batch step and watch the payload, the fname
flow variable, and the rname record variable.
33. Step into the second batch step and look at the payload, the flow variables, and the record
variables; you should see the rname record variable and size flow variable but not the fname
flow variable.
34. Step through the rest of the records in the second batch step.
35. Step into the on complete phase; you should see the payload is an ImmutableBatchJobResult.
36. Locate the values for totalRecords, successfulRecords, and FailedRecords.
438
37. Step to the end of the application.
38. Stop the project and switch perspectives.
439
Walkthrough 13-3: Create a batch job to synchronize records from
a database to Salesforce
In this walkthrough, you create a batch job to retrieve records from a legacy database and insert them
into Salesforce if they do not already exist. You will:
• Create a batch job that polls a database for records with a specific postal code.
• Use a Message Enricher scope to check if a record already exists in Salesforce (an account
with the same Name) and stores the result in a record variable and retains the original payload.
• Add a second batch step with a filter that only allows new records (records that don’t already
exist in Salesforce) to be added to Salesforce.
• Use a batch commit scope to commit records in batches.
440
6. Set its message to display each record – the message payload in that phase – on a new line.
14. Configure the Salesforce endpoint to use the existing Salesforce connector configuration.
15. Set the operation to Query.
16. Click the Query Builder button.
17. Set the type to Account (Account).
18. Select a field of Name; it does not matter what you select, you just want to see if any records
are returned.
19. Click the Add Filter button.
441
20. Create a filter to check if the Name field in the record being processed already exists in the
database.
Name = #[payload.Name]
Note: Right now, you can use payload.name or payload.Name because the payload is a
caseSensitiveHashMap. Later this walkthrough, however, you will transform the Map to an
Account object with a Name property and will have to refer to this as payload.Name.
442
22. Review the generated query.
26. In the Message Enricher Properties view, set the source to an expression that checks to see if
any records were returned, i.e. if there is a payload.
#[payload.size() > 0]
443
27. Set the target to assign the result of the source expression to a record variable called exists.
#[recordVars.exists]
#[!recordVars.exists]
444
32. Debug the project and clear the application data.
33. Step through the application and watch the record variables; you should see exists set to false
for records with names that don’t exist in Salesforce and true for those that do.
Add an account to Salesforce manually with a name matching one of the database
records
35. In a web browser, navigate to http://login.salesforce.com/ and log in with your Salesforce
Developer account.
36. Click the Accounts link in the main menu bar.
37. In the view drop-down menu, select All Accounts with Postal Code and click the Go button.
38. Click the New Account button.
39. Enter an account name (one that matches one of the accounts you added with your postal code
to the MySQL database) and click Save.
445
42. Step through the application and watch the record variables; you should now get one record that
gets its exists record variable set to true.
45. Configure the Salesforce endpoint to use the existing Salesforce connector configuration.
46. Set the operation to Create.
47. Set the sObject type to Account (Account).
48. Leave the sObject field mappings to from expression #[payload].
446
49. Look at the input tab of the metadata explorer; you should see a problem letting you know that
payload is a Map in this step but the outbound Salesforce endpoint is expecting a List of
Account objects.
50. Drill-down in both values and look at the fields.
Transform the objects into the Account objects that the endpoint expects
51. Add a Transform Message component after the poll scope in the input phase.
Note: You want to transform all the records at once in the input phase – not one by one in the
processing phase.
52. In the Transform Message Properties view, look at the input section and see the input has
associated metadata.
447
53. Look at the output section; it has no metadata and no way to add any.
54. Copy the Salesforce endpoint in the second batch step and paste it after the Transform
Message component in the batch input phase.
Note: You are temporarily adding this Salesforce endpoint after the database endpoint so
DataSense will work to create the mappings. You could instead add the DataWeave
transformation to the process records phase, but this would add additional overhead.
55. Look at the output section of the Transform Message Properties view again; you should now
see metadata for a List of Account objects.
448
56. Drag properties from the input section to the output section to make the following mappings:
• country to BillingCountry
• city to BillingCity
• street to BillingStreet
• name to Name
• state to BillingState
• postal to BillingPostalCode
449
Create the List that the endpoint is expecting
59. Return to the Properties view for the Salesforce endpoint in the second batch step.
60. Look at the input tab of the metadata explorer; you should see that the outbound Salesforce
endpoint is expecting a List of Account objects.
61. Drag a Batch Commit scope from the Mule Palette and drop it in the second batch step.
62. Add the Salesforce endpoint to it.
63. In the Batch Commit properties view, set the commit size to 10.
450
66. Return to Salesforce in a web browser and look at the accounts; you should see the records
from the legacy MySQL database are now in Salesforce.
Note: You could also check for the records by making a request to http://localhost:8081/sfdc.
67. Run the application again but do not clear the application data; no records should be processed.
68. Return to salesforce.com and locate your new record(s); they should have been inserted only
once.
69. Return to Anypoint Studio and stop the project.
451