Skip navigation

As part of the DevOps culture, and in particular the Ops processes, Stack Automation Engineers will always be interested in orchestrating the infrastructure and make it available for various environments, starting from Dev & Test, Benchmark, and/or Production or others.


Depending on your preferences, you could deploy a Chef Server in Oracle IaaS and orchestrate all your infrastructure ( the nodes ) from it, that being probably one of the most common setups, also my preferred one and to which I will make reference in this current article.



Alternatively, you could work directly from your workstation where you have installed Chef DK and orchestrate all your infrastructure in Oracle IaaS ( the various nodes  ) through a Chef Server that you can deploy it anywhere:




or have your Nodes Chef orchestrating themselves together with opc-init from remote accessible URL(s) where you deployed the desired scripts (pre-bootstrap), you can read more about it here.


Follow this link, for a full tutorial on how to deploy Chef Server on Oracle Compute Cloud and how to knife a simple cookbook named "custom-ssh-banner".


Once you uploaded your cookbook on the chef server and knife it on a node, presuming your orchestrated node is named "chef-node1", once you will ssh into your "chef-node1" you should receive a similar notification as in the below:


This banner was brought to you by Chef using custom-ssh-banner.
[opc@chef-node1 ~]$


Tip: to knife bootstrap your node with a public ip <Node_Public_IP> and a hostname chef-node1:


knife bootstrap <Node_Public_IP> --ssh-user opc --sudo --identity-file <SSH_private_key> --node-name chef-node1.compute-identity-domain.oraclecloud.internal --run-list 'recipe[your_recipe]'


  • opc refers to the Oracle Public Cloud user, through which you can sudo to root on the machine if needed
  • chef-node1.compute-identity_domain.oraclecloud.internal refers to the internal hostname as qualified in Oracle IaaS


Once you finished the above tutorial you should be able to build your own Cookbooks and recipes or use the Chef Market.


Interested to learn more on how to deploy a Standalone Oracle Database with Chef cookbooks ? Check this tutorial.

Interested to learn more on how to deploy Middleware/Weblogic Chef cookbooks ? Check this GitHub Chef Samples.


Happy coding.


**The views expressed in this post are my own and do not necessarily reflect the views of Oracle.

I explained in the first post From Disaster to Recovery part I the importance of having a DR site set up for your IT infrastructure and for your business overall.


Here are three examples of architectures that could lead to a DR solution set in place would be:


     1. Using Database Backup as a Service





This is effective when all your database backups are done using Database Backup Cloud Service and all the backups from production environment go on the Cloud Storage. This allows you to restore your databases both in the on-premise servers or/and on the Cloud Services like Database Cloud Service or Exadata Cloud Service.


     2. Using Data Guard or Active Data Guard.




If backing up the databases on the cloud storage is not enough you could chose for an Active Data Guard replication between the sites.

The Active Data Guard Replication could be implemented using the Maximum Availability Architecture giving you also data consistency and protection.

This way the standby database would be in read-only mode and could also be used for reporting, queries or sandbox creation.



     3. Full Stack Disaster Recovery




  • Database
    • Use Database Backup Service to send on-premise database backups to Oracle Cloud using RMAN
    • Restore the database in the cloud from the backup
  • Application
    • Use JAVA / REST calls to copy on-premise application data to Storage Cloud Service
    • You can also use OSC Appliance for the copy
    • Restore the data into the compute cloud from the object storage


The solutions and the architectures may vary also according to each company’s restrictions, SLAs or prerequisites. Using Database Cloud service as a standby-site for disaster recovery would prove to be both efficient and cost effective.


**The views expressed in this post are my own and do not necessarily reflect the views of Oracle.

In this blog, I will present a sample implementation for a hybrid mobile app using Oracle JET (version 2.0.x) that will display data fetched from Oracle Sales Cloud via Oracle Mobile Cloud Service (version 16.3.x)


Building enterprise grade bespoke mobile apps pose a number of challenges. Implementing data retrieval in mobile application client code is incredibly complex because it needs to be shaped it in the required format within reasonable performance limits with all aspects of security handled appropriately. These requirements are addressed by mobile back-end implemented in Mobile Cloud Service (MCS), resulting into a superior user experience that implies increased user adoption.


