In the past few years, the buzz word “Microservices” attracted more and more attention. It is nothing new. It’s just a different perspective on how to look at your projects. One of the characteristics of Microservices is to have a smaller team working on smaller and lighter projects. You are now probably asking yourself what is the connection between Microservices and Oracle (JET and WebCenter Content).

Imagine you are an Oracle customer and you have Oracle WebCenter Content as your main document management system for your enterprise. Now, you would like to have a small application that provides a different view of some folder structure.

For instance, you have a top folder called Contracts. However, you would like to see in a single view the files and folders of the Contracts folder, but also the files and folders of each folder within Contracts. This sounds rather complicated. I call it the “Umbrella View” and it looks similar to the example within the following screen:

20161104_picture_01The top table displays all the files within the Contracts folder, then each area underneath it represents a sub-folder of Contracts, where the folders and files of the respective sub-folder are displayed. Now it should be easier.

If you have Oracle WebCenter Content, then you are in luck because for each service there is a JSON mode. To activate it, you have to add the IsJson=1 parameter to the service call; e.g. to get all the files and folders for a folder you call the service FLD_BROWSER:

http://middleware/cs/idcplg?IdcService=FLD_BROWSE&path=%2fEnterprise%20Libraries%2fContribution%20

Folders%2fContracts&doMarkSubscribed=1&IsJson=1

The response for this is a JSON with the following structure (it is not a REST call, but it is enough for our use case):

20161104_picture_02

So, you have within the ResultSets.ChildFiles node the following:

JSON Field Description
fields The fields returned for each file, this will give you the position of a field in the “rows” array.
rows The field values.

 

Furthermore, the Results.FolderInfo node contains the following:

JSON Field Description
fields The fields returned for each folder, this will give you the position of a field in the “rows” array.
rows The field values.

 

This service is not retrieving all the data we need, so I have to call it several times for each folder box of the Umbrella View. If the user of this small microservice would like to rearrange the folder boxes in a logical order, he can do it with ease because the boxes are draggable. Furthermore, the users can see and edit the metadata of those files and folders, as well to execute actions like: Create, Delete, Move. For all of this you can use the Oracle WebCenter Content services in JSON mode.

Why to choose Oracle JET for this microservice? There are many reasons, but, regarding this use case, I needed a fast POC done by one person to show my customer what can be done. It took me 1 day to finish this POC and to show the customer how we can visualize the Umbrella View and how fast it runs.

Ok, let’s dive in the implementation. I’ve created a new Oracle JET project with NetBeans and started to work on a module by taking the code from Oracle JET Cookbook and adapting it to my needs. For starters, I’ve taken the Reorder Titles from the Masonry Layout area:

http://www.oracle.com/webfolder/technetwork/jet/jetCookbook.html?component=masonryLayout&demo=reorderTilesMasonryLayout

This was used to make the draggable folder box for my umbrella view.

I’ve also taken a Basic Table from here:

http://www.oracle.com/webfolder/technetwork/jet/jetCookbook.html?component=table&demo=basicTable

This was used to display the files of the top folder.

And a Modal Dialog sample from here:

http://www.oracle.com/webfolder/technetwork/jet/jetCookbook.html?component=dialog&demo=modal

I’ve played a bit with the CSS styling and in a short period of time I had this awesome skeleton for my application.

Then I’ve started to integrate the FLD_BROWSE service to bring data to my application. In the module “handleActivated” function, which is NEW in the 2.2.0 Oracle JET project template, I’ve used a simple $.ajax method for making the call to the service. Within the success function I’ve translated the JSON to the arrays needed by my POC. For instance, I’ve used a map to get the fields for the files. This will be handy later on:

var fields = d.ResultSets.ChildFiles.fields;
for (var i = 0; i < fields.length; i++) {
    fieldsMap[fields[i].name] = i;
}

By using this map, it was cleaner to read the fields for the files from the FLD_BROWSE JSON than just using the hardcoded field index (which might change):

var rows = d.ResultSets.ChildFiles.rows;
for (var i = 0; i < rows.length; i++) {
    self.folderFiles.push({fFileGUID: rows[i][fieldsMap['fFileGUID']],
        fParentGUID: rows[i][fieldsMap['fParentGUID']],
        fFileName: rows[i][fieldsMap['fFileName']],
        xEFReferenceNumber: rows[i][fieldsMap['xEFReferenceNumber']],
        xEFCDVSContractingParty: rows[i][fieldsMap['xEFCDVSContractingParty']]});
}

See that I’ve also read the custom files attributes like: ‘xEFReferenceNumber’.

I’ve done the same for folders. The fields map for folders is different than the one from files, so I cannot reuse the map from files:

var fields = d.ResultSets.ChildFolders.fields;
for (var i = 0; i < fields.length; i++) {
    fieldsMap[fields[i].name] = i;
}

Then to get the fields values, I’ve used this:

var rows = d.ResultSets.ChildFolders.rows;
for (var i = 0; i < rows.length; i++) {
    self.umbrellaFolders.push({index: 0, fFolderGUID: rows[i][fieldsMap['fFolderGUID']],
        fParentGUID: rows[i][fieldsMap['fParentGUID']],
        fFolderName: rows[i][fieldsMap['fFolderName']],
        xEFReferenceNumber: rows[i][fieldsMap['xEFReferenceNumber']],
        xEFCDVSContractingParty: rows[i][fieldsMap['xEFCDVSContractingParty']],
        folders: ko.observableArray(),
        files: ko.observableArray()
    });

The interesting part for the code above is that the fields “folders” and “files” are observable arrays that have no data yet. Those are the files and folders within a box. Now, for each box we trigger another $.ajax call which will fill with data the observable arrays. This has a very cool effect. My application will not hang until all the data for my Umbrella View is retrieved. However, each folder box will have an asynchronous call to the server to load the files and folders for the respective box area.

In the Masonry view, I’ve used the following structure:

<!-- ko foreach: umbrellaFolders -->
Display header
   <!-- ko foreach: $data.folders -->
    Display the folders within the box, this will automatically refresh as the folders is an observableArray
   <!-- /ko -->
  <!-- ko foreach: $data.files -->
    Display the files within the box, this will automatically refresh as the files is an observableArray
   <!-- /ko -->
<!-- /ko -->

The last thing I’ve done was to integrate a modal dialog to display the file’s metadata. For this, I’ve used an iframe within the Oracle JET dialog component:

<div style="display:none" id="modalDialog1" title="Document Information" 
     data-bind="ojComponent:{component: 'ojDialog', initialVisibility: 'hide',
               rootAttributes: { style: 'width: 710px; height:570pxoverflow:hidden'}}">
    <iframe src="http://middleware/cs/idcplg?parentLocation=http%3A%2F%2Fmiddleware%2Fcs%2Fidcplg%3FIdcService%3DFLD_BROWSE%26path%3D%252fEnterprise%2520Libraries%252fContribution%2520Folders%252fContracts%252fCDVS%252fContract%2520Documents%252f0%252fNew%2520Suite%2520of%2520Contracts%26doMarkSubscribed%3D1&coreContentOnly=1&fFolderGUID=492CBFBAA96D47FF4BFF7967FE211D46&IdcService=FLD_EDIT_METADATA_RULES_FORM" 
            name="fld_dialog" width="695" height="570" frameborder="0"></iframe>
</div>

The result is the following:

20161104_picture_03

The conclusion following this project is that Oracle JET can be used to build fast POCs and to build applications in the Microservices paradigm. Also, the investment in Oracle WebCenter Content by my customer paid off as well because it allows us to build smaller, lighter applications, which help increase the business users’ experience.