SOAP, JMS, Restful, SFTP… Sometimes your integration just comes to the point in which you need to be able to download a file from your browser. From Ubuntu One all the way to Dropbox and Google Drive, the number of file storage services on the cloud just keeps climbing. One that is particularly gaining a lot of momentum and putting a lot of effort on cloud to cloud integration is Box, so we decided to build a Cloud Connector for it and we’ll show it to you in this post.

So we could go with really quick examples of each of the many operations that the connector exposes but let’s face it, you can see that on your own looking at the connector’s documentation. Instead, let’s take a quick tour looking at how you can use the connector and the power of Mule Studio to download an Attachment from SalesForce and upload it into your box account.

Install the connector

If you want to use the connector on an application developed “the traditional way”, you can find the connector’s install guide and API reference here.

However, this post is all about using Studio so let’s take a look at how to make the connector available in Studio using the new Eclipse update sites!

First, go to the help menu and click on “Install New Software”

Then, click on the add site button:

Then register the new update site using this URL: http://repository.mulesoft.org/connectors/releases

Then Select the box cloud connector and install it:

Last step! Accept the license agreement:

You’re all set! After finishing the installation, Studio will restart and you’ll have the box connector available on the Cloud Connectors pallete:

Getting Started with authentication

box uses an authentication mechanism that is very similar to OAuth although it’s not OAuth. However, the principle is the same, you register your application and in return get an apiKey. You then use that apiKey to request an access token which you’ll use on your requests. The details of how to set this up on the Box side are in this page.

From the Mule side of the house, it is also very simple! First, create a configuration for your connector:

Let’s take a close look at this config. The really important and mandatory value here is the Api Key, which you obtained when you registered your app at box. Then, what are the other params all about? Well, let’s see it with an example!

Get the Ticket

Whatever approach you take, you need to start by requesting a ticket, using the Get Ticket operation.

What this operation does is to go to box with the Api Key you supplied and request access to the system. box replies with a ticket id that the connector will return on the payload but will also store internally. You then need to navigate to https://www.box/api/1.0/auth/<<your_ticket_here>> where you will be prompted for your credentials. This way, only box is aware of your account and password.

Get the Authentication Token

Once you have validated your ticket using your credentials, the cloud connector will store the ticket internally and will use it to retrieve the second piece of the security puzzle which is the authentication token. There are two ways of getting the token:

The first approach is to use a separate flow to manually go fetch it. All you have to do is use the Auth Token operation. This operation takes no parameters because the connector already knows the ticket. Your authentication then consists of these two flows:

The other alternative is to use the callback params. This basically means that you will provide a url and port in which you will ask box to deliver the authentication token using a callback post. Notice that for this to work, you have to:

  • Configure this very same url and port in box when you’re registering your application (the link provided before explains how to do this as well)
  • If your application is running behind a firewall, make sure to expose the proper host and port to the outside world

Let’s get ready to rummmmble!

let’s create a flow that takes these steps:

  • Listens for an http call that will trigger the integration process. For simplicity sake, we’ll assume that you’re already authenticated to box and that the id of the attachment to be transferred is known and provided as a query parameter. Again, this is not a realistic scenario, but we’ll assume that in order to maintain the example simple and demonstrative.
  • Then, we’ll query salesforce for this attachment
  • Finally, we’ll upload it to box

First, drop a new http inbound endpoint and create a new flow with it.  Let’s have this endpoint listening to the path “integrate”.

 

Now, it’s time to hit Salesforce. Go to the Cloud Connectors section on Studio’s components pallet and drop a SalesForce connector on the flow. Then create a new configuration that looks as follows (notice how placeholders are used for credentials and sensitive information):

So, we need to query sales force for the attachment with with the id we just got on the http query parameters. So set the connector to perform the query operation using this value:

Once the query is completed, the Sales Force connector will have changed your message’s payload to a List<Map<String, String>> in which each element of the list is a map that represents an attachment (in our case this list will be empty or have only one element since we requested an specific id).

At the same time, this map will contain three entries, each for the Id, Name and Body fields we just requested.

In order to upload this to box, we need to extract the file name and the attachment contents from the payload. But there’s a catch! the Sales Force API uses encoding to broadcast file contents over http (many web based applications do this, including box). So, we need to take that encoded content and transform it to a java.io.InputStream, which is what the box connector expects to perform an upload.

