Best Practices from Oracle Development's A‑Team

Documents Cloud and Atlassian Confluence: A Macro for Attachments

Mark Foster

Oracle Documents Cloud Service and Atlassian Confluence both use the term "Application Link" but with different meanings. The Confluence definition is related to connecting two different systems together for integration, whereby authentication settings and connection details are kept securely. In Documents Cloud, the Application Link REST resource definition refers to an embedded user interface that can be added into other applications. To make the terminology a bit further confusing, both products use the term "AppLinks" as a short name. But these two features work well together for integrating Documents Cloud into Confluence as an attachment storage feature. Using a Documents Cloud macro for attachments provides a HTML5 user experience with drag and drop capabilities for adding and managing files. The standard Confluence attachments macro allows content to be stored within Confluence, but putting content in the Oracle cloud allows for further possibilities with those files.

Creating a Confluence macro skeleton can be done by following tutorials that illustrate the steps. The Atlassian SDK is required in the development environment. This macro was tested on Confluence versions 5.4.x and higher. Once the project is created, a Documents Cloud macro that uses the embedded user interface can be written into a single Java class. The class must extend the Confluence Macro interface. The macro can be created in a single class and packaged into a jar file that can be uploaded into Confluence. A similar macro could be created for Jira, although that is not explored in this post.

Adding the macro to the page is like any other installed macro in Confluence. The macro can be selected from the list of installed macros and dropped into the Confluence page.



The result of the DOCSMacro is shown in the following screen shot. A Confluence page where the macro has been added renders the folder in embedded format, and users cannot navigate above the folder and see other pages' folder content. An embedded and locked-down view of a single folder in Documents Cloud is presented. Users can interact with the folder using the intuitive interface of Documents Cloud Service. In this sample, all of the Folders are created at root level of Documents Cloud, which is coined the "self" folder in Documents Cloud. The assumption for the sample code is that the Documents Cloud user account is only being used for Confluence. In other words, the account is dedicated for this purpose.

The function of this "DOCSMacro" follows a pattern that is re-usable in other Documents Cloud "Application Link" integrations. The macro makes only two REST calls to Documents Cloud. If loading the macro for the Confluence page for the first time, a create folder REST call is made. The folder that is created is then saved in a page property (docs_folder_guid), so that the folder is persisted and forever associated with that page. Because of this, the macro has a 1:1 relationship between Confluence Page and Documents Cloud folder. Even if the macro on the page is removed and a re-added, the same folder that was originally created will be loaded again because the Confluence page property will remain.

Once a folder is created and saved to the page, the macro will call the Documents Cloud AppLink REST service. An embedded iframe is generated with the REST response details and access tokens. JavaScript handling of the “appLinkReady” event is also included in the macro.




Installing the Macro

Login to Confluence as an Administrator. Go to the “Managed Add-Ons” Page and click “Upload add-on”. Select the jar file (e.g. docsmacro-1.0-snapshot.jar) and install it.


The macro installation process will then show a success page.





Setup the Confluence Application Link

The Confluence Application Link setup is done to store the Documents Cloud host, username, and password for making connections from the Macro. This feature provides security for the password within Confluence and the Macro is able to access the connection details for making REST calls using the Atlassian classes ApplicationLinkRequest and ApplicationLinkRequestFactory. But first the Application Link must be created in Confluence.

Login to Confluence as an Administrator. On the Administration menu, create a new “Application Link”.  Enter the URL of the Oracle Documents Cloud instance in the format below. No trailing slash is needed, just the protocol, host, and context root.


Then click "Create New Link". On the next page that displays, check the box for "Use this URL". The URL has been redacted from the screenshot but is the same format as listed above. Click Continue.




The name of the Confluence Application Link must be the value “Oracle Documents Cloud”. This value is hardcoded into the sample macro and when executed that name will be sought. The type of macro must be “Generic Application”.




Once the Application Link is created in Confluence, the security credentials must be set. Edit the Application Link. The first page that loads will show information that you have already entered. Click on the “Outgoing Authentication” option on the left menu to enter in the username and password of the DOCS account. Then click "Enabled" to activate the link.



Technical details of the project

A key dependency must be added to the pom.xml in order for the Confluence Application Link classes to be available in the macro. The applinks-api must be included, such as this example.

<dependency>  <groupId>com.atlassian.applinks</groupId>  <artifactId>applinks-api</artifactId>  <version>4.2.5</version> </dependency>


