Integrating Oracle Document Cloud and Oracle Sales Cloud, maintaining data level business object security

Introduction

When customers see the rich functionality available in Oracle Documents Cloud they often ask if they can use this functionality within their Oracle Fusion SaaS Applications to store, and share, documents. At first the integration appears to be quite straightforward, e.g. use the Documents Cloud Web API, embed an iFrame that points to the relevant opportunity id folder in Oracle Documents Cloud and all should be good. However the implementer will soon realise that this approach, on its own, would not respect the Oracle Fusion Applications data security model, I.e. who has authorization to see the documents? and therefore is not production worthy.

The remainder of this blog article describes the challenges faced when integrating Oracle Documents Cloud with Oracle Sales Cloud and proposes a design pattern which solves many of the issues encountered, whilst ensuring the pattern is flexible enough to be used by multiple SaaS applications.

Once Oracle Documents Cloud is embedded within Oracle Sales Cloud, the user then will have many additional features available ot them, such as :

  • Hierarchical folders
  • In Place viewing of documents of different types (Word, Excel, Powerpoint etc)
  • Drag and Drop interface for adding new documents
  • And more

For more information on Oracle Documents Cloud features please see Oracle Documents Cloud webpage

What are the challenges embedding Oracle Documents Cloud with Oracle Sales Cloud?

There are a number of considerations which need to be taken into account when embedding Oracle Documents cloud into Oracle Sales Cloud, namely:

Angelo_DocCld_sampleimage

Screenshot of Documents Cloud Embedded within a Sales Cloud

  • How do you embed the Oracle Documents Cloud user interface in Oracle Sales Cloud?
  • Security, how are you going to ensure documents are secured based on SAAS data security policies?, these normally do not map to PaaS security roles
  • How do you ensure the integration is easily maintainable?

It is possible that you will have multiple Oracle SaaS applications installed (Sales, HCM, ERP, Service etc.) and ideally you would want to use the same integration pattern for all of your SaaS integrations. This however raises its own set of challenges given that different SaaS products offer different extensibility tools (Application Composer, .NET, PHP etc) and differing levels of extensibility, therefore to ensure the highest level of reuse, you will need to use the lowest common denominator extensibility option and move common logic to a common location, such as a middletier.

Architecture

BlogArchitecture

High Level Architecture

Oracle Java Cloud – SaaS Extensions is a specific variant of the Oracle Java Cloud server but designed specifically to integrate with Oracle SaaS Applications. JCS-SX’s main differentiators are identity association with Fusion Applications and low cost due to its multi tenanted architecture For more information please see the Oracle Java Cloud – SaaS Extensions (JCS-SX) website.

The implementation of this pattern uses the Oracle Java Cloud – SaaS Extensions (JCS-SX) service to host some java code, in the form of a JEE Servlet. The functionality of this servlet includes :

  • Ensuring only Fusion Applications Authenticated Users can access a document folder
  • If an object doesn’t already have a folder created, the servlet creates the folder in Oracle Documents cloud then stores it in Oracle Sales Cloud again. This is done for to ensure subsequent calls are more efficient.
  • Only folders for which the user can “see” from the SaaS application are able to be accessed – thus ensuring the solution respects SaaS visibility rules
  • Return a generated html page which displays the Oracle Documents Cloud folder for the Sales Cloud object requested

Historically a pattern previous commonly used involved using Oracle Sales Cloud groovy code to call a SOAP façade hosted on JCS-SX, which in turn communicated using the REST API with Oracle Documents Cloud to create folders in Oracle Documents Cloud. This pattern is not used here for a number of reasons.

  • This would require additional customizations/groovy code on the SaaS side to call our SOAP-REST Façade and one of the desires of this integration pattern is to reduce the amount of SaaS side customization as much as possible so that can support as many SaaS products as possible with a single code base.
  • This would make the JCS-SX code more complex than it really needs to be, we would need multiple entry points (createFolder, ShareFolder, generate an AppLink etc)
  • Finally although Oracle Sales Cloud has great outbound SOAP service support it is often best practice to encapsulate multiple, potentially complex, SOAP calls in a middle tier layer, in our case a servlet hosted on JCS-SX.

The added benefit is that given that the bulk of the business logic is in our Java layer, our integration can easily be used for other SaaS applications, like HCM,ERP, Service Cloud, even non Oracle SaaS products, which offer different levels of customization/languages but fundamentally they all support the concept of embedding an iFrame and passing parameters..

The Integration Flow

