Integration Workbook
Integration Workbook
Integration Workbook
© Copyright 2000–2013 salesforce.com, inc. All rights reserved. Salesforce.com is a registered trademark of salesforce.com, inc., as are other
                     names and marks. Other marks appearing herein may be trademarks of their respective owners.
                                                                                                                                                                           Table of Contents
Table of Contents
   Tutorial #2: Connect the Warehouse App with an External Service ........................................................6
           Step 1: Create an External ID Field on Invoice........................................................................................................................6
           Step 2: Create a Remote Site Record........................................................................................................................................6
           Step 3: Create an Integration Apex Class..................................................................................................................................7
           Step 4: Test the @future Method..............................................................................................................................................9
           Step 5: Create a Trigger to Call the @future Method...............................................................................................................9
           Step 6: Test the Complete Integration Path...........................................................................................................................10
           Summary.................................................................................................................................................................................11
                                                                                                i
Force.com Integration Workbook
      Intended Audience
      This workbook is intended for developers new to the Force.com platform but have basic working knowledge in Java.
      Tell Me More....
      This workbook is designed so that you can go through the steps as quickly as possible. At the end of some steps, there is an
      optional Tell Me More section with supporting information.
      •   You can find the latest version of this and other workbooks at developer.force.com/workbooks.
      •   To learn more about Force.com and to access a rich set of resources, visit Developer Force at
          http://developer.force.com.
                                                                   1
Before You Begin
               Note: After you’ve gone through this workbook, you can un-install the Warehouse data model and sample data from
               your organization by navigating to Installed Packages under Setup and deleting the Warehouse package.
                                                                    2
Tutorial #1: Create a New Heroku Application                                                               Step 1: Clone the Github Project
      1. Open a command line terminal. For Mac OS X users, this can be done by going to the Terminal program, under
         Applications/Utilities. For PC users, this can be done by going to the Start Menu, and typing cmd into the Run
         dialog.
      2. Once in the command line terminal, change to a directory where you want to download the example app. For example, if
         your directory is “development,” type cd development.
      3. Execute the following command:
      1. In the command line terminal, change directory to the spring-mvc-fulfillment-base folder you created in the last
         step:
cd spring-mvc-fulfillment-base
2. Execute the following command to login to Heroku (followed by Heroku login credentials, if necessary):
heroku login
heroku create
          Heroku creates a local git repository as well as a new repository on its hosting framework, where you can push applications,
          and adds the definition for that remote deployment for your local git repository to understand. This makes it easy to leverage
          git for source control, make local edits, and deploy your application to the Heroku cloud.
                                                                     3
Tutorial #1: Create a New Heroku Application                                                                      Step 3: Test the Application
           All application names on Heroku must be unique, so you’ll see messages like the following when Heroku creates a new
           app:
                   Important: The output above shows that the new application name is quiet-planet-3215. You might want
                   to copy and paste the generated name into a text file or otherwise make a note of it. Throughout this workbook,
                   there are references to the application name that look like {appname} that should be replaced with your application
                   name. So, if your application name is quiet-planet-3215, when a tutorial step prompts you to enter a URL
                   with the format https://{appname}.herokuapp.com/_auth, use:
                   https://quiet-planet-3215.herokuapp.com/_auth.
           The process will take a while as it copies files, grabs any required dependencies, compiles, and then deploys your application.
      5. Once the process is complete, you can preview the existing application by executing:
heroku open
      Tell Me More...
      Look carefully as the git push happens and you’ll see some magic. Early on, Heroku detects that the push is a Spring MVC
      app, so it installs Maven, builds the app, and then gets it running for you, all with just a single command.
                                                                       4
Tutorial #1: Create a New Heroku Application                                                                                   Summary
      5. In the browser URL bar, select the invoice record ID, which is everything after salesforce.com in the URL. It should
         look something like a01E0000000diKc. Copy the ID to your clipboard.
      6. Return to the browser window or tab showing your Heroku application.
      7. Paste the invoice record ID into the field under Id.
      8. Click Create. An order is created with the Invoice ID. Your page looks something like:
     Summary
      Heroku’s polyglot design lets you easily deploy your applications with industry-standard tools, such as git. Typically, teams
      use local development environments, like Eclipse, and in fact Heroku has released an Eclipse plugin for seamless integration
      with Eclipse. You can also interact with Heroku on the command line and directly access logs and performance tools for your
      applications.
                                                                   5
Tutorial #2: Connect the Warehouse App with an External                                   Step 1: Create an External ID Field on Invoice
Service
                                                                    6
