Node.js Runtime Guide

For Use with Red Hat OpenShift Application Runtimes

This guide provides details on using the {NodeJS} runtime with Red Hat OpenShift Application Runtimes.

Preface

This guide covers concepts as well as practical details needed by developers to use the Node.js runtime.

Chapter 1. Node.js Runtime Details

Node.js is based on the V8 JavaScript engine from Google and allows you to write server-side JavaScript applications. It provides an I/O model based on events and non-blocking operations that enables you to write applications that are both lightweight and efficient. Node.js also provides a large module ecosystem called npm. Check out Additional Resources for further reading on Node.js.

The Node.js runtime enables you to run Node.js applications and services on OpenShift while providing all the advantages and conveniences of the OpenShift platform such as rolling updates, continuous delivery pipelines, service discovery, and canary deployments. OpenShift also makes it easier for your applications to implement common microservice patterns such as externalized configuration, health check, circuit breaker, and failover.

Chapter 2. Missions and Cloud-Native Development on OpenShift

What are Missions?

Missions are working applications that showcase different fundamental pieces of building cloud native applications and services.

A teaching tool, or a sandbox for understanding how to develop applications for your project

They can also be updated or extended for your own use case

What is a Booster?

A booster is the implementation of a mission in a specific runtime. Boosters are preconfigured, functioning applications that demonstrate a fundamental aspect of modern application development and run in an environment similar to production.

Each mission is implemented in one or more runtimes. Both the specific implementation and the actual project that contains your code are called a booster.

For example, the REST API Level 0 mission is implemented for these runtimes:

Chapter 3. Available Missions and Boosters for Node.js

3.1. REST API Level 0 Mission - Node.js Booster

The REST API Level 0 mission shows how to map business operations to a remote procedure call endpoint over HTTP using a REST framework. This corresponds to Level 0 in the Richardson Maturity Model. Creating an HTTP endpoint using REST and its underlying principles to define your API lets you quickly prototype and design the API flexibly. For more information on REST, see Section 3.1.6, “REST Resources”.

This booster introduces the mechanics of interacting with a remote service using the HTTP protocol. It allows you to:

Execute an HTTP GET request on the api/greeting endpoint.

Receive a response in JSON format with a payload consisting of the Hello, World! String.

Execute an HTTP GET request on the api/greeting endpoint while passing in a String argument. This uses the name request parameter in the query string.

Receive a response in JSON format with a payload of Hello, $name! with $name replaced by the value of the name parameter passed into the request.

Viewing the Booster source code and README

To view the source code and README file of this booster, use developers.redhat.com/launch or the Fabric8 Launcher tool on a Single-node OpenShift Cluster to generate your own version of the booster. From there you can view the generated GitHub repository or download and extract the ZIP file containing the booster code.

The MY_APP_NAME-1-aaaaa pod should have a status of Running once it is fully deployed and started. Your specific pod name will vary. The number in the middle will increase with each new build. The letters at the end are generated when the pod is created.

The route information of a pod gives you the base URL which you use to access it. In the example above, you would use http://MY_APP_NAME-MY_PROJECT_NAME.OPENSHIFT_HOSTNAME as the base URL to access the application.

Although each method uses the same oc commands to deploy your application, using Fabric8 Launcher provides an automated booster deployment workflow that executes the oc commands for you.

3.1.3.1. Getting the Fabric8 Launcher Tool URL and Credentials

You need the Fabric8 Launcher tool URL and user credentials to create and deploy boosters on Single-node OpenShift Cluster. This information is provided when the Single-node OpenShift Cluster is started.

3.1.3.3. Authenticating the oc CLI Client

To work with boosters on Single-node OpenShift Cluster using the oc command-line client, you need to authenticate the client using the token provided by the Single-node OpenShift Cluster web interface.

The MY_APP_NAME-1-aaaaa pod should have a status of Running once it is fully deployed and started. Your specific pod name will vary. The number in the middle will increase with each new build. The letters at the end are generated when the pod is created.

The route information of a pod gives you the base URL which you use to access it. In the example above, you would use http://MY_APP_NAME-MY_PROJECT_NAME.OPENSHIFT_HOSTNAME as the base URL to access the application.

3.2. Externalized Configuration Mission - Node.js Booster

The Externalized Configuration mission provides a basic example of using a ConfigMap to externalize configuration. ConfigMap is an object used by OpenShift to inject configuration data as simple key and value pairs into one or more Linux containers while keeping the containers independent of OpenShift.

This mission shows you how to:

Set up and configure a ConfigMap.

Use the configuration provided by the ConfigMap within an application.

Deploy changes to the ConfigMap configuration of running applications.

3.2.1. About Externalized Configuration

It is important for the application configuration to be externalized and separated from its code. This allows the application configuration to change as it moves through different environments while leaving the code unchanged. This also keeps sensitive or internal information out of your code base and version control. Many languages and application servers provide environment variables to support externalizing an application’s configuration. Microservices architectures and polyglot environments add a layer of complexity to managing an application’s configuration. Applications are comprised of independent, distributed services, each potentially with its own configuration. This creates a maintenance challenge to keep the configuration synchronized and accessible from all services.

ConfigMaps enable the application configuration to be externalized and used in individual Linux containers and pods on OpenShift. You can create a ConfigMap object in a variety of ways, including using a YAML file, and inject it into the Linux container. ConfigMaps also allow sets of configuration data to be easily grouped and scaled. This lets you configure an arbitrarily large number of environments beyond the basic Development, Stage, and Production. You can find more information about ConfigMaps in the OpenShift documentation.

Viewing the Booster source code and README

To view the source code and README file of this booster, use developers.redhat.com/launch or the Fabric8 Launcher tool on a Single-node OpenShift Cluster to generate your own version of the booster. From there you can view the generated GitHub repository or download and extract the ZIP file containing the booster code.

The MY_APP_NAME-1-aaaaa pod should have a status of Running once its fully deployed and started. Your specific pod name will vary. The number in the middle will increase with each new build. The letters at the end are generated when the pod is created.

The route information of a pod gives you the base URL which you use to access it. In the example above, you would use http://MY_APP_NAME-MY_PROJECT_NAME.OPENSHIFT_HOSTNAME as the base URL to access the application.

Although each method uses the same oc commands to deploy your application, using Fabric8 Launcher provides an automated booster deployment workflow that executes the oc commands for you.

3.2.4.1. Getting the Fabric8 Launcher Tool URL and Credentials

You need the Fabric8 Launcher tool URL and user credentials to create and deploy boosters on Single-node OpenShift Cluster. This information is provided when the Single-node OpenShift Cluster is started.

3.2.4.3. Authenticating the oc CLI Client

To work with boosters on Single-node OpenShift Cluster using the oc command-line client, you need to authenticate the client using the token provided by the Single-node OpenShift Cluster web interface.

The MY_APP_NAME-1-aaaaa pod should have a status of Running once its fully deployed and started. Your specific pod name will vary. The number in the middle will increase with each new build. The letters at the end are generated when the pod is created.

The route information of a pod gives you the base URL which you use to access it. In the example above, you would use http://MY_APP_NAME-MY_PROJECT_NAME.OPENSHIFT_HOSTNAME as the base URL to access the application.

3.2.6. Interacting with the Unmodified Node.js Booster

The booster provides a default HTTP endpoint that accepts GET requests.

Use curl to execute a GET request against the booster. You can also use a browser to do this.

$ curl http://MY_APP_NAME-MY_PROJECT_NAME.OPENSHIFT_HOSTNAME/api/greeting
{"content":"Hello, World from a ConfigMap !"}

Update the deployed ConfigMap configuration.

$ oc edit configmap app-config

Change the value for the message key to Bonjour, %s from a ConfigMap ! and save the file.

Update of the ConfigMap should be read by the application within an acceptable time (a few seconds) without requiring a restart of the application.

Execute a GET request using curl against the booster with the updated ConfigMap configuration to see your updated greeting. You can also do this from your browser using the web form provided by the application.

$ curl http://MY_APP_NAME-MY_PROJECT_NAME.OPENSHIFT_HOSTNAME/api/greeting
{"content":"Bonjour, World from a ConfigMap !"}

3.2.7. Externalized Configuration Resources

More background and related information on Externalized Configuration and ConfigMap can be found here:

3.3. Relational Database Backend Mission - Node.js Booster

Limitation: Run this booster on a Single-node OpenShift Cluster. You can also use a manual workflow to deploy this booster to OpenShift Online Pro and OpenShift Container Platform. This booster is not currently available on OpenShift Online Starter.

The Relational Database Backend booster expands on the REST API Level 0 booster to provide a basic example of performing create, read, update and delete (CRUD) operations on a PostgreSQL database using a simple HTTP API. CRUD operations are the four basic functions of persistent storage, widely used when developing an HTTP API dealing with a database.

The booster also demonstrates the ability of the HTTP application to locate and connect to a database in OpenShift. Each runtime shows how to implement the connectivity solution best suited in the given case. The runtime can choose between options such as using JDBC, JPA, or accessing ORM APIs directly.

The booster application exposes an HTTP API, which provides endpoints that allow you to manipulate data by performing CRUD operations over HTTP. The CRUD operations are mapped to HTTP Verbs. The API uses JSON formatting to receive requests and return responses to the user. The user can also use an UI provided by the booster to use the application. Specifically, this booster provides an application that allows you to:

Navigate to the application web interface in your browser. This exposes a simple website allowing you to perform CRUD operations on the data in the my_data database.

Execute an HTTP GET request on the api/fruits endpoint.

Receive a response formatted as a JSON array containing the list of all fruits in the database.

