Wednesday, December 5, 2018

Node.js musings part I: node version management

I started programming at a very young age, when I was twelve. My first programming language was Basic. I wrote a program that would generate random calculation problems in different categories (under 10, under 100). If the answer given by the user was incorrect, a picture based on 10 x 10 squares would show the correct answer visually.
It was actually used by a remedial teacher (my mom 😉) on our home computer.

Since then I learned a language comparable to Pascal, I used LISP in university, took classes in C, C++, MFC, Visual Basic and Java.

The next software I wrote was after I graduated, for a marketing department. They showed calculations of how much water a water closet or shower would use in different languages. I wrote it in Visual Basic. That was the first time I learned about the hassle of versions in real life.
The program ran fine on my Windows machine (I think it was Windows 95). But on the sales persons machine it would not print. The library was incompatible with my compiled code. I was in 'DLL hell' 😱 as my professor used to call it.

I stayed away from procedural language and decided to focus on Java and JEE. I loved it! No issues with native libraries, object orientation to structure your code, automated builds, test frameworks etc etc.
Of course, I was involved in multiple projects. Some projects would support Java version 1.4 others 1.5 etc.  First I started having different versions on my machine and updating environment variables, but quickly I would need application servers etc as well, so I started creating Virtual Images for Virtual Box and have different versions of the JDK and application versions there.At least I had no issues with native libraries, like I remembered from Visual Basic! It was not ideal, but I managed and felt in control.

Today we are doing more and more projects in the (Oracle) Cloud. We are doing projects in Oracle SOA CS, Oracle Integration Cloud Service, Oracle API Platform Cloud Service and Oracle Mobile Cloud Service.
Oracle Mobile Cloud Service is expecting node.js code for the mobile backend functions that you write. This meant I had to learn JavaScript. Not everything was easy from the start: The asynchronous nature of Node was something I definitely had to get used to.  asynch/await to the rescue ;)
The beauty: no more application servers, no more multiple VMs for different versions: just code! So far so good. :)

Then, we moved to a different version of the cloud service and upgraded our node version to version 8.11.3. and happily start using the new version. I think right now we are on version 11. Of course this does not have a happy end: a week ago I started investigating Oracle BlockChain Cloud Service. It expects node version 6 😰. And now I am back in version hell: node.js uses specific native libraries under the covers, that of course are not the same between the different versions. I need to be able to switch between versions. Some projects expect the paths to be pointing to the right versions and of course constructs like await are not supported, so running my code in Netbeans becomes complicated...

nvm-win to the rescue

I was considering creating images for Virtual Box again (also because I still like bash better than windows Powershell), but I decided to research the topic a little bit. I stumbled upon this project: nvm-windows

It look really good: I can switch versions without having to fiddle around with the path or environments myself, it is all managed by this package that is written in go (another language I might want to learn, but one thing at the time ;) )

Here is how to install it on Windows:
  1. Uninstall node from your local machine. Remove all folders related to it C:\Users\{username}\AppData\Roamding\npm and C:\Users\{username}\AppData\Roamding\npm-cache
  2. Download nvm-setup.zip
  3. Unzip it
  4. Run nvm-setup and accept the defaults
  5. Open a new Powershell window and type nvm
  6. It will show the version (1.1.7 in my case)
  7. Install the versions of node you need. In my case
    1. nvm install 6
    2. nvm install 8
    3. nvm install latest
You can now list your versions, and use the one you would like to use by typing
  • nvm list
  • nvm use 6.15.1
I am not sure I love Node.js and javascript as much (yet) as I love Java, but it might happen in the future ....

Any comments and pointers on how you deal with versions of node are much appreciated, please feel free to comment on this blog or tweet them!

Happy coding 😏

Monday, December 3, 2018

Setting up fn on Kubernetes in the Oracle Cloud (OKE)

In this post I will briefly describe how you can install fn on Kubernetes in the Oracle Cloud (OKE).

Prerequisites

  1. You need to have access to Oracle Cloud Infrastructure (OCI) with a unique account. If you have a federated account, you should create another one to be able to create a kubernetes cluster. This account must have either Administrator privileges or belong to a group to which a policy grants the appropriate Container Engine for Kubernetes permissions. Since my example is for R&D purposes, I will be using an account with Administrator privileges.
  2. Install and configure the OCI CLI, generate an API signing key pair and add that public key to your username. 
  3. Create a separate compartment for the cluster and make sure your compartment has the necessary resources and your root compartments needs the policy Allow service OKE to manage all-resources in tenancy 
  4. Install and setup kubectl on Windowns (tip: use Chocolatey)
  5. Install helm

Create the Kubernetes cluster

  1. Navigate to your console
  2. Under Developer Services, select "clusters"
  3. Pick the compartment that you created or want to use
  4. Click on "Create Cluster" and accept all the defaults
  5. Click "Create"
  6. Inspect the details 
  7. Download the kubeconfig file and store it in your .kube directory
If it fails because of service limits, raise an SR with Oracle support to get your limits increased.

Install fn 

  1. Make sure your server version of helm is up to date (helm init --upgrade)
  2. Create a directory fnhelm
  3. Clone the git repo: git clone https://github.com/fnproject/fn-helm.git
  4. Install the chart dependencies: helm dep build fn
  5. Install it in your cluster: helm install --name my-release fn

Deploy your function to the cluster

  1. Make sure you are logged in to your dockerhub account
  2. Set the fn context to the right value
  3. Deploy the function to the cluster

The fn context

When you use fn deploy, it uses a context to determine where to deploy to, and what registry to use. The URL for the fnserver you deployed to the kubernetes cluster  can be found by issuing the following command

  • $(kubectl get svc --namespace default my-release-fn-api -o jsonpath='{.status.loadBalancer.ingress[0].ip}'):80
However, you can also look it up using a kubectl proxy: 
  • kubectl proxy 
  • Navigate to a browser: https://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#
  • Select "Services" in the navigation menu at the left


  • Click on the External Endpoint of the my-release-fn-api 
  • You should see the following:
Now we can create the context by running the following commands:
  • fn list contexts
  • fn create context ociLonneke --api-url [your url] --provider default --registry [your_dockerhub_username]
  • fn list contexts

Deploy the function to the cluster

Finally! We are ready to deploy our first function to our cluster. In this case I use the Java tutorial example. 
  • fn init --runtime java --trigger http javafn
  • fn build
  • fn deploy --app java-app
This will result in the following output (or something similar)

Successfully created app:  java-app
Successfully created function: javafn with lonneke/javafn:0.0.2
Successfully created trigger: javafn-trigger
Trigger Endpoint: http://xxx.xx.xx.xx:80/t/java-app/javafn-trigger

Test the function

Open a browser and type the url as stated by the trigger endpoint. You should see the following result:

Next steps

Now you have your kubernetes cluster up and running, you can move your functions from your local installation to the cluster and start using them in production!

Happy coding 😊