SAP Cloud Platform & Cloud Foundry – test, feedback, tips and tricks

After you followed all the steps to setting up Cloud Foundry in your SAP Cloud Platform Cockpit, it’s time to dig into and like all new environment you are testing, you’ll face some problems.

In this article, I’ll quickly overview the activation/installation and talk about a simple NodeJS with a MongoDB scenario. I hope it will help you to be more familiar with the tools, to implement your own needs on the platform.

Quick CF activation/installation

Install CF on your machine and follow instructions detailed here. One it’s installed, you need to test the CF CLI by typing cf in your favorite terminal.

A quota was not automatically assigned for my account because I had several sub accounts. Then, when I deployed an application, I get an error message:

Activate MongoDB / PostgreSQL and other services

Follow the path: Cloud Foundry > Services > Service Marketplace and activate the services you want to use. You can directly map the service with your app if you have already deployed it.

Create and deploy a NodeJS

First, you need to create a skeleton NodeJS project using the Nodeclipse available for free on the Eclipse Market or create your own project from scratch using the framework your like. You can simply download this project from my Github account : js-app-for-sap-cloud-foundry.

If you are not using mongodb in the scenario, you can comment the line require(‘./server/db/mongo-connect.js’)(oAppEnv);. It simplifies the workflow, you can uncomment it later. When your project is ready, be sure it compiles by running the two following commands:

npm install
node app.js

If all is OK, your project is ready to be hosted on CF.

// Logon to Could Foundry
cf login
// Enter your credentials and navigate to the space you want to host the app
// Change directory and push it!
cd js-app-for-sap-cloud-foundry
cf push

The file manifest.yml is very important for your app deployment, to specify the app information: commands, name, buildpack, etc. Below, an example of manifest.yml file

---
applications:
- name: js-app
  memory: 512M
  host: js-app
  command: node app.js

Fields you need to know for the manifest.yml file:

Key Value
name The name of the application
buildpack The name of the Node.js buildpack determined before with command cf buildpacks. (by default an auto determination of the buildpack is done if the buildpack information is missing)
command For NodeJS apps, a start command is needed to start the application. Here for example, it’s “node app.js”.
memory RAM available for the application.
disk_quota Disk space available for the application.
host Host information used in the URL which makes the application accessible.

Connect with a MongoDB

The first step is to create a new MongoDB instance. You have to go to your SAP CP CF sub account > Services > Service Marketplace and select MongoDB. Now in your left panel you can select Instances and create a new one (see below)

Now you are able to map your instance with the app you deployed before. The manifest.yml will change a little bit and the service will be mapped like this:

---
applications:
- name: js-app
  memory: 512M
  host: js-app
  command: node app.js
  services:
  - mongodb-service 

/!\ “mongodb-service” is the name of you instance, you need to adapt /!\

Useful links

Github | SAP/hcp-cloud-foundry-tutorials
SAP CP | Cloud Foundry Tutorials
Github | Cloud Foundry CLI
Cloud Foundry CLI Reference Guide

Useful CLI commands

cf
cf apps
cf login
cf logout
cf push
cf buildpacks
cf marketplace
cf api api.cf.<host information>
cf create-service mongodb v3.0-dev mongo-service

Google Apps Script: Get current user email from a spreadsheet Add-On

Retrieve the current user email using App Script in your Spreadsheet Add-On is a little bit tricky. You can easily use the Session object to get it but in some cases, this object will return undefined.

Current user email using Session object

var userEmail = Session.getActiveUser().getEmail();

So, you need to find a workaround. The workaround could be to use the PropertyService object.

Current user email using PropertiesService object

var userEmail = PropertiesService.getUserProperties().getProperty('userEmail');

Why not, that’s another way to get it but not 100% too. If you want to secure it and combine another way to get it, you need to work with the sheet protection.

Current user email using spreadsheet protection

var protection = SpreadsheetApp.getActive().getRange('A1').protect();
protection.removeEditors(protection.getEditors());
var editors = protection.getEditors();
if (editors.length === 2) {
    var owner = SpreadsheetApp.getActive().getOwner();
    editors.splice(editors.indexOf(owner), 1);
}
userEmail = editors[0];
protection.remove();
PropertiesService.getUserProperties().setProperty('userEmail', userEmail);

Free to play

The full method, ready to use, capy-paste in your code and have fun:

function getCurrentUserEmail() {
    var userEmail = Session.getActiveUser().getEmail();
    if (userEmail === '' || !userEmail || userEmail === undefined) {
        userEmail = PropertiesService.getUserProperties().getProperty('userEmail');
        if (!userEmail) {
            var protection = SpreadsheetApp.getActive().getRange('A1').protect();
            protection.removeEditors(protection.getEditors());
            var editors = protection.getEditors();
            if (editors.length === 2) {
                var owner = SpreadsheetApp.getActive().getOwner();
                editors.splice(editors.indexOf(owner), 1);
            }
            userEmail = editors[0];
            protection.remove();
            PropertiesService.getUserProperties().setProperty('userEmail', userEmail);
        }
    }
    return userEmail;
}

Dynamic port & Bower + Grunt scripts with Heroku host

I use Heroku to host some project like Osprey, and I need to admit that this is really a nice platform to host your personal projects for free. It’s really easy to start with but you need to know a few of things…

First of all, check the Node tutorial provided by Heroku.

Bower & Grunt

If you have some bower or grunt scripts to launch after the npm install and before the npm start, you need to add a bash script reference in your package.json file. Your package.json file will contain a postinstall command:

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "start": "node server.js",
  "postinstall": "bash ./build.sh"
},

And your build.sh file should contain all the commands to build the rest of your project (copy, move files, etc…)

#!/bin/bash
./node_modules/bower/bin/bower install
./node_modules/grunt-cli/bin/grunt

Dynamic port

Heroku assigns dynamically a port to your app. So, if you have set a fixed port in your server.js file, it will not work with the heroku deployment. The port is added to the process.env.PORT variable so you need to pull it from there. You app.listen method should look something like this:

var port = process.env.PORT;
app.listen(port || 3000);

Google Photos, bring back your filters (Deimos, Ariel, Triton, Phobos, etc…)

Since Novembre 2016, Google has “improved” the Google Photos app, but they simply removed all filters for something that is not equal… I’ve sent a feedback through the Google Photos contact form (https://photos.google.com/ > left menu > give feedback).

The workaround is to download an old version of Google Photos and install to a simulator or on your phone. You can find all APK versions on the APKMirror website.

If you don’t know which version is needed for your phone, check on Google your phone architecture version and dpi. For example, for a Nexus 5X, it’s arm64 – dpi 420 (default), so you need to download the 540717 (October 31, 2016) version which corresponds to: arm64, Android 4.1+, 400-480dpi

Forum posts

Google Forum – Is there way to use the previous filter?

Google, bring back your filters! They were good!

Developer / Coder / Programmer, you may have to celebrate something today!

That’s my list of events related to computer science that you have to celebrate at office with your colleagues. So you have no excuse to clean out your computer in February, do a backup in March or celebrate all your killed Bugs during the year in December. There is a lot of other days to celebrate, you can find my list and feel free to contribute.

And please, don’t forget to bring croissants at office…

January Event
15 Jan Wikipedia Day
25 Jan Macintosh Computer Day
28 Jan Data Privacy Day
February Event
04 Feb Facebook’s Birthday
08 Feb Clean Out Your Computer Day
20 Feb Introduce a Girl to Engineering Day
22 Feb World Thinking Day
March Event
14 Mar Pi day
31 Mar World Backup Day
April Event
05 Apr Annual CSS Naked Day
21 Apr High Five Day
27 Apr Morse Code Day
May Event
01 May CSS Reboot Day
22 May The Ethernet Birthday
25 May Geek Pride Day
June Event
23 Jun Alan Turing’s Birthday
July Event
06 Jul Take Your Webmaster to Lunch Day
22 Jul Pi Approximation Day
26 Jul System Administrator Appreciation Day
September Event
07 Sep Google Commemoration Day
12 Sep Programmer’s Day
20 Sep Software Freedom Day
October Event
16 Oct Steve Jobs Day
November Event
25 Nov Update Your Parents Browser Day
30 Nov Computer Security Day
December Event
02 Dec Kill a Bug Day

Cheers.