Execute an HTTP GET request on the api/fruits/* endpoint while passing in a valid item ID as an argument.

Receive a response in JSON format containing the name of the fruit with the given ID. If no item matches the specified ID, the call results in an HTTP error 404.

Execute an HTTP POST request on the api/fruits endpoint passing in a valid name value to create a new entry in the database.

Execute an HTTP PUT request on the api/fruits/* endpoint passing in a valid ID and a name as an argument. This updates the name of the item with the given ID to match the name specified in your request.

Execute an HTTP DELETE request on the api/fruits/* endpoint, passing in a valid ID as an argument. This removes the item with the specified ID from the database and returns an HTTP code 204 (No Content) as a response. If you pass in an invalid ID, the call results in an HTTP error 404.

This booster does not showcase a fully matured RESTful model (level 3), but it does use compatible HTTP verbs and status, following the recommended HTTP API practices.

Viewing the Booster source code and README

To view the source code and README file of this booster, use developers.redhat.com/launch or the Fabric8 Launcher tool on a Single-node OpenShift Cluster to generate your own version of the booster. From there you can view the generated GitHub repository or download and extract the ZIP file containing the booster code.

3.3.1. Relational Database Backend design tradeoffs

Table 3.3. Design Tradeoffs

Pros

Cons

Each runtime determines how to implement the database interactions. One can use a low-level connectivity API such as JDBC, some other can use JPA, and yet another can access ORM APIs directly. Each runtime decides what would be the best way.

Each runtime determines how the schema is created.

The PostgreSQL database example provided with this mission is not backed up with persistent storage. Changes to the database are lost if you stop or redeploy the database pod. To use an external database with your mission’s pod in order to preserve changes, see the Integrating External Services chapter of the OpenShift Documentation. It is also possible to set up persistent storage with database containers on OpenShift. (For more details about using persistent storage with OpenShift and containers, see the Persistent Storage, Managing Volumes and Persistent Volumes chapters of the OpenShift Documentation).

Alternatively, if you downloaded a ZIP file of your project, extract it.

$ unzip MY_PROJECT_NAME.zip

Create a new OpenShift project.

$ oc new-project MY_PROJECT_NAME

Navigate to the root directory of your booster.

Deploy the PostgreSQL database to OpenShift. Ensure that you use the following values for user name, password, and database name when creating your database application. The booster application is pre-configured to use these values. Using different values prevents your booster application from integrating with the database.

The my-database-1-aaaaa pod should have a status of Running and should be indicated as ready once it is fully deployed and started. Your specific pod name will vary. The number in the middle will increase with each new build. The letters at the end are generated when the pod is created.

Use npm to start the deployment to OpenShift.

$ npm install && npm run openshift

These commands install any missing module dependencies, then using the Nodeshift module, deploy the booster on OpenShift.

The route information of a pod gives you the base URL which you use to access it. In the example above, you would use http://MY_APP_NAME-MY_PROJECT_NAME.OPENSHIFT_HOSTNAME as the base URL to access the application.

Although each method uses the same oc commands to deploy your application, using Fabric8 Launcher provides an automated booster deployment workflow that executes the oc commands for you.

3.3.3.1. Getting the Fabric8 Launcher Tool URL and Credentials

You need the Fabric8 Launcher tool URL and user credentials to create and deploy boosters on Single-node OpenShift Cluster. This information is provided when the Single-node OpenShift Cluster is started.

3.3.3.3. Authenticating the oc CLI Client

To work with boosters on Single-node OpenShift Cluster using the oc command-line client, you need to authenticate the client using the token provided by the Single-node OpenShift Cluster web interface.

Alternatively, if you downloaded a ZIP file of your project, extract it.

$ unzip MY_PROJECT_NAME.zip

Create a new OpenShift project.

$ oc new-project MY_PROJECT_NAME

Navigate to the root directory of your booster.

Deploy the PostgreSQL database to OpenShift. Ensure that you use the following values for user name, password, and database name when creating your database application. The booster application is pre-configured to use these values. Using different values prevents your booster application from integrating with the database.

The my-database-1-aaaaa pod should have a status of Running and should be indicated as ready once it is fully deployed and started. Your specific pod name will vary. The number in the middle will increase with each new build. The letters at the end are generated when the pod is created.

Use npm to start the deployment to OpenShift.

$ npm install && npm run openshift

These commands install any missing module dependencies, then using the Nodeshift module, deploy the booster on OpenShift.

The route information of a pod gives you the base URL which you use to access it. In the example above, you would use http://MY_APP_NAME-MY_PROJECT_NAME.OPENSHIFT_HOSTNAME as the base URL to access the application.

3.4. Health Check Mission - Node.js Booster

When you deploy an application, its important to know if it is available and if it can start handling incoming requests. Implementing the health check pattern allows you to monitor the health of an application, which includes if an application is available and whether it is able to service requests.

The purpose of this use case is to demonstrate the health check pattern through the use of probing. Probing is used to report the liveness and readiness of an application. In this use case, you configure an application which exposes an HTTP health endpoint to issue HTTP requests. If the container is alive, according to the liveness probe on the health HTTP endpoint, the management platform receives 200 as return code and no further action is required. If the health HTTP endpoint does not return a response, for example if the thread is blocked, then the application is not considered alive according to the liveness probe. In that case, the platform kills the pod corresponding to that application and recreates a new pod to restart the application.

This use case also allows you to demonstrate and use a readiness probe. In cases where the application is running but is unable to handle requests, such as when the application returns an HTTP 503 response code during restart, this application is not considered ready according to the readiness probe. If the application is not considered ready by the readiness probe, requests are not routed to that application until it is considered ready according to the readiness probe.

3.4.1. Health Check Concepts

In order to understand the health check pattern, you need to first understand the following concepts:

Liveness

Liveness defines whether an application is running or not. Sometimes a running application moves into an unresponsive or stopped state and needs to be restarted. Checking for liveness helps determine whether or not an application needs to be restarted.

Readiness

Readiness defines whether a running application can service requests. Sometimes a running application moves into an error or broken state where it can no longer service requests. Checking readiness helps determine whether or not requests should continue to be routed to that application.

Fail-over

Fail-over enables failures in servicing requests to be handled gracefully. If an application fails to service a request, that request and future requests can then fail-over or be routed to another application, which is usually a redundant copy of that same application.

Resilience and Stability

Resilience and Stability enable failures in servicing requests to be handled gracefully. If an application fails to service a request due to connection loss, in a resilient system that request can be retried after the connection is re-established.

Probe

A probe is a Kubernetes action that periodically performs diagnostics on a running container.

Viewing the Booster source code and README

To view the source code and README file of this booster, use developers.redhat.com/launch or the Fabric8 Launcher tool on a Single-node OpenShift Cluster to generate your own version of the booster. From there you can view the generated GitHub repository or download and extract the ZIP file containing the booster code.

The MY_APP_NAME-1-aaaaa pod should have a status of Running once its fully deployed and started. You should also wait for your pod to be ready before proceeding, which is shown in the READY column. For example, MY_APP_NAME-1-aaaaa is ready when the READY column is 1/1. Your specific pod name will vary. The number in the middle will increase with each new build. The letters at the end are generated when the pod is created.

The route information of a pod gives you the base URL which you use to access it. In the example above, you would use http://MY_APP_NAME-MY_PROJECT_NAME.OPENSHIFT_HOSTNAME as the base URL to access the application.

Although each method uses the same oc commands to deploy your application, using Fabric8 Launcher provides an automated booster deployment workflow that executes the oc commands for you.

3.4.3.1. Getting the Fabric8 Launcher Tool URL and Credentials

You need the Fabric8 Launcher tool URL and user credentials to create and deploy boosters on Single-node OpenShift Cluster. This information is provided when the Single-node OpenShift Cluster is started.

3.4.3.3. Authenticating the oc CLI Client

To work with boosters on Single-node OpenShift Cluster using the oc command-line client, you need to authenticate the client using the token provided by the Single-node OpenShift Cluster web interface.

The MY_APP_NAME-1-aaaaa pod should have a status of Running once its fully deployed and started. You should also wait for your pod to be ready before proceeding, which is shown in the READY column. For example, MY_APP_NAME-1-aaaaa is ready when the READY column is 1/1. Your specific pod name will vary. The number in the middle will increase with each new build. The letters at the end are generated when the pod is created.

The route information of a pod gives you the base URL which you use to access it. In the example above, you would use http://MY_APP_NAME-MY_PROJECT_NAME.OPENSHIFT_HOSTNAME as the base URL to access the application.

3.4.5. Interacting with the Unmodified Node.js Booster

Once you have the Node.js booster deployed, you will have a service called MY_APP_NAME running that exposes the following REST endpoints:

/api/greeting

This endpoint returns a JSON containing greeting of name parameter (or World as default value).

/api/stop

This endpoint forces the service to become unresponsive which is meant to simulate a failure in the service.

The following steps demonstrate how to verify the service availability and simulate a failure. This failure of an available service causes the OpenShift self-healing capabilities to be trigger on the service.

Note

The below steps use the command line to interact with the service. Alternatively, you can use the web interface to perform the same steps (See #4).

Use curl to execute a GET request against the MY_APP_NAME service. You can also use a browser to do this.

Invoke the /api/stop endpoint and verify the availability of the /api/greeting endpoint shortly after that.

Invoking the /api/stop endpoint simulates an internal service failure and triggers the OpenShift self-healing capabilities. When invoking /api/greeting after simulating the failure, the service should return a HTTP status 503.

Use oc get pods -w to continuously watch the self-healing capabilities in action.

While invoking the service failure, you can watch the self-healing capabilities in action on OpenShift console, or with the oc client tools. You should see the number pods in a READY state move to zero (0/1) and after a short period (less than one minute) move back up to one (1/1). In addition the RESTARTS count increases every time you you invoke the service failure.

Alternatively to the interaction using the terminal window, you can use the web interface provided by the service to invoke the different methods and watch the service move through the life cycle phases.

http://MY_APP_NAME-MY_PROJECT_NAME.OPENSHIFT_HOSTNAME

Optional: Use the web console to view the log output generated by the application at each stage of the self-healing process.

Navigate to your project.

On the sidebar, click on Monitoring.

In the upper right-hand corner of the screen, click on Events to display the log messages.

Optional: Click View Details to display a detailed view of the Event log.

The health check application generates the following messages:

Message

Status

Unhealthy

Readiness probe failed. This message is expected and indicates that the simulated failure of the /api/greeting endpoint has been detected and the self-healing process starts.

Killing

The unavailable Docker container running the service is being killed before being re-created.

Pulling

Downloading the latest version of docker image to re-create the container.

Pulled

Docker image downloaded successfully.

Created

Docker container has been successfully created

Started

Docker container is ready to handle requests

3.4.6. Health Check Resources

More background and related information on health checking can be found here:

3.5. Circuit Breaker Mission - Node.js Booster

Limitation: Run this booster on a Single-node OpenShift Cluster. You can also use a manual workflow to deploy this booster to OpenShift Online Pro and OpenShift Container Platform. This booster is not currently available on OpenShift Online Starter.

The Circuit Breaker mission demonstrates a generic pattern for reporting the failure of a service and then limiting access to the failed service until it becomes available to handle requests. This helps prevent cascading failure in other services that depend on the failed services for functionality.

This mission shows you how to implement a Circuit Breaker and Fallback pattern in your services.

3.5.1. About Circuit Breaker

The Circuit Breaker is a pattern intended to mitigate the impact of network failure and high latency on service architectures where services synchronously invoke other services. In such cases, if one of the services becomes unavailable due to network failure or incurs unusually high latency values due to overwhelming traffic, other services attempting to call its endpoint may end up exhausting critical resources in an attempt to reach it, rendering themselves unusable. This condition is also known as cascading failure and can render the entire microservice architecture unusable.

Essentially, the Circuit Breaker acts as a proxy between a protected function and a remote function, which monitors for failures. Once the failures reach a certain threshold, the circuit breaker trips, and all further calls to the circuit breaker return with an error or a predefined fallback response, without the protected call being made at all. The Circuit Breaker usually also contain an error reporting mechanism that notifies you when the Circuit Breaker trips.

Why Circuit Breaker is Important

In an architecture where multiple services depend on each other for functionality, a failure in one service can rapidly propagate to its dependent services, causing the entire architecture to collapse. Implementing a Circuit Breaker pattern helps prevent this. With the Circuit Breaker pattern implemented, a service client invokes a remote service endpoint via a proxy at regular intervals. If the calls to the remote service endpoint fail repeatedly and consistently, the Circuit Breaker trips, making all calls to the service fail immediately over a set timeout period and returns a predefined fallback response. When the timeout period expires, a limited number of test calls are allowed to pass through to the remote service to determine whether it has healed, or remains unavailable. If these test calls fail, the Circuit Breaker keeps the service unavailable and keeps returning the fallback responses to incoming calls. If the test calls succeed, the Circuit Breaker closes, fully enabling traffic to reach the remote service again.

Viewing the Booster source code and README

To view the source code and README file of this booster, use developers.redhat.com/launch or the Fabric8 Launcher tool on a Single-node OpenShift Cluster to generate your own version of the booster. From there you can view the generated GitHub repository or download and extract the ZIP file containing the booster code.

Both the MY_APP_NAME-greeting-1-aaaaa and MY_APP_NAME-name-1-aaaaa pods should have a status of Running once they are fully deployed and started. You should also wait for your pods to be ready before proceeding, which is shown in the READY column. For example, MY_APP_NAME-greeting-1-aaaaa is ready when the READY column is 1/1. Your specific pod names will vary. The number in the middle will increase with each new build. The letters at the end are generated when the pod is created.

The route information of a pod gives you the base URL which you use to access it. In the example above, you would use http://MY_APP_NAME-MY_PROJECT_NAME.OPENSHIFT_HOSTNAME as the base URL to access the application.

Although each method uses the same oc commands to deploy your application, using Fabric8 Launcher provides an automated booster deployment workflow that executes the oc commands for you.

3.5.4.1. Getting the Fabric8 Launcher Tool URL and Credentials

You need the Fabric8 Launcher tool URL and user credentials to create and deploy boosters on Single-node OpenShift Cluster. This information is provided when the Single-node OpenShift Cluster is started.

3.5.4.3. Authenticating the oc CLI Client

To work with boosters on Single-node OpenShift Cluster using the oc command-line client, you need to authenticate the client using the token provided by the Single-node OpenShift Cluster web interface.

Both the MY_APP_NAME-greeting-1-aaaaa and MY_APP_NAME-name-1-aaaaa pods should have a status of Running once they are fully deployed and started. You should also wait for your pods to be ready before proceeding, which is shown in the READY column. For example, MY_APP_NAME-greeting-1-aaaaa is ready when the READY column is 1/1. Your specific pod names will vary. The number in the middle will increase with each new build. The letters at the end are generated when the pod is created.

The route information of a pod gives you the base URL which you use to access it. In the example above, you would use http://MY_APP_NAME-MY_PROJECT_NAME.OPENSHIFT_HOSTNAME as the base URL to access the application.

Once you have the Node.js booster deployed, you have the following services running:

MY_APP_NAME-name

Exposes the following endpoints:

the /api/name endpoint, which returns a name when this service is working, and an error when this service is set up to demonstrate failure.

the /api/state endpoint, which controls the behavior of the /api/name endpoint and determines whether the service works correctly or demonstrates failure.

MY_APP_NAME-greeting

Exposes the following endpoints:

the /api/greeting endpoint that you can call to get a personalized greeting response.

When you call the /api/greeting endpoint, it issues a call against the /api/name endpoint of the MY_APP_NAME-name service as part of processing your request. The call made against the /api/name endpoint is protected by the Circuit Breaker.

If the remote endpoint is available, the name service responds with an HTTP code 200 (OK) and you receive the following greeting from the /api/greeting endpoint:

{"content":"Hello, World!"}

If the remote endpoint is unavailable, the name service responds with an HTTP code 500 (Internal server error) and you receive a predefined fallback response from the /api/greeting endpoint:

{"content":"Hello, Fallback!"}

the /api/cb-state endpoint, which returns the state of the Circuit Breaker. The state can be:

open : the circuit breaker is preventing requests from reaching the failed service,

closed: the circuit breaker is allowing requests to reach the service.

The following steps demonstrate how to verify the availability of the service, simulate a failure and receive a fallback response.

Use curl to execute a GET request against the MY_APP_NAME-greeting service. You can also use the Invoke button in the web interface to do this.

3.6. Secured Mission - Node.js Booster

Limitation: Run this booster on a Single-node OpenShift Cluster. You can also use a manual workflow to deploy this booster to OpenShift Online Pro and OpenShift Container Platform. This booster is not currently available on OpenShift Online Starter.

Implements the Open ID Connect protocol which is an extension of the OAuth 2.0 specification.

Issues access tokens to provide clients with various access rights to secured resources.

Securing an application with SSO enables you to add security to your applications while centralizing the security configuration.

Important

This mission comes with Red Hat SSO pre-configured for demonstration purposes, it does not explain its principles, usage, or configuration. Before using this mission, ensure that you are familiar with the basic concepts related to Red Hat SSO.

Viewing the Booster source code and README

To view the source code and README file of this booster, use developers.redhat.com/launch or the Fabric8 Launcher tool on a Single-node OpenShift Cluster to generate your own version of the booster. From there you can view the generated GitHub repository or download and extract the ZIP file containing the booster code.

3.6.1. Project Structure

the sources for the Greeting service, which is the one which we are going to to secure

a template file (service.sso.yaml) to stand up the SSO server

the Keycloak adapter configuration to secure the service

3.6.2. Standing up Red Hat SSO

The service.sso.yaml file contains all OpenShift configuration items to stand up a pre-configured Red Hat SSO server. The SSO server configuration has been simplified for the sake of this exercise and does provide an out-of-the-box configuration, with pre-configured users and security settings. The service.sso.yaml file also contains very long lines, and some text editors, such as gedit, may have issues reading this file.

Warning

It is not recommended to use this SSO configuration in production. Specifically, the simplifications made to the booster security configuration impact the ability to use it in a production environment.

Table 3.5. SSO Booster Simplifications

Change

Reason

Recommendation

The default configuration includes both public and private keys in the yaml configuration files.

We did this because the end user can deploy Red Hat SSO module and have it in a usable state without needing to know the internals or how to configure Red Hat SSO.

In production, do not store private keys under source control. They should be added by the server administrator.

The configured clients accept any callback url.

To avoid having a custom configuration per runtime we avoid the verification of the callback as mandated by the OAuth2 specification.

An application-specific callback URL should be provided with a valid domain name.

Clients do not require SSL/TLS and the secured applications are not exposed over HTTPS.

The boosters are simplified by not requiring certificates generated for each runtime.

In production a secure application should use HTTPS rather than plain HTTP.

The token timeout has been increased to 10 minutes from the default of 1 minute.

Provides a better user experience when working with the command line examples

From a security perspective, the window an attacker would have to guess the access token is extended. It is recommended to keep this window short as it makes it much harder for a potential attacker to guess the current token.

3.6.3. Red Hat SSO Realm Model

The master realm is used to secure this booster. There are two pre-configured application client definitions that provide a model for command line clients and the secured REST endpoint.

There are also two pre-configured users in the Red Hat SSO master realm that can be used to validate various authentication and authorization outcomes: admin and alice.

3.6.3.1. Red Hat SSO Users

The realm model for the secured boosters includes two users:

admin

The admin user has a password of admin and is the realm administrator. This user has full access to the Red Hat SSO administration console, but none of the role mappings that are required to access the secured endpoints. You can use this user to illustrate the behavior of an authenticated, but unauthorized user.

alice

The alice user has a password of password and is the canonical application user. This user will demonstrate successful authenticated and authorized access to the secured endpoints. An example representation of the role mappings is provided in this decoded JWT bearer token:

The roles object provides the roles that have been granted to the user at the global realm level. In this case alice has been granted the booster-admin role. We will see that the secured endpoint will look to the realm level for authorized roles.

The preferred_username field provides the username that was used to generate the access token.

3.6.3.2. The Application Clients

The OAuth 2.0 specification allows you to define a role for application clients that access secured resources on behalf of resource owners. The master realm has the following application clients defined:

demoapp

This is a confidential type client with a client secret that is used to obtain an access token that contains grants for the alice user which enable alice to access the WildFly Swarm, Eclipse Vert.x, Node.js and Spring Boot based REST booster deployments.

secured-booster-endpoint

The secured-booster-endpoint is a bearer-only type of client that requires a booster-admin role for accessing the associated resources, specifically the Greeting service.

3.6.4. SSO Adapter Configuration

The SSO adapter is the client side, or client to the SSO server, component that enforces security on the web resources. In this specific case, it is the Greeting service.

3.6.5. Deploying the Secured booster to Single-node OpenShift Cluster

3.6.5.1. Getting the Fabric8 Launcher Tool URL and Credentials

You need the Fabric8 Launcher tool URL and user credentials to create and deploy boosters on Single-node OpenShift Cluster. This information is provided when the Single-node OpenShift Cluster is started.

Follow the on-screen instructions to create your booster in Node.js. When asked about which deployment type, select I will build and run locally.

Follow on-screen instructions.

When done, click the Download as ZIP file button and store the file on your hard drive.

3.6.5.3. Authenticating the oc CLI Client

To work with boosters on Single-node OpenShift Cluster using the oc command-line client, you need to authenticate the client using the token provided by the Single-node OpenShift Cluster web interface.

These commands install any missing module dependencies, then using the Nodeshift module, deploy the booster on OpenShift.

3.6.6. Deploying the Secured Booster to OpenShift Container Platform

In addition to the Single-node OpenShift Cluster, you can create and deploy the booster on OpenShift Container Platform with only minor differences. The most important difference is that you need to create the booster application on Single-node OpenShift Cluster before you can deploy it with OpenShift Container Platform.

These commands install any missing module dependencies, then using the Nodeshift module, deploy the booster on OpenShift.

3.6.7. Authenticating to the Secured Booster API Endpoint

The Secured booster provides a default HTTP endpoint that accepts GET requests if the caller is authenticated and authorized. The client first authenticates against the Red Hat SSO server and then performs a GET request against the Secured booster using the access token returned by the authentication step.

3.6.7.1. Getting the Secured Booster API Endpoint

When using a client to interact with the booster, you must specify the Secured booster endpoint, which is the PROJECT_ID service.

Prerequisites

The Secured booster deployed and running.

The oc client authenticated.

Procedure

In a terminal application, execute the oc get routes command.

A sample output is shown in the following table:

Example 3.1. List of Secured endpoints

Name

Host/Port

Path

Services

Port

Termination

secure-sso

secure-sso-myproject.LOCAL_OPENSHIFT_HOSTNAME

secure-sso

<all>

passthrough

PROJECT_ID

PROJECT_ID-myproject.LOCAL_OPENSHIFT_HOSTNAME

PROJECT_ID

<all>

sso

sso-myproject.LOCAL_OPENSHIFT_HOSTNAME

sso

<all>

In the above example, the booster endpoint would be http://PROJECT_ID-myproject.LOCAL_OPENSHIFT_HOSTNAME. PROJECT_ID is based on the name you entered when generating your booster using developers.redhat.com/launch or the Fabric8 Launcher tool.

3.6.7.2. Authenticating HTTP requests using the Command Line

Request a token by sending a HTTP POST request to the Red Hat SSO server. In the following example, the jq CLI tool is used to extract the token value from the JSON response.

The attributes, such as username, password, and client_secret are usually kept secret, but the above command uses the default provided credentials with this booster for demonstration purpose.

If you do not want to use jq to extract the token, you can run just the curl command and manually extract the access token.

Note

The -sk option tells curl to ignore failures resulting from self-signed certificates. Do not use this option in a production environment. On macOS, you must have curl version 7.56.1 or greater installed. It must also be built with OpenSSL.

Invoke the Secured service. Attach the access (bearer) token to the HTTP headers:

Make sure the web form has been updated after you made the selection, so it displays the correct RSASHA256(…​) information in the Signature section. If it has not, try switching to HS256 and then back to RS256.

Paste the following content in the topmost text box into the VERIFY SIGNATURE section:

3.7. Cache Mission - Node.js Booster

Limitation: Run this booster on a Single-node OpenShift Cluster. You can also use a manual workflow to deploy this booster to OpenShift Online Pro and OpenShift Container Platform. This booster is not currently available on OpenShift Online Starter.

The Cache mission demonstrates how to use a cache to increase the response time of applications.

This mission shows you how to:

Deploy a cache to OpenShift.

Use a cache within an application.

3.7.1. About Caching

Caching allows you to store information and access it for a given period of time. An advantage of caching is that a cache can provide access to information faster or more reliably than repeatedly calling the original service. A disadvantage of caching is that the cached information is not up to date, but that can be mitigated by setting an expiration or TTL (time to live) on each value stored in the cache.

For example, assume you have two applications: service1 and service2. Service1 depends on a value from service2. If that value from service2 infrequently changes, service1 could cache the value from service2 for a period of time. If it takes service1 500ms to retrieve the value directly from service2, but 100ms to retrieve the cached value, service1 would save 400ms by using the cached value for each cached call. Using cached values can also reduce the number of times service2 is called. If service1 would make uncached calls to service2 5 times per second, over 10 seconds, that would be 50 calls. If service1 started using a cached value with a TTL of 1 second instead, that would be reduced to 10 calls over 10 seconds.

How the Cache Mission Works

The cache, cute name, and greeting services are deployed and exposed.

User accesses the web frontend of the greeting service.

User invokes the greeting HTTP API using a button on the web frontend.

The greeting service depends on a value from the cute name service.

The greeting service first checks if that value is stored in the cache service. If it is, then the cached value is returned.

If the value is not cached, the greeting service calls the cute name service, returns the value, and stores the value in the cache service with a TTL of 5 seconds.

The web front end displays the response from the greeting services as well as the total time of the operation.

User invokes the service multiple times to see the difference between cached and uncached operations.

Cached operations are significantly faster than uncached operations.

User can force the cache to be cleared before the TTL expires.

Viewing the Booster source code and README

To view the source code and README file of this booster, use developers.redhat.com/launch or the Fabric8 Launcher tool on a Single-node OpenShift Cluster to generate your own version of the booster. From there you can view the generated GitHub repository or download and extract the ZIP file containing the booster code.

The route information of a pod gives you the base URL which you use to access it. In the example above, you would use http://MY_APP_NAME-greeting-MY_PROJECT_NAME.OPENSHIFT_HOSTNAME as the base URL to access the greeting service.

3.7.3. Deploying the Cache Booster to Single-node OpenShift Cluster

Use one of the following options to execute the Cache booster locally on Single-node OpenShift Cluster:

Although each method uses the same oc commands to deploy your application, using Fabric8 Launcher provides an automated booster deployment workflow that executes the oc commands for you.

3.7.3.1. Getting the Fabric8 Launcher Tool URL and Credentials

You need the Fabric8 Launcher tool URL and user credentials to create and deploy boosters on Single-node OpenShift Cluster. This information is provided when the Single-node OpenShift Cluster is started.

3.7.3.3. Authenticating the oc CLI Client

To work with boosters on Single-node OpenShift Cluster using the oc command-line client, you need to authenticate the client using the token provided by the Single-node OpenShift Cluster web interface.

The route information of a pod gives you the base URL which you use to access it. In the example above, you would use http://MY_APP_NAME-greeting-MY_PROJECT_NAME.OPENSHIFT_HOSTNAME as the base URL to access the greeting service.

3.7.4. Deploying the Cache Booster to OpenShift Container Platform

The process of creating and deploying boosters to OpenShift Container Platform is similar to OpenShift Online:

If you have a different entry point for your application, you need to change the command to specify that entry point:

$ node inspect path/to/entrypoint

For example, when using the express generator to create your application, the entry point is set to ./bin/www by default. Some of the boosters, such as the REST API Level 0 booster, use ./bin/www as an entry point.

If you have a different entry point for your application, you need to change the command to specify that entry point:

$ node --inspect path/to/entrypoint

For example, when using the express generator to create your application, the entry point is set to ./bin/www by default. Some of the boosters, such as the REST API Level 0 booster, use ./bin/www as an entry point.

Attach the V8 inspector and perform debugging commands.

For example, if using Google Chrome:

Navigate to chrome://inspect.

Select your application from below Remote Target.

You can now see the source of your application and can perform debugging actions.

4.1.3. Starting Your Application on OpenShift in Debugging Mode

To debug your Node.js-based application on OpenShift remotely, you must set the NODE_ENV environment variable inside the container to development and configure port forwarding so that you can connect to your application from a remote debugger.

Prerequisites

Your application running on OpenShift.

The oc binary installed on your machine.

The ability to execute the oc port-forward command in your target OpenShift environment.

Procedure

Using the oc command, list the available deployment configurations:

$ oc get dc

Set the NODE_ENV environment variable in the deployment configuration of your application to development to enable debugging. For example:

$ oc set env dc/MY_APP_NAME NODE_ENV=development

Redeploy the application if it is not set to redeploy automatically on configuration change. For example:

$ oc rollout latest dc/MY_APP_NAME

Configure port forwarding from your local machine to the application pod:

List the currently running pods and find one containing your application:

Here, $LOCAL_PORT_NUMBER is an unused port number of your choice on your local machine. Remember this number for the remote debugger configuration.

Attach the V8 inspector and perform debugging commands.

For example, if using Google Chrome:

Navigate to chrome://inspect.

Click Configure.

Add 127.0.0.1:$LOCAL_PORT_NUMBER.

Click Done.

Select your application from below Remote Target.

You can now see the source of your application and can perform debugging actions.

When you are done debugging, unset the NODE_ENV environment variable in your application pod. For example:

$ oc set env dc/MY_APP_NAME NODE_ENV-

4.2. Debug Logging

Debug logging is a way to add granular logging to an application that can be explicitly enabled only when performing debugging. This allows you to keep the logging capability in your application and only enable it when needed.

Depending on your application, this module may already be included. For example, when using the express generator to create your application, the debug module is already added to package.json. Some of the boosters, such as the REST API Level 0 booster, already have the debug module in the package.json.

Install the application dependencies.

$ npm install

4.2.2. Accessing Debug Logs on Localhost

Use the DEBUG environment variable when starting your application to enable debug logging.

Prerequisites

An application with debug logging.

Procedure

Set the DEBUG environment variable when starting your application to enable debug logging.

$ DEBUG=mybooster npm start

The debug module can use wildcards to filter debugging messages. This is set using the DEBUG environment variable.

Test your application to invoke debug logging.

For example, when debug logging in the REST API Level 0 booster is set to log the name variable in the /api/greeting method:

$ curl http://localhost:8080/api/greeting?name=Sarah

View your application logs to see your debug messages.

mybooster name: Sarah +3m

4.2.3. Accessing Node.js Debug Logs on OpenShift

Use the the DEBUG environment variable in your application pod in OpenShift to enable debug logging.

Prerequisites

An application with debug logging.

The oc CLI client installed.

Procedure

Use the oc CLI client to log into your OpenShift instance.

$ oc login ...

Deploy your application to OpenShift.

$ npm run openshift

This runs the openshift npm script, which wraps direct calls to nodeshift.

Find the name of your pod and follow the logs to watch it start.

$ oc get pods
....
$ oc logs -f pod/POD_NAME

Important

After your pod has started, leave this command running and execute the remaining steps in a new terminal window. This allows you to follow the logs and see new entries made to it.

Test your application.

For example, if you had debug logging in the REST API Level 0 booster to log the name variable in the /api/greeting method:

$ oc get routes
...
$ curl $APPLICATION_ROUTE/api/greeting?name=Sarah

Return to your pod logs and notice there are no debug logging messages in the logs.

Set the DEBUG environment variable to enable debug logging.

$ oc get dc
...
$ oc set env dc DC_NAME DEBUG=mybooster

Return to your pod logs to watch the update roll out.

After the update has rolled out, your pod will stop and you will no longer be following the logs.

Find the name of your new pod and follow the logs.

$ oc get pods
....
$ oc logs -f pod/POD_NAME

Important

After your pod has started, leave this command running and execute the remaining steps in a different terminal window. This allows you to follow the logs and see new entries made to it. Specifically, the logs will show your debug messages.

Test the application to invoke debug logging.

$ oc get routes
...
$ curl $APPLICATION_ROUTE/api/greeting?name=Sarah

Return to your pod logs to see the debug messages.

...
mybooster name: Sarah +3m

To disable debug logging, remove the DEBUG environment variable from the pod:

The files section tells nodeshift what files and directories to include when deploying to OpenShift. nodeshift uses the node-tar module to create a tar file based on the files and directories you list in the files section. This tar file is used when nodeshift deploys your application to OpenShift. If the files section is not specified, nodeshift will send the entire current directory, excluding:

node_modules/

.git/

tmp/

It is recommended that you include a files section in package.json to avoid including unnecessary files when deploying to OpenShift.

Optionally, you can create a .nodeshift directory at the root of your project to include deployment yaml files. These files will create items such as routes when deploying your application to OpenShift using nodeshift. For example, to add a route during deployment, you could create a .nodeshift/route.yaml with the following:

Ensure all the ports used by your application are correctly exposed when configuring your routes.

Appendix A. About Nodeshift

Nodeshift is a module for running OpenShift deployments with Node.js projects.

Important

Nodeshift assumes you have the oc CLI client installed, and you are logged into your OpenShift cluster. Nodeshift also uses the current project the oc CLI client is using.

Nodeshift uses resource files in the .nodeshift folder located at the root of the project to handle creating OpenShift Routes, Services and DeploymentConfigs. More details on Nodeshift are available on the Nodeshift project page.

Appendix B. Updating the Deployment Configuration of a Booster

The deployment configuration for a booster contains information related to deploying and running the booster in OpenShift, such as route information or readiness probe location. The deployment configuration of a booster is stored in a set of YAML files. For boosters that use the Fabric8 Maven Plugin, the YAML files are located in the src/main/fabric8/ directory. For boosters using Nodeshift, the YAML files are located in the .nodeshift directory.

Important

The deployment configuration files used by the Fabric8 Maven Plugin and Nodeshift do not have to be full OpenShift resource definitions. Both Fabric8 Maven Plugin and Nodeshift can take the provided files and infer some missing information to create a full OpenShift resource definition. The resource definitions generated by the Fabric8 Maven Plugin are available in the target/classes/META-INF/fabric8/ directory. The resource definitions generated by Nodeshift are available in the tmp/nodeshift/resource/ directory.

If you updated the configuration of your application directly using the web-based console or the oc CLI client, export and add these changes to your YAML file. Use the oc export all command to show the configuration of your deployed application.

A npm script for deploying this application to Single-node OpenShift Cluster. Run with npm run openshift. The strictSSL option allows us to deploy to Single-node OpenShift Cluster instances with self-signed certificates.

Appendix E. Application Development Resources

Appendix F. The Source-to-Image (S2I) Build Process

Source-to-Image (S2I) is a build tool for generating reproducible Docker-formatted container images from online SCM repositories with application sources. With S2I builds, you can easily deliver the latest version of your application into production with shorter build times, decreased resource and network usage, improved security, and a number of other advantages. OpenShift supports multiple build strategies and input sources.

You must provide three elements to the S2I process to assemble the final container image:

The application sources hosted in an online SCM repository, such as GitHub.

The S2I Builder image, which serves as the foundation for the assembled image and provides the ecosystem in which your application is running.

Optionally, you can also provide environment variables and parameters that are used by S2I scripts.

The process injects your application source and dependencies into the Builder image according to instructions specified in the S2I script, and generates a Docker-formatted container image that runs the assembled application. For more information, check the S2I build requirements, build options and how builds work sections of the OpenShift Container Platform documentation.

Appendix G. Proficiency Levels

Each mission available on Fabric8 Launcher teaches you about certain topics, but requires certain minimum knowledge, which varies by mission. For clarity, the minimum requirements and concepts are organized in several proficiency levels. In addition to the levels described in this chapter, there can be additional requirements with each mission, specific to its aim or the technologies it uses.

Foundational

The missions rated at Foundational proficiency generally require no prior knowledge of the subject matter; they provide general awareness and demonstration of key elements, concepts, and terminology. There are no special requirements except those directly mentioned in the description of the mission.

Advanced

When using Advanced missions, the assumption is that you are familiar with the common concepts and terminology of the subject area of the mission in addition to Kubernetes and OpenShift. You must also be able to perform basic tasks on your own, for example configure services and applications, or administer networks. If a service is needed by the mission, but configuring it is not in the scope of the mission, the assumption is that you have the knowledge to to properly configure it, and only the resulting state of the service is described in the documentation.

Expert

Expert missions require the highest level of knowledge of the subject matter. You are expected to perform many tasks based on feature-based documentation and manuals, and the documentation is aimed at most complex scenarios.

Appendix H. Glossary

H.1. Product and Project Names

developers.redhat.com/launch

developers.redhat.com/launch is a standalone getting started experience offered by Red Hat for jumpstarting cloud-native application development on OpenShift. It provides a hassle-free way of creating functional example applications, called missions, as well as an easy way to build and deploy those missions to OpenShift.

Legal Notice

The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.

Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.

Red Hat, Red Hat Enterprise Linux, the Shadowman logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.

Linux® is the registered trademark of Linus Torvalds in the United States and other countries.

Java® is a registered trademark of Oracle and/or its affiliates.

XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.

MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.

Node.js® is an official trademark of Joyent. Red Hat Software Collections is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.

The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.