All of this can easily be done with the new (MEL) and some of the processors introduced in for easy message handling. You can totally use these features from Studio’s palette, but for the sake of shortness I’ll show you how to use those processors in the final XML:

Ok, so one final step! Go to the Cloud Connectors pallet and drop a box component at the end of your flow. Set it to perform the Upload Stream operation as described in this image:

A couple of things to notice about this last operation:

  • There’s no reference to the actual contents to be uploaded. The Upload Stream operation already knows that it should look for an InputStream on the message payload. The transformer on the prior step already did us the favor or guaranting that for us.
  • The Folder Id parameter is set to a default value of zero. In box, folder zero means the root folder. If you want to put it elsewhere just provided the corresponding id.
  • Last but not least, notice how the attachName property set on the message is used to tell box how the file should be named. Here we chose to use the same name it had on Sales Force, but you can use any naming convention you like.

That’s pretty much it! Let’s wrap this up by taking a look at how the completed flow looks like: 

I know what you’re thinking: “Pictures look pretty but where can I get the actual Mule config for this example??” Well, I uploaded it to box, you can get it following this link

So, that’s it! Here’s a simple example of how to take files hosted on a popular cloud service like Sales Force and share them in box. We also did it easily and in style using Mule Studio.

I hope you find this useful and feel free to shoot questions any time!

PS: I’d like to give a BIG thank you to Mariano Merlo for his great help at testing the connector and this sample iApp

No related posts.


11 Responses to “Upload your Salesforce.com attachments to Box using Mule Studio”

Yaman July 31st, 2012, 11:02 am

Nice!….You nailed it! cloud integrantion as pure as it can get, simple and straight to the point. Integrating my apps to Box is going to add a lot of value to my apps.

Thanks guys!!

Sodero July 31st, 2012, 12:33 pm

This is why Mule is my favourite tool for integration. Good to know I can know play with Box as well

anil October 4th, 2012, 2:06 am

nice demo have been looking out for this.
I’m facing difficulty in starting the mule flow its giving an error saying
listener on 8081 already registered

Mariano Gonzalez October 4th, 2012, 6:22 am

Hello Anil, nice to hear that you’ve been expecting this!. As for the port being already taken, I recommend using tools like netstat to determine which other process it taking over that port. Or you can just set the app’s endpoint in a different port.

Regards

anil October 4th, 2012, 8:11 pm

Hi Mariano,

Thanks for the prompt reply. i didn’t mean to say port being taken by a different application, the problem is mule tries to start two listeners on localhost:8081 as per your example and both are inbound endpoints. So it gives a listener error. the change i have done to use it is given below. But i’m still curious to know why it works on your environment and not on mine. Any thoughts appreciated.
We can discuss on skype: anilrpuliyeril or gtalk: anillraju@gmail.com .

#[groovy:message.getProperty('fileName',org.mule.api.transport.PropertyScope.INBOUND)]

message.payload;

Mariano Gonzalez October 5th, 2012, 6:35 pm

Anil,

If you want box me your application’s code and I’ll be happy to help you find the difference.

Best regards,

Mariano Gonzalez October 9th, 2012, 8:28 am

Hello Anil,

I took a look at your app and I don’t see anything wrong. So I decided to make a test application using your config and it started without any problems. I’ll be sending it the code of that app to your private email. The config is exactly the same you sent except for two things:

* I changed the connector version to 1.1.0 (no particular reason, just to avoid tempering with my Studio install)
* I changed the file endpoint path to be Mac compatible. You probably want to change that back to windows format

Best regards

Mule up your holiday’s pics: from Facebook to Box - M-Square December 26th, 2012, 10:43 am

[...] Box, the process of  setting up a Box application and authenticating to it was also covered in this post. Again, you can go ahead if familiar with it, reading is suggested before continuing.Last thing [...]

Jose Chama February 4th, 2013, 2:36 pm

Hi Mariano,

I am following all the steps you described in the blog but I am getting stuck in boxnet:upload-files.

I am getting the following error: “Failed to invoke uploadFiles. Message payload is of type: ByteArrayInputStream”

What am I missing?

Thanks a lot,
Jose

Mariano Gonzalez February 5th, 2013, 6:30 am

Hello Jose,

If you could send me your project plus the full logs I’ll be happy to take a look and help you.

Regards,

Leave a Comment