Using the DropBox API in the MuleSoft Anypoint Platform

Overview

MuleSoft has hundreds of connectors to numerous platforms which take away the need to write custom code. You can find them along with templates and examples on the Anypoint Exchange. The connectors generally wrap the platform APIs and expose all the available operations making it easier to setup integrations without any custom code. But what if the architecture of the flow prevents you from leveraging the connectors?

I recently ran into this scenario with a project that involved uploading files from a headless server to DropBox. Using the MuleSoft DropBox connector which wraps the REST API seemed like a no-brainer at first; but I ran into an architectural issue with the deployment. The initial design below shows how simple the project is, especially without the need to write any code.

The first flow (1) provides an HTTP endpoint where the user can be authenticated through OAuth to retrieve the access token from DropBox. Once authenticated, the second flow (2) can begin to upload files to DropBox. More information about how MuleSoft handles the OAuth process and storage of the token can found on this blog post. The design of this project works as expected but the issue is around the deployment. When deployed to a headless server, there’s no easy way to authenticate the application through the OAuth flow. Additionally, each re-deployment requires the application to be authenticated again which takes away the autonomy of the solution.

So I took a different approach to my project and started looking at the calling the DropBox REST API directly for uploading files. When setting up your application in DropBox, you can generate an access token which you can store and use without going through the OAuth flow.

Within my original project design, I removed the flow to authenticate the user through OAuth. I also replaced the DropBox connector in the second flow with the HTTP connector which allows me to easily make a REST API call. You can see the new flow below.

Setting up the HTTP Connector

For the HTTP connector to make the REST API call, setup requires configuring the request to make an HTTPS call to DropBox. The URL structure looks like the following:

https://content.dropboxapi.com:443/1/files_put/auto/<path/filename>

So the request configuration should look like the image below on the General tab. Be sure to set the Protocol: field to HTTPS and set the Port: to 443

The TLS/SSL tab also needs to be configured when making an HTTPS call. More information on how to set that up can be found here.

Back on the configuration screen, set the Method field to PUT and the Path field to the following:

1/files_put/auto/#[flowVars.originalFilename]

The last step is setting up the header parameters to pass the access token to the API. Under the Parameters section, click on Add Parameter and select header from the drop-down. Set the Name: to Authorization and set the Value: field to Bearer<YOUR_ACCESS_TOKEN_HERE>.

I’ve included a snipped of the Mule XML below:

<file:connector name="File_First" autoDelete="true" streaming="true" validateConnections="true" doc:name="File" />

<http:request-config name="Dropbox_HTTPS_Request_Configuration" protocol="HTTPS" host="content.dropboxapi.com" port="443" basePath="/" doc:name="HTTP Request Configuration">
    <tls:context>
        <tls:key-store type="jks" path="keystore.jks" keyPassword="<password>" password="<password>"/>
    </tls:context>
</http:request-config>

<flow name="upload-first-floor">
    <file:inbound-endpoint path="${file.first}"  responseTimeout="30000" doc:name="Retrieve File" connector-ref="File_First" pollingFrequency="30000" fileAge="20000">
        <file:filename-regex-filter pattern="(.*).avi" caseSensitive="true"/>
    </file:inbound-endpoint>
    <logger message="Moving #[flowVars.originalFilename] to Box" level="INFO" doc:name="Logger"/>
    <set-variable variableName="streamPayload" value="#[payload]" doc:name="Store Payload"/>
    <http:request config-ref="Dropbox_HTTPS_Request_Configuration" path="1/files_put/auto/#[flowVars.originalFilename]" method="PUT" doc:name="DropBox API - File Upload">
        <http:request-builder>
            <http:header headerName="Authorization" value="Bearer <YOUR ACCESS TOKEN>"/>
        </http:request-builder>
    </http:request>
    <expression-component doc:name="Close Payload InputStream">streamPayload.close()</expression-component>
</flow>

Conclusion

As you can see, making a REST API call is just as easy as using the pre-built connectors in the Anypoint Platform. Architectural and functional design considerations generally drive the decision on which approach is better for the scenario.

I had the option of storing the DropBox access token into an Object Store and referencing the token from the DropBox connector using the accessTokenId but since my project only needs to upload files, I took the route of using the HTTP connector and making the REST API call directly.


Posted

in

by

Comments