In this sample, we will retrieve Opportunities for a specific Account from Sales Cloud and display on the mobile application.


Key Components

Below tables summarizes the key components involved in this solution:


Client Application (JET Hybrid app)A JET Hybrid application that communicates with Oracle MCS
Oracle MCSMCS (Mobile Cloud Service) delivers cloud-based, server-side mobile services to enable quick and easy app development.  It reduces complexity and redundancy when creating code blocks by providing ready-to-integrate features and templates.
Oracle  Sales CloudOracle Sales Cloud delivers a wide range of functionality to improve sales effectiveness, better understand customers, and build a pipeline for success. It exposes multiple public REST APIs that can be used to access data stored in Sales Cloud and construct integrations to other systems


Life-Cycle Flow

Below diagram shows the life-cycle flow for data flow from Oracle Sales Cloud to Mobile device via MCS:




Below are the main steps involved:

  1. The mobile app initiates connection with the mobile back-end server (MCS) and authenticate the logged in user.
  2. The mobile app make a REST call to custom API
  3. The custom API internally uses connector API to interact with Oracle Sales Cloud
  4. The response received to custom API’s is sent back to display data in the app


Below is the security approach followed:

  • Client Side: Hybrid Mobile Application:
    1. Authenticated the mobile application via SSO: On success , status 200 OK, API returns SSO TOKEN
    2. Used this SSO Token in Authorization header while calling MCS Custom API. This token is used to propagate identity to MCS Connector


  • Mobile Back-end: Oracle Mobile Cloud Service
    1. MCS API:
      • Developed custom API which in turn calls REST based connector (Oracle Sales Cloud)
    2. MCS Connector:
      • Developed Connector API pointing to Sales Cloud
      • Set the security policy to “oracle/http_saml20_token_bearer_over_ssl_client_policy” , keeping everything as default

1. In order to follow this security approach mentioned in this blog, please ensure that single sign-on (SSO) is set up for your Oracle Cloud account.

2. Both MCS and Sales Cloud service should be in same identity domain.

Component: Oracle Mobile Cloud Service

Step 1: Create a mobile back-end

  • Login into Oracle MCS and create a new mobile back-end, provide a suitable Name and description
  • Enable OAuth Consumer
  • Check-box to select "Enable Single Sign-On"

If the Mobile Backend is in Draft state and you don't see the Enable SSO checkbox, SSO isn't set up for your account. If you want to set it up, have your team's identity domain administrator go to the Oracle Cloud My Services page and configure SSO.



Step 2: Create a custom API

Here are the steps to create a custom API:

  • General: Create a new custom API, provide API display Name and API name. This API name translates to the external URL for the custom API for our mobile apps to connect with it.


  • Endpoints:  The next step is to define REST end points


          Add details to the endpoint, in this case it is a GET request:



  • Security: For sake of simplicity, we are keeping the disabling the credentials required to access this API


  • Implementation:  Here is the implementation code for this custom API, to know more about what you can do with custom code, I would recommend to visit “Implementing Custom APIs”


  "name" : "rdhsalesapplapi",
  "version" : "1.0.0",
  "description" : "Sales Cloud API ",
  "main" : "rdhsalesapplapi.js",
  "oracleMobile" : {
    "dependencies" : {
      "apis" : { },
      "connectors" : { "/mobile/connector/RDOSCAPIConnectorOriginSecured": "1.0"}




 * Mobile Cloud custom code service entry point.
 * @param {external:ExpressApplicationObject}
 * service 
module.exports = function (service) {
     *  The file samples.txt in the archive that this file was packaged with contains some example code.
    service.get('/mobile/custom/RDHSalesApplAPI/opportunities', function (req, res) {
        var sdk = req.oracleMobile;
        var result = [];
        var statusCodeOk = 200;
        var statusCodeError = 404;
        // handling the Rest call response and processing the data
        var handler = function (error, response, body) {
            var responseMessage = JSON.parse(body);
            if (error) {
                responseMessage = error.message;
            } else {
                if (!responseMessage.items) {
                    res.send(statusCodeError, 'No Opportunities found for the user');
            var opps = [];
            opps = responseMessage.items;
            opps.forEach(function (oppty) {
                var temp = {};
                temp.TargetPartyId = oppty.TargetPartyId;
                temp.OptyId = oppty.OptyId;
                temp.OptyNumber = oppty.OptyNumber;
                temp.SalesStage = oppty.SalesStage;
                temp.Name = oppty.Name;
                temp.Revenue = oppty.Revenue;
            res.send(statusCodeOk, result);
        //call for REST api to get list of opportunities
        var optionsList = {};
        var SalesAccountConnectorBaseURI = '/mobile/connector/RDOSCAPIConnectorOriginSecured';       
        optionsList.uri = SalesAccountConnectorBaseURI + '/salesApi/resources/latest/opportunities/';
        console.log('optionList  = ' + JSON.stringify(optionsList));, handler);


Step 3: Create a connector API

Before moving ahead, I would recommend you to go through this blog MCS Connector APIs: why should you be using them?  to know why connector APIs are required in spite of having the option to implement external service integration using Custom APIs directly


The next step is to create REST connector for accessing Oracle Sales Cloud:


  • General Configuration: Provide a name and description for new REST Connector API, and the path to the remote service it will expose.


  • Create Rules: User can create rules that automatically add default parameters when calling specific resources on this service. For this sample, we donot require any such rule so skip this option
  • Security Configuration: Use SAML as the client-side security policy in the MCS Connector, i.e. oracle/http_saml20_token_bearer_over_ssl_client_policy



Step 4: Select API and associate with your Mobile Backend


The next step is to select the custom API created and associate it with your mobile  backend.



Step 4: Test the Custom API

The last step is to test the custom API


A. Get Single Sign-On Auth Token

Open the following URL in an incognito or private browser window. The URL formation is as below:






The browser login screen shall look like:



Upon Success, the browser will show Single Sign-On OAuth Token:




B.  Test Custom API using MCS UI Test Endpoint

  • Select Mobile Backend
  • Paste SSO Token
  • Click Test Endpoint




Upon Success : Status 200 , data would be displayed:



Component: Oracle JET Hybrid Mobile App

Once the mobile back-end is up and ready, our next step is to display the data fetched data from MCS on the mobile interface.

You may please refer to Troubleshooting while developing your First JET based Hybrid Application blog in case of initial issues faced during development/configuration issues.

Project Setup using Yeoman

Yeoman generator for Oracle JET lets you quickly set up a project for use as a Web application or mobile-hybrid application for Android and iOS.

Use following command to generate hybrid application for Android:

yo oraclejet:hybrid oscmcssample --appId=com.rdh.oscmcs --appName="oscmcssample" --template=navBar --platforms=android  



Cordova Plugin Required

Please refer to Cordova Applications section in Oracle Mobile Cloud Service to obtain details of the cordova plugin.


Following cordova plugin needs to be added in our application:

  • oracle-mobile-cloud-cookies: Plugin for authenticating with MCS via SSO
  • cordova-plugin-inappbrowser: Plugin to provide a web browser view, required for displaying SSO Login Page


Adding Oracle MCS Cordova SDK

In order to communicate with Oracle MCS, following steps are required:

  1. Download the Cordova SDK from Oracle MCS. Extract the same on your local machine. It will contain Javascript based Cordova SDK , configuration files and documentation
  2. Add Oracle MCS Cordova SDK to your application, Copy mcs.js, mcs.min.js and oracle_mobile_cloud_config.js into the directory where you keep your JavaScript libraries.


For example, in this implementation, I have kept these files in mcs folder added in js/libs folder as shown in below image:



2. Fill in your mobile backend details in oracle_mobile_cloud_config.js.

var mcs_config = {
  "logLevel": 3,
  "mobileBackends": {
      "default": true,
      "baseUrl": "",
      "applicationKey": "YOUR_BACKEND_APPLICATION_KEY",
      "synchronization": {
        "periodicRefreshPolicy": "PERIODIC_REFRESH_POLICY_REFRESH_NONE",
        "policies": [
            "path": '/mobile/custom/taskApi/*',
            "fetchPolicy": 'FETCH_FROM_SERVICE_ON_CACHE_MISS_OR_EXPIRY',
            "expiryPolicy": 'EXPIRE_ON_RESTART',
            "evictionPolicy": 'EVICT_ON_EXPIRY_AT_STARTUP',
            "updatePolicy": 'QUEUE_IF_OFFLINE',
            "noCache" : false
            "path": '/mobile/custom/firstApi/tasks',
            "fetchPolicy": 'FETCH_FROM_SERVICE_ON_CACHE_MISS'
            "path": '/mobile/custom/secondApi/tasks',
        "default" :{
          "fetchPolicy": 'FETCH_FROM_SERVICE_IF_ONLINE',
          "expiryPolicy": 'EXPIRE_ON_RESTART'
        "authorization": {
        "basicAuth": {
          "backendId": "YOUR_BACKEND_ID",
          "anonymousToken": "YOUR_BACKEND_ANONYMOUS_TOKEN"
        "oAuth": {
          "clientId": "YOUR_CLIENT_ID",
          "clientSecret": "YOUR_ClIENT_SECRET",
          "tokenEndpoint": "YOUR_TOKEN_ENDPOINT"
          "facebookAppId": "YOUR_FACEBOOK_APP_ID",
          "backendId": "YOUR_BACKEND_ID",
          "anonymousToken": "YOUR_BACKEND_ANONYMOUS_TOKEN"
          "clientId": "5xxxxxx7-bf49-45c1-aeda-2xxxxx4",
          "clientSecret": "yxxxxxxx",
          "tokenEndpoint": ""


For more details, please See Configuring SDK Properties for Cordova.


After adding the physical files, update the paths mapping for mcs and mcs_cloud_config  in main.js file under requirejs.config section:

                                'knockout': 'libs/knockout/knockout-3.4.0.debug',
                                'jquery': 'libs/jquery/jquery-2.1.3',
                                'jqueryui-amd': 'libs/jquery/jqueryui-amd-1.11.4',
                                'promise': 'libs/es6-promise/promise-1.0.0',
                                'hammerjs': 'libs/hammer/hammer-2.0.4',
                                'ojdnd': 'libs/dnd-polyfill/dnd-polyfill-1.0.0',
                                'ojs': 'libs/oj/v2.0.2/debug',
                                'ojL10n': 'libs/oj/v2.0.2/ojL10n',
                                'ojtranslations': 'libs/oj/v2.0.2/resources',
                                'text': 'libs/require/text',
                                'signals': 'libs/js-signals/signals',
                                'mcs': 'libs/mcs/mcs',
                                'mcsconf': 'libs/mcs/oracle_mobile_cloud_config'

Implementation Steps

We will be implementing the entire code in dashboard.html and dashboard.js for easy implementation.


Add the additional modules: mcs and mcsconf to get loaded in dashboard.js file:

define(['ojs/ojcore', 'knockout', 'jquery', 'mcs', 'mcsconf', 'ojs/ojknockout', 'ojs/ojfilmstrip', 'ojs/ojpagingcontrol', 'ojs/ojbutton'],


Initialize following variables in dasbhoardViewModel function

var backend = 'empty';
                self.model = ko.observable('filmstrip-navdots-example');
                self.dataReady = ko.observable(false);
       = ko.observableArray();
                self.buttonSSOLogin = function () {



Updated dashboard.html file: Please find attached the updated dashboard.html file


Step 1.  Load Mobile Back end’s Configuration into the application:

function initializeMCS() {
                    mcs.MobileBackendManager.platform = new mcs.CordovaPlatform();
                    backend = mcs.MobileBackendManager.getMobileBackend("RDXTESTSSO");
                    if (backend != null) {

Step 2. Authenticate and Log In Using the SDK:

function ssoLogin() {
                            function (statusCode, data) {
                                alert("SSO Login success, status:" + statusCode);                               
                            function (statusCode, data) {
                                console.log(statusCode + " with message:  " + data);
                                alert("SSO Login failed, statusCode" + statusCode);

Step 3. In all REST calls to MCS APIs, include the given token in the Authorization header. In this case, we will be passing this token while calling API to fetch data from our SalesCloud custom API:

function fetchSalesCloudData(ssoToken)
                    var mcsbackendURL = mcs_config.mobileBackends.RDXTESTSSO.baseUrl + "/mobile/custom/RDHSalesApplAPI/opportunities";
                    var token = "Bearer " + ssoToken;
                    var settings = {
                        "async": true,
                        "crossDomain": true,
                        "url": mcsbackendURL,
                        "method": "GET",
                        "headers": {
                            "authorization": token
                    $.ajax(settings).done(function (response) {
                        $.each(response, function () {
                                Name: this.Name,
                                OptyId: this.OptyId,
                                OptyNumber: this.OptyNumber,
                                SalesStage: this.SalesStage,
                                Revenue: this.Revenue
                        self.dataReady = true;

Step 4: Display data using Oracle JET filmstrip component

function displaySalesCloudData()
                    console.log("inside displayFilmStrip");
                    self.pagingModel = null;
                    getItemInitialDisplay = function (index)
                        return index < 1 ? '' : 'none';
                    getPagingModel = function ()
                        if (!self.pagingModel)
                            var filmStrip = $("#filmStrip");
                            var pagingModel = filmStrip.ojFilmStrip("getPagingModel");
                            self.pagingModel = pagingModel;
                        return self.pagingModel;


Build and Run the application on Android emulator/device


In your command prompt, please change directory to project folder and run the following command:


Build the application using following command

 grunt build --platform=android


Once build is success, then run the application using following command, assuming android emulator is already up and running:

grunt serve --platform=android  --disableLiveReload=true  



Please find attached the screen-shot output of the emulator:

1. Application Icon:



2. SSO Login




3. SSO Login view in embedded web-view. Enter mobile user credentials and press SignIn Button



4. Success Alert message


5. Display of Sales Cloud data on view using JET Filmstrip component


Although the picture below seems extremely funny, in theory screaming for help is the last thing that we should do when disaster happens. But the theory is not reality!



We would expect that Disaster Recovery plans are just an extra measure for natural disasters. So we build our datacenters deep in the ground, Earth-quake free zones, and different geographic arias. But I saw some dazzling numbers that contradicted me:


It is rather difficult to keep your entire business alive when a junior electric engineer misunderstands which cable is the most important power cord for the datacenter and disconnects it. And this is just the simplest example that you can’t predict all the downtimes.

A disaster recovery solution should cover at least these aspects:

    • Avoid Single Point of Failure
    • Prevent Data Loss
    • Reduce Downtime Cost & Revenue Impact for Planned & Unplanned Outages
    • Disaster and Data Protection for Compliance & Regulatory Purposes


Depending on the tools and architecture used a Disaster Recovery plan can lead to a complex and expensive implementations that will make you question twice: why should we do it.


It is just a matter of choosing the right tools.

A low cost, simple and low risk solution for Oracle databases would be using Data Guard to Oracle Cloud environment.

The combo would easily cover:

  • Primary / DR synchronisation

Using Data Guard it would assure the synchronization on different MAA best practices.


  • On-Demand elasticity after migration to the DR site

Using the Database Cloud Service offers you the elasticity needed to fit your database in the cloud.


  • High investment in Hardware and Software & DR site operational aspects

DR requires High investments in new Hardware, Software licenses and additional staff to operate the site... Using Oracle Database Cloud Service would drastically reduce these costs.


  • Data inconsistency or corruption

Data corruption can happen if remote storage mirroring solutions are used to replicate database files instead of using Oracle Data Guard of Golden Gate.


From Disaster to Recovery it’s just a matter of choosing the proper tools, software and the right partners. In my next post I will detail 3 Disaster Recovery architectures using Database Cloud Backup Service, Data Guard, and obviously the Oracle Public Cloud environment.


**The views expressed in this post are my own and do not necessarily reflect the views of Oracle.

Oracle Developer Cloud Service provides you with following capabilities as far as JUnit is concerned


  • Viewing the list of all executed tests and the cumulative test metrics
  • Test Result History to track the history of all tests in a graphical form


This blog contains a simple JPA based project which uses an in-memory Derby database to execute JUnit tests. You will see how to


  • Setup the source code in your Developer Cloud service instance Git repository
  • Configure the build process along with the JUnit test related actions
  • Execute the build and track the test results





Unit test


The JUnit test case


public class JSRRepositoryTest {

    public JSRRepositoryTest() {
    static Map<String, String> props = new HashMap<>();
    final static String PU_NAME = "derby-in-memory-PU";

    public static void setUpClass() {

        props.put("javax.persistence.jdbc.url", "jdbc:derby:target/derbydb;create=true");
        props.put("javax.persistence.jdbc.driver", "org.apache.derby.jdbc.EmbeddedDriver");
        JPAFacade.bootstrapEMF(PU_NAME, props);


    public static void tearDownClass() {
        props = null;


    JSRRepository cut;

    public void setUp() {
        cut = new JSRRepository();

    public void tearDown() {
        //nothing to do

    public void getSingleJSRTest() {
        JavaEESpecification spec = cut.get("123");
        assertNotNull("Spec was null!", spec);
        assertEquals("Wrong spec id", spec.getJsrId(), new Integer(123));
        assertEquals("Wrong spec name", spec.getName(), "jsonb");

    @Test(expected = RuntimeException.class)
    public void getSingleJSRTestForNullValue() {


    @Test(expected = RuntimeException.class)
    public void getSingleJSRTestForBlankValue() {


    public void getSingleJSRTestForInvalidValue() {
        JavaEESpecification spec = cut.get("007");
        assertNull("Spec was not null!", spec);

    public void getAllJSRsTest() {
        List<JavaEESpecification> specs = cut.all();
        assertNotNull("Specs list was null!", specs);
        assertEquals("2 specs were not found", specs.size(), 2);

    public void createNewJSRTest() {
        JavaEESpecification newSpec = new JavaEESpecification(366, "Java EE Platform", "8");
        JavaEESpecification spec = cut.get("366");
        assertNotNull("Spec was null!", spec);
        assertEquals("Wrong spec id", spec.getJsrId(), new Integer(366));
        assertEquals("Wrong spec name", spec.getName(), "Java EE Platform");
        assertEquals("Wrong spec version", spec.getVersion(), "8");

    public void updateJSRDescTest() {

        String specID = "375";
        String oldDesc = "security for the Java EE platform";
        String newDesc = "updated desc on " + new Date();

        JavaEESpecification newSpec = new JavaEESpecification(Integer.parseInt(specID), oldDesc, "Security", "1.0");
        JavaEESpecification updatedSpec = new JavaEESpecification(Integer.parseInt(specID), newDesc, "Security", "1.0");

        JavaEESpecification spec = cut.get(specID);

        assertNotNull("Spec was null!", spec);
        assertEquals("Description was not updated", spec.getDescription(), newDesc);
        assertEquals("Wrong spec id", spec.getJsrId(), new Integer(specID));
        assertEquals("Wrong spec name", spec.getName(), "Security");
        assertEquals("Wrong spec version", spec.getVersion(), "1.0");


Project & code repository creation


Create a project in your Oracle Developer Cloud instance








Create a Git repository – browse to the Home tab, click New Repository and follow the steps






You should see your new repository created


Populating the Git repo


Push the project from your local system to your Developer Cloud Git repo you just created. We will do this via command line and all you need is Git client installed on your local machine. You can use this or any other tool of your choice


cd <project_folder> 
git init
git remote add origin <developer_cloud_git_repo>
git add .
git commit -m "first commit"
git push -u origin master  //Please enter the password for your Oracle Developer Cloud account when prompted


You should be able to see the code in your Developer Cloud console




Configure build job










Activate the following post build actions


  • Publishing of JUnit test result reports
  • Archiving of test reports (if needed)





Trigger build



Check test results


After the build process is over (it will fail in this case), check the top right corner of your build page and click Tests



Overall metrics



Failed tests snapshot



Failed test details



Example of a passed test



Result History





**The views expressed in this post are my own and do not necessarily reflect the views of Oracle.