Likewise, in the atlassian-plugin.xml file, references to the applicationLinkService must be present as a component-import entry.


<component-import key="applicationLinkService"     interface="com.atlassian.applinks.api.ApplicationLinkService" /> <component-import key="entityLinkService"     interface="com.atlassian.applinks.api.EntityLinkService" /> 


In the DocsMacro java code, having the applinks-api makes light work of calling REST services to Documents Cloud. Once the REST URL is prepared, the request that gets created needs no authentication header set because Confluence takes care of it for you. The credentials are stored in the Application Link, thus no need for coding to get the credentials into the Macro itself.

ApplicationLinkRequestFactory requestFactory = confluenceAppLinkForDocs     .createAuthenticatedRequestFactory(); ApplicationLinkRequest request = requestFactory.createRequest(MethodType.POST, docsUrl); String responseBody = null; try {  responseBody = request.execute(new ApplicationLinkResponseHandler<String>() {   public String credentialsRequired(     final Response response)     throws ResponseException {    return response.getResponseBodyAsString();   }   public String handle(final Response response)     throws ResponseException {    return response.getResponseBodyAsString();   }  }); } catch (ResponseException e) {

Once a JSON response is returned from Documents Cloud, parsing the JSON and extracting the folder id can be done with a JsonParser. The "id" field in the JSON response contains the folder GUID, and setting a page property to the id can be performed using the Confluence ContentPropertyManager class.

JsonObject jobj = new JsonParser().parse(responseBody).getAsJsonObject(); contentPropertyManager.setStringProperty(conversionContext.getEntity(),                                          guidPageProperty, jobj.get("id").getAsString()); 


On the DOCS AppLink request and response, a bit of additional work is needed because the appLinkReady event must be handled. The JSON response contains the URL and the proper tokens needed for handling the event. The output of the macro is ultimately an HTML page with an iframe and event handler.


JsonObject jobj = new JsonParser().parse(responseBody)   .getAsJsonObject(); // Create the iframe builder.append("<iframe id='content_frame' src="   + jobj.get("appLinkUrl")   + " style='width:100%; height:520px;''></iframe>\n"); builder.append("<script>\n"); builder.append("$( document ).ready(function() {\n"); builder.append("var dAppLinkUrl=" + jobj.get("appLinkUrl") + ";\n"); builder.append("var dAppLinkRefreshToken=" + jobj.get("refreshToken")   + ";\n"); builder.append("var dAppLinkAccessToken=" + jobj.get("accessToken")   + ";\n"); builder.append("var dAppLinkRoleName='" + parameters.get("role")   + "';\n"); builder.append("var embedPreview='true';\n"); builder.append(" function OnMessage (evt) {\n"); builder.append("  console.log('in onMessage function, message is:' + evt.data.message);\n"); builder.append("  if (evt.data.message === 'appLinkReady') {\n"); builder.append("   var iframe= $('#content_frame')[0];\n"); builder.append("   var iframewindow= iframe.contentWindow ? iframe.contentWindow : iframe.contentDocument.defaultView;\n"); builder.append("    var msg = {\n"); builder.append("     message: 'setAppLinkTokens',\n"); builder.append("     appLinkRefreshToken:dAppLinkRefreshToken,\n"); builder.append("     appLinkAccessToken:dAppLinkAccessToken,\n"); builder.append("     appLinkRoleName:dAppLinkRoleName,\n"); builder.append("     embedPreview: embedPreview\n"); builder.append("    }\n"); builder.append("     console.log('calling iframewindow.postmessage');\n"); builder.append("    iframewindow.postMessage(msg, '*');\n"); builder.append("  }\n"); builder.append(" };\n"); builder.append(" console.log('calling window.addEventListener for message callback');\n"); builder.append(" window.addEventListener && window.addEventListener('message', OnMessage, false);\n"); builder.append("});\n"); builder.append("</script>\n"); return builder.toString();


To download the Macro and test it out, the packaged jar is available in this zip file. Likewise, the two important pieces of the Macro itself are included, which are the DocsMacro.java class that does the work, and the atlassian-plugin.xml file that enables the Confluence AppLink API. This sample could be extended in various ways using the REST API to build a custom interface instead of the DOCS AppLink feature. The key part is gaining access to the DOCS REST API from within Confluence, and then all of the functionality of Oracle Documents Cloud, and potentially other Oracle PaaS products, is available to you.



Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha