Пропустить навигацию
Edi-Oracle

Orchestrations in Oracle IaaS with Chef

Опубликовано: Edi-Oracle 31.10.2016

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.

                     ChefServer-in-OPC.png

 

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:

 

Chef_101.png

 

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.

                                         Chef_103.png

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.

Andrei Manoliu-Oracle

From Disaster to Recovery part II

Опубликовано: Andrei Manoliu-Oracle 26.10.2016

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:

 

Component
Details
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:

 

jet-mcs-salescloud.png

 

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.

mcs-backend-settings.png

 

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.

mcs-api-general.png

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

mcs-api-endpoints.png

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

mcs-api-endpoint.png

 

  • 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”

Package.json

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

 

rdhsalesapplapi.js

 

/**
 * 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;
                result.push(temp);
            });
            res.send(statusCodeOk, result);
            res.end;
        };
        //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));
        sdk.rest.get(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.

  mcs-connector-general.png

  • 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

mcs-connector-securityconfiguration.png

 

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.

mcs-backend-api.png

 

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:

 

<SSO_Token_Endpoint>?clientID=<client_ID>

 

example: https://xyz.oraclecorp.com:443/mobile/platform/sso/token?clientID=5xxxx7-bf49-45c1-aeda-2xxx4

 

The browser login screen shall look like:

browser-sso-login-screen.png

 

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

 

browser-sso-token-screen.png

 

B.  Test Custom API using MCS UI Test Endpoint

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

mcs-api-testendpoint.png

 

 

Upon Success : Status 200 , data would be displayed:

mcs-api-testendpoint-result.png

 

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:

mcs-additions.png

 

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

var mcs_config = {
  "logLevel": 3,
  "mobileBackends": {
    "RDXTESTSSO": {
      "default": true,
      "baseUrl": "https://xxx.oraclecorp.com:443",
      "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"
        },
        "facebookAuth":{
          "facebookAppId": "YOUR_FACEBOOK_APP_ID",
          "backendId": "YOUR_BACKEND_ID",
          "anonymousToken": "YOUR_BACKEND_ANONYMOUS_TOKEN"
        },
        "ssoAuth":{
          "clientId": "5xxxxxx7-bf49-45c1-aeda-2xxxxx4",
          "clientSecret": "yxxxxxxx",
          "tokenEndpoint": "https://xxx.oraclecorp.com:443/mobile/platform/sso/token"
        }
      }
    }
  }
};

 

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:

 paths:
                    //injector:mainReleasePaths
                            {
                                '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'
                            }
                    //endinjector

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);
                self.data = ko.observableArray();
                self.buttonSSOLogin = function () {
                    initializeMCS();
                };

 

 

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();
                    mcs.MobileBackendManager.setConfig(mcs_config);
                    backend = mcs.MobileBackendManager.getMobileBackend("RDXTESTSSO");
                    if (backend != null) {
                        backend.setAuthenticationType("ssoAuth");
                        ssoLogin();
                    }
                }

Step 2. Authenticate and Log In Using the SDK:

function ssoLogin() {
                    backend.Authorization.authenticate(
                            function (statusCode, data) {
                                console.log(data);
                                console.log(statusCode);
                                alert("SSO Login success, status:" + statusCode);                               
                                fetchSalesCloudData(data.access_token);
                            },
                            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";
                    console.log(mcsbackendURL);
                    var token = "Bearer " + ssoToken;
                    console.log(token);
                    var settings = {
                        "async": true,
                        "crossDomain": true,
                        "url": mcsbackendURL,
                        "method": "GET",
                        "headers": {
                            "authorization": token
                        }
                    };
                    $.ajax(settings).done(function (response) {
                        console.log(response);
                        $.each(response, function () {
                            self.data.push({
                                Name: this.Name,
                                OptyId: this.OptyId,
                                OptyNumber: this.OptyNumber,
                                SalesStage: this.SalesStage,
                                Revenue: this.Revenue
                            });
                        });
                        self.dataReady = true;
                        displaySalesCloudData();
                    });
                }

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  

 

Output

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

1. Application Icon:

app-icon.png

 

2. SSO Login

 

app-dashboard-sso-login-button.png

 

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

app-login-page.png

 

4. Success Alert message

app-login-success.png

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

app-dashboard-filmstrip.png

Andrei Manoliu-Oracle

From Disaster to Recovery Part I

Опубликовано: Andrei Manoliu-Oracle 05.10.2016

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

 

 

Steps

 

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";


    @BeforeClass
    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);


    }


    @AfterClass
    public static void tearDownClass() {
        props.clear();
        props = null;


        JPAFacade.closeEMF();
    }


    JSRRepository cut;


    @Before
    public void setUp() {
        cut = new JSRRepository();
    }


    @After
    public void tearDown() {
        //nothing to do
    }


    @Test
    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() {
        cut.get(null);


    }


    @Test(expected = RuntimeException.class)
    public void getSingleJSRTestForBlankValue() {
        cut.get("");


    }


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


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


    @Test
    public void createNewJSRTest() {
        JavaEESpecification newSpec = new JavaEESpecification(366, "Java EE Platform", "8");
        cut.newJSR(newSpec);
        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");
    }


    @Test
    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");
        cut.newJSR(newSpec);
        JavaEESpecification updatedSpec = new JavaEESpecification(Integer.parseInt(specID), newDesc, "Security", "1.0");


        cut.updateJSRDescription(updatedSpec);
        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>
//e.g. https://john.doe@developer.us.oraclecloud.com/developer007-foodomain/s/developer007-foodomain-project_2009/scm/junit-sample-app-repo.git 
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

 

 

 

 

 

 

 

Important

 

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.