Tutorial #2: Connect the Warehouse App with an External                                           Step 3: Create an Integration Apex Class
Service
Now any Apex code in your app can call the fulfillment Web service.
      Tell Me More...
      Just for fun, you can skip Step 2 and create and test the callout in Step 3 and Step 4 below to observe the error message that
      is generated when an app attempts to callout to a URL without permission. Don't forget to come back and add the remote
      site record, though!
// 1) see above
                                                                     7
Tutorial #2: Connect the Warehouse App with an External                                     Step 3: Create an Integration Apex Class
Service
// 2) see above
// 3) see above
      This code collects the necessary data for the remote service, makes the remote service HTTP call, and processes any data
      returned by the remove service to update local invoices with the corresponding external IDs. See the embedded comments in
      the code for more information.
                                                                 8
Tutorial #2: Connect the Warehouse App with an External                                                   Step 4: Test the @future Method
Service
         This small snippet of Apex code retrieves the ID for a single invoice and calls your @future method using this ID.
      3. Click the Open Log checkbox.
      4. Click Execute. You should see two entries appear in the logs. Double click the second line — it should have Future
         Handler as its operation and a status of Success.
      5. Click the Filter checkbox under the Execution Log and type DEBUG as the filter text. Scroll down and double click the
         last line of the execution log. You should see a popup with the response from the fulfillment Web service that looks
         something like:
      Now that you have a functional @future method that can call the fulfillment Web service, it's time to tie things together
      with a trigger.
      1. Go to the Invoice custom object from Setup by clicking Create > Objects > Invoice.
      2. Scroll down to Triggers, click New, and paste the following code in place of the trigger skeleton:
                                                                     9
Tutorial #2: Connect the Warehouse App with an External                                        Step 6: Test the Complete Integration Path
Service
3. Click Save.
      The comments in the code explain what is happening. In particular, understand that Force.com triggers must be able to handle
      both single row and bulk updates because of the varying types of calls that can fire them (single row or bulk update calls). The
      trigger creates a list of invoice IDs that have been closed in this update, and then calls the @future method once, passing the
      list of IDs.
The following screen shows the Invoices tab before any changes have been made:
                                                                     10
Tutorial #2: Connect the Warehouse App with an External                                                                       Summary
Service
The following screen shows the Invoices tab after the asynchronous call has returned the new order ID:
     Summary
      Congratulations! Your app is sending invoices for fulfillment. You have successfully created an asynchronous Apex class that
      posted invoice details to your fulfillment app hosted on Heroku. Of course, your external application could reside anywhere
                                                                  11
Tutorial #2: Connect the Warehouse App with an External                                                                    Summary
Service
      as long as you have access via Web services. Your class uses open standards including JSON and REST to transmit data, and
      a trigger on Invoices to execute the process.
                                                                12
Tutorial #3: Update the Heroku App                                                                  Step 1: Configure Your Connected App
Note: Be sure to replace {appname} with your actual Heroku app name.
      1. Return to the command line, and make sure you’re in the spring-mvc-fulfillment-base folder.
      2. Enter the following command to fetch the “full” branch and merge it with your master branch, all in one step:
                                                                    13
Tutorial #3: Update the Heroku App                                           Step 3: Update the User Interface with Invoice Information
3. You need to set your Access keys to your Heroku application. Enter:
          Replace PUBLICKEY with the Consumer Key. Similarly, replace PRIVATEKEY with the Consumer Key. It may be
          helpful to do this in a text editor before putting it on the command line.
      4. Execute the following command to push the local changes to Heroku:
      5. In a browser tab or window, navigate to https://{appname}.herokuapp.com to see the changes (refresh your browser
         if needed).
      By adding an OAuth flow to your app, your app can get a user’s permission to have session information without requiring the
      third-party server to handle the user’s credentials. With this added to the project, the fulfillment application can use the
      Force.com REST API to access information directly from the user’s instance.
      Tell Me More...
      You can review all of the changes brought in by this branch on github at:
      https://github.com/sbob-sfdc/spring-mvc-fulfillment-base/compare/master...full. Notice that the
      changes use the Force.com REST API to manipulate Invoice records. Look at InvoiceServiceImpl.java in particular
      to see how it creates, queries, retrieves and deletes invoices. This tutorial only uses the findOrder() method. The others
      are included for your reference.
add:
           <h3>Invoice</h3>
           <p>Number: <c:out value="${invoice.number}"/></p>
           <p>Status: <c:out value="${invoice.status}"/></p>
                                                                  14