As the saying goes “A picture is worth a thousand words” so at this point let’s look at the integration flow implemented by the pattern. We will do this by means of a flow diagram and go through each step explaining the functionality explaining the design consolidations the developer should be aware of and offering some limited code samples.

Angelo_DocCld_flow

SalesCloud to DocCloud Integration Flow

Step 1 is the action of calling the integration from within a Oracle Sales Cloud tab. Here we are embedding the integration servlet within Sales Cloud using the App composer framework and some groovy scripting. The groovy script below calls the JCS-SX servlet, passing data (the object type, the object number, a JWT security token and optionally a Oracle Documents Cloud folder stored in a custom field) and the response of the Java servlet is a HTML page which redirects to the specific Oracle Documents Cloud Folder.

def jwt=(new oracle.apps.fnd.applcore.common.SecuredTokenBean().getTrustToken();
def docCloudIntegrationURL = oracle.topologyManager.client.deployedInfo.DeployedInfoProvider.getEndPoint("DocSalesCloudIntegration");
def url = docCloudIntegrationURL+"?objectnumber="+OptyNumber+"&objecttype=OPPORTUNITY&jwt="+jwt+"&folderGUID="+folderGUID;
return url;

TIP : In the above example we have used a feature of Oracle Fusion Applications called “Topology manager” to store the endpoint of our JCS-SX hosted Servlet. This is good practice as it allows a level of indirection where the developer can store the physical hostname/url of the servlet in one place and reuse it in many places. e.g. Tab for Opportunities, Tab for Accounts etc etc.

For more information please refer to the Oracle Documentation : Working with user Tokens & Topology Manager

For specific steps on how to create a tab in Sales Cloud simplified UI please see this documentation link or this short YouTube video by our fusion Applications Developer Relations group.

Step 2 is now being executed from within our servlet running on JCS-SX. This is where we check to see that the user who’s requested to see the objects documents, actually has permission to do so. To accomplish this we issue a REST query back to Oracle Sales Cloud asking if this user (identified by the JWT security token passed) can query this specific object using the object number.

To check the object is accessible we issue the following REST call in our Java code

GET <SalesCloudServerURL>/salesApi/resources/latest/opportunities/123456?fields=Name&onlyData=true


TIP :  For efficiency purposes, when querying data from Oracle Fusion Applications using the REST, or SOAP , API ensure that you only return the data you require.For the REST API simply add the parameter “fields” with a comma seperated list of fieldnames. For the SOAP API you can add <findAttribute> tags with the fields you wish to return.

If the query to Oracle Sales Cloud returns data (i.e. a single row) then we can assume the user has valid access to the object, at that time, and thus can proceed. If we get a “no data found” (i.e. a 404 error) then we simply return a security exception to the user interface as the user has no access. In practice the user should never receive this error as the URL call is generated based on them navigating to a screen with access but for security reasons this check is necessary.

The principal advantage of this approach is we are using SaaS application functionality to determine if a record is visible by a user rather than trying to determine it from the Java servlet . We assume that if you can query the object from the SaaS API then you have access. Additionally this technique will work for any SaaS application regardless of how it “secures” data visibility, e.g. Oracle Sales Cloud uses territory management to determine visibility whereas HCM Cloud uses job roles. For non Fusion Applications we are assuming that SaaS applications API respects its user interfaces visibility rules in the same way as Oracle Fusion Applications.

Step 3 is concerned with checking, or finding, the folder in Oracle Documents Cloud where the objects documents are stored (e..g files for an opportunity). This integration pattern stores the objects documents in a hierarchy within Oracle Documents Cloud. The application root directory contains a collection of folders, one for each object type (e.g. Opportunity, Account etc.) and then within that a sub folder (ObjectNumber-ObjectName) of the object we’re looking for.

If a folder GUID is passed in as a parameter to the Java servlet then we then simply need to check, using the GUID, that the folder exists in Documents Cloud and then move on to step 4 of the process. If we are not passed a folder GUID then we need to perform an in-order traversal of the hierarchy and find the folder, whose name would be <ObjectNumber>-<ObjectName>. This second method is not going to be very efficient as we could have a scenario where we could have 1000s of folders which we would need to trawl through. Thankfully it should only occur the first time a folder is accessed and subsequent requests would be quicker as we store the folder GUID in Sales Cloud in a custom field.

This second approach however does have a massive advantage in that it can be used for SaaS Applications where it is not possible to store a custom field in the SaaS application and pass it in context of the user interface. So although less efficient it will continue to work and give us more options. If we were in this scenario then I would strongly recommend one of the following strategies be implemented to reduce the folder count to only include a subset of all documents.

  • A data aging mechanism where objects relating to inactive/old Accounts/Opportunities etc. are archived off
  • Or the use of a database store, like Database Cloud Service, to hold a mapping table of DocCloud GUIDs to Oracle Sales Cloud objects, indexed by the Oracle Sales Cloud ObjectID/Type.
Angelo_DocCld_heirarchy

Example of hierarchy stored in Document Cloud

Example Object type hierarchy within Documents Cloud

Step 4 is only executed if the folder does not exist. The lack of the folder implies that no documents have been stored for this object and the next step is to create the folder. This would normally happen the first time a user shows the tab in Oracle Sales Cloud. It is also worth noting that the folder only gets created in Oracle Documents Cloud when, and only when, the Documents Cloud tab in Oracle Sales Cloud is selected, this way we don’t get empty folders in Oracle Documents Cloud.

If you had used groovy scripts in Oracle Sales Cloud and created a folder on the creation event of a Oracle Sales Cloud object (e.g. creation of a new opportunity), you would cause the creation of a number of empty folders and require more customizations to be done in Oracle Sales Cloud.

The Documents Cloud REST call for creating a folder is as follows :

POST <DocCloudServerURL>/folders/FF4729683CD68C1CCCCC87DT001111000100000001
{
    name : "1234-Vision-Website",
    description : "Folder for Vision Software Opportunity 1234 Website Deal"
}

The long HEX number is the parent folder GUID, which is either passed in from SalesCloud or discovered by an inorder traversal of the documents cloud folder hierarchy.

Step 5, In step 3 we walked through a fixed hierarchy to find the folder using a combination of Object Number and Object Name (e.g. “1234-Vision-Website”), as mentioned earlier this approach isn’t efficient therefore at this stage we store the discovered, or generated, folder GUID in Oracle Sales Cloud using for subsequent requests

TIP : For more information on how to create custom fields in Sale Cloud checkout this youtube viewlet from Oracle Fusion Application Developer Relations.

Other Oracle Fusion Applications products also allow the storage of custom fields in the SaaS instance by a technology called “FlexFields”, if your interested checkout this ATeam Chronicles blog article on Descriptive FlexFields.

Step 6 is only reached when we’ve found the folder on Oracle Documents Cloud and have checked that he user has access to the folder. Now all we need to do is generate an HTML page which will show the documents. Specifically we want to show the user the folder with the documents BUT importantly not allow them to navigate in/out of the folder. This can be achieved by using a feature of Oracle Documents Cloud called “AppLinks”. An AppLink is a generated URL which gives temporary access to an Oracle Documents Cloud folder, or item. In this step the Java servlet generates some HTML and JavaScript code which when sent back to the browser iFrame, which executes it and subsequently redirects to Oracle Document Cloud to the AppLink URL previously generated

The REST call which generates a Folder AppLink is shwon below. In this example we are using the role of “contributor” as we want to give our users the ability to add, and remove, files

POST <docCloudServerURL>/applinks/folders/FF4729683CD68C1CCCCC87DT001111000100000001
{
   "assignedUser": "Any User",
    "role : "contributor"
}

For more information on AppLinks please see this article on Oracle Documents Cloud and AppLinks on the A-Team Chronicles website.

Step 7 Is now the final phase of the servlet which is to return a HTML page back to the iframe embedded within Oracle Sales Cloud

Step 8 is the page being rendered in the iFrame in Oracle Sales Cloud, at this point the HTML/JavaScript is executed and redirects the iframe to Oracle Documents Cloud showing the appropriate page in Oracle Documents Cloud.

 

Conclusion

From the above pattern you can see that it’s perfectly possible to integrate Oracle Sales Cloud and Oracle Documents Cloud in a manner that not only is incredibly functional, efficient but importantly maintains the complex security model enjoyed by SaaS applications like Oracle Sales Cloud. This pattern also highlights many micro patterns which are used to create this integration, namely (with links to other blog entries)

 

A complete downloadable asset, containing the sample code above ready to be deployed into Oracle JCS-SX, will be made available soon.

 

 

 

Comments

  1. Jeroen Burgers says:

    Truly nice and well-explained. I belief this deserves to become productized, by that enabling OSC customers with great functionality. Oracle document cloud being the enterprise-grade, giving the feature-rich functionality you’d have with Dropbox. Integration with OSC makes a whole lot of sense, for obvious reasons. Thanks for sharing!

    • Angelo Santagata says:

      Thank you! The design pattern,and sourcecode, above has been given to product management for consideration to be included with the product. In addition to satisfy immediate customer needs we are going through the process of publishing the code, via github, as a sample prebuilt integration

Add Your Comment