Tutorial #3: Update the Heroku App                                             Step 3: Update the User Interface with Invoice Information
7. Wait for the push to finish, and navigate to your fulfillment app in the browser (refreshing if necessary) to see the changes.
      Notice that, given an ID, this code retrieves the corresponding invoice record. Because there might be mock ID's in the
      database that are not in Force.com, the app handles the corresponding exception by showing default data. Adding the invoice
      to the model makes it available to the view. Now when you test the fulfillment application, it will show the invoice information
      currently in your Force.com instance by grabbing the information via the REST API using the record ID. Your order detail
      page might look something like:
      Tell Me More...
      To really see the application in motion, you can edit information on Force.com (like the Description of the Invoice) and
      see it represented the next time you load that order in your Heroku app.
      Notice that the Web service call from Force.com to create orders is not secured. Securing this call goes beyond the scope of
      this workbook, but a simple solution would be to set up a shared secret between the Force.com app and the fulfillment app.
      The Force.com app would create an HMAC of the parameters in the request, using the secret, and the fulfillment app would
      verify the HMAC.
                                                                    15
Tutorial #4: Add Your App to Salesforce Using Force.com                              Step 1: Update your Canvas App with a New Branch
Canvas
      1. Return to the command line, and make sure you’re in the spring-mvc-fulfillment-base folder.
      2. Enter the following command to fetch the canvas branch and merge it with your master branch, all in one step:
      4. In a browser tab or window, navigate to https://{appname}.herokuapp.com to see the changes (refresh your browser
         if needed).
      Tell Me More...
      You can review all of the changes brought in by this branch on GitHub at
      https://github.com/sbob-sfdc/spring-mvc-fulfillment-base/compare/full...canvas.
      Notice that the changes use the signed request from the Force.com Canvas API and not the Heroku-initiated OAuth from
      Tutorial 3, Step 2 and also use the Force.com REST API to manipulate invoice records. Look at CanvasUiController.java
      in particular to see how it retrieves, parses, and sets the signed request for use by the app. Also, order.jsp has changed to
      present an easier-to-use screen on the invoice page layout. This tutorial has only set the signed request for use on the canvasui
      page and the orders page in the app.
                                                                    16
Tutorial #4: Add Your App to Salesforce Using Force.com                   Step 2: Edit The Connected App Details and Enable it for
Canvas                                                                                                         Force.com Canvas
      If you look at CanvasUiController.java, you’ll see something like the following, which shows Heroku obtaining a signed
      request and validating it. We’re leveraging the OAUTH_CLIENT_SECRET Heroku key set in Tutorial 3, Step 2 to validate the
      signed request. After the validation, the signed request is passed to order.jsp where the browser can access it.
        @Controller
        @RequestMapping(value="/canvasui")
        public class CanvasUIController {
             @Autowired
             private OrderService orderService;
             @Autowired
             private InvoiceService invoiceService;
             @Autowired
             public CanvasUIController(Validator validator) {
                 this.validator = validator;
             }
             @RequestMapping(method= RequestMethod.POST)
             public String postSignedRequest(Model model,
            @RequestParam(value="signed_request")String signedRequest, HttpServletRequest request){
                            Invoice invoice;
                            try {
                                invoice = invoiceService.findInvoice(order.getId());
                            } catch (ApiException ae) {
                                // No match
                                invoice = new Invoice();
                            }
                            model.addAttribute("invoice", invoice);
                            return "order";
                       }
                  }
                  return getOrdersPage(model);
             }
             @RequestMapping(method=RequestMethod.GET)
             public String getOrdersPage(Model model) {
                 model.addAttribute("order", new Order());
                 model.addAttribute("orders", orderService.listOrders());
                  return "orders";
             }
                                                                17
Tutorial #4: Add Your App to Salesforce Using Force.com        Step 2: Edit The Connected App Details and Enable it for
Canvas                                                                                              Force.com Canvas
        <html>
         <head>
          <title>Order</title>
          <link rel="stylesheet" href="<c:url value="/resources/blueprint/screen.css" />
          " type="text/css" media="screen, projection">
          <link rel="stylesheet" href="<c:url value="/resources/blueprint/print.css" />"
        type="text/css" media="print">
          <!--[if lt IE 8]>
           <link rel="stylesheet" href="<c:url value="/resources/blueprint/ie.css" />
          " type="text/css" media="screen, projection">
          <![endif]-->
          <script type="text/javascript" src="<c:url value="/resources/jquery-1.4.min.js" /> ">
          </script>
          <script type="text/javascript" src="<c:url value="/resources/json.min.js" /> ">
          </script>
                <script type="text/javascript" src="<c:url value="/resources/canvas-all.js" /> ">
            </script>
                <script>
                    // Get the Signed Request from the CanvasUIController
                    var sr = JSON.parse('${not empty signedRequestJson?signedRequestJson:"{}"}');
                       // This function will be called when the "Delete Order" button is clicked.
                       // It will delete the record from the Heroku database.
                       function deleteHandler(){
                           $.deleteJSON("/order/${order.orderId}", function(data) {
                               alert("Deleted order ${order.orderId}");
                                                          18
Tutorial #4: Add Your App to Salesforce Using Force.com                          Step 3: Configure Access to Your Force.com Canvas App
Canvas
                                 location.href = "/orderui";
                             }, function(data) {
                                 alert("Error deleting order ${order.orderId}");
                             });
                             return false;
                        }
                      // This function gets the instance the user is on for a page referesh
                      function getRoot() {
                          return sr.client.instanceUrl;
                      }
                  </script>
         </head>
         <body>
                <div id="bodyDiv" style="width:inherit;">
                    <div id="myPageBlockTable">
                        <h2 id="OrderTitle">
                            Order Number: <c:out value="${order.orderId}"/>
                        </h2>
                        <table id="myTable" width="100%">
                            <col width="20%">
                            <tr><td class="myCol">Invoice Id:</td><td class="valueCol">
                            <c:out value="${invoice.id}"/></td></tr>
                            <tr><td class="myCol">Invoice Number:</td><td class="valueCol">
                            <c:out value="${invoice.number}"/></td></tr>
                           <tr><td class="myCol">Status:</td><td class="valueCol" valign="center">
                                   <c:out value="${invoice.status}"/>
                                       <!-- Display a green check if the order is Shipped, or a red x if
        not shipped -->
                                <c:choose>
                                    <c:when test="${invoice.status == 'Shipped'}">
                                        <img src="/resources/images/shipped.png" />
                                    </c:when>
                                    <c:otherwise>
                                        <img src="/resources/images/pending.png" />
                                    </c:otherwise>
                                </c:choose>
                            </td></tr>
                        </table>
                        <!-- Display the Back and Delete Order Button if viewed outside
                        of salesforce (no signed request). -->
                        <!-- Display the Finalize Button if viewed inside of salesforce and
                        the Status is not Shipped. -->
                        <c:choose>
                            <c:when test="${empty signedRequestJson}">
                                <button onclick="location.href='/orderui'">Back</button>
                                <button id="deleteButton">Delete Order</button>
                            </c:when>
                            <c:otherwise>
                                <c:if test="${invoice.status ne 'Shipped'}">
                                    <button id="finalizeButton">Finalize</button>
                                </c:if>
                            </c:otherwise>
                        </c:choose>
                    </div>
                </div>
         </body>
        </html>
                                                                    19
Tutorial #4: Add Your App to Salesforce Using Force.com                     Step 4: Make Your Force.com Canvas App Available from the
Canvas                                                                                                                   Chatter Tab
Your app is now available to anyone with the System Administrator profile.
      The values you selected in the Locations field when creating the connected app in Step 2: Edit The Connected App Details
      and Enable it for Force.com Canvas on page 16 determine where an installed canvas app appears. When an app is made
      available to the Chatter tab, there’s nothing we need to do for this step. If you log into your Salesforce org and select the
      Chatter tab, you’ll see that your canvas app appears in the app navigation list.
               Note: When displaying the list of orders on the Chatter Tab, remember that orders.jsp has been set up to handle
               the signed request POST. However, if you click into a record from this page, you are redirected to orderui, which
               uses the OAuth. If the Heroku OAuth flow is inactive, you may receive an error when viewing the individual order.
                                                                   20
Tutorial #4: Add Your App to Salesforce Using Force.com                     Step 5: Use Visualforce to Display the Canvas App on a Record
Canvas
               <apex:page standardController="Invoice__c">
                   <apex:canvasApp developerName="CanvasFulfillment"
           parameters="{'orderId':'{!Invoice__c.OrderId__c}'}" width="100%"/>
               </apex:page>
                                                                   21
Tutorial #4: Add Your App to Salesforce Using Force.com                                                                          Summary
Canvas
Now when users go to an invoice record, they’ll see the canvas app right on the record detail page:
      Notice the Finalize button in the canvas app. If the invoice is not in a shipped status, the red “X” and Finalize will show in
      the app. If you click Finalize, Heroku uses the Force.com Canvas API to call the REST API and update the invoice status
      field. Once the status is set to 'Shipped', the red “X” is replaced and Finalize is hidden.
     Summary
      Congratulations! With a combination of OAuth authentication, the REST API, Apex triggers, @future callouts, the polyglot
      framework of the Heroku platform, Force.com Canvas, and Visualforce, you created and deployed a bi-directional integration
      between two clouds.
      This workbook touches upon just one example of the many ways to integrate your applications with Salesforce. One integration
      technology not touched on is the Streaming API that lets your application receive notifications from Force.com whenever a
      user changes Salesforce data. You can use this in the fulfillment application to monitor when a user updates invoices and to
      automatically update the application pages accordingly. Visit http://developer.force.com to learn more about all the
      ways you can integrate your application with Force.com.
22