![]() |
Protect your Code Engine functions |
Henrik's thoughts on life in IT, data and information management, cloud computing, cognitive computing, covering IBM Db2, IBM Cloud, Watson, Amazon Web Services, Microsoft Azure and more.
Showing posts with label nodejs. Show all posts
Showing posts with label nodejs. Show all posts
Friday, March 15, 2024
Authentication for your IBM Cloud Code Engine functions
Thursday, January 25, 2024
Tutorial on cloud end-to-end security - an overview
![]() |
Cloud solution architecture |
Recently, my team updated our tutorial on applying end-to-end security to a cloud application. The tutorial features a typical app with an attached NoSQL database and object storage. Moreover, it leverages other services for increased security and to provide observability. Even better, all components can be automatically deployed, including a Tekton-based delivery pipeline. In this blog post, I am going to provide an overview and discuss some implementation details.
Thursday, November 30, 2023
Thoughts on how to move from Cloud Functions to Code Engine
![]() |
Moving code and containers |
Tuesday, November 28, 2023
Tips and tricks for using IBM Cloud Code Engine functions
![]() |
Utilize Code Engine runtime information |
Monday, October 11, 2021
Db2 on Cloud credentials and how to connect from your app
Over the past 12 months, Db2 on Cloud migrated instances to a new deployment model. It seems to be based on the IBM Cloud Databases model and resulted in a different structure for the service credentials. Previously, Db2 on Cloud instances were accessible on the typical ports 50000 and 50001. The JSON-based credentials object included ready-to-use connection URIs. Now, after the change, the VCAP object has more parts, but is missing the easy-to-use URIs. In the following, I am showing you how to consume the new credential structure in your app and to successfully connect to Db2 on Cloud.
Friday, May 28, 2021
IBM Cloud: Send out alert emails using SMTP
Last year, I blogged about how to use Slack or email notifications for security IBM Cloud security issues. Now I added another code sample, showing how to send out notification emails using any SMTP server. The code is written in Python and Node.js and deployed as IBM Cloud Functions-based webhook. The core part in charge of connecting to an SMTP email server and sending the email is isolated as dedicated action. Thus, it is possible to use it on its own, e.g., to send out emails unrelated to the IBM Cloud Security & Compliance Center.
Monday, March 1, 2021
JWT token authentication in Db2 runtimes like Python or Node.js
![]() |
Python script connecting to Db2 with JWT |
Labels:
DB2,
developer,
IT,
json,
knowledge center,
nodejs,
Python,
security,
version 11.5
Monday, March 2, 2020
Extend IBM Cloud Security Advisor with your own security metrics
![]() |
Custom findings in Security Advisor |
Thursday, October 4, 2018
Db2 Node.js and Python drivers and ORM
I am back from the Db2 Aktuell conference with my talk about Db2 app development and IBM Cloud. One of the many questions I received since then is about where to find the Db2 drivers for Node.js and Python. What type of ORM (Object-Relational Mapping) libraries are supported? Let me briefly answer that here and provide some links.
![]() |
Db2 drivers turning bits into information |
Db2 and Node.js or Python
Db2 supports many programming languages for database application development, a good overview is in the Db2 Knowledge Center. Node.js and Python use the open source drivers for IBM Database Servers that are available on GitHub.- Last year, I blogged about the Python drivers and that IBM actually provides four different ones. The reason is that there are different Python APIs and frameworks, including SQLAlchemy and Django. Both of them feature their own ORM layer.
- For Node.js, a popular framework is Sails with its Waterline ORM. Db2 is a supported database. A popular Node.js API framework is Loopback by the IBM company Strongloop. The Db2 connector can be found in this GitHub repository. Sequelize is a promise-based ORM, the Db2 driver team has started adding support.
Thursday, February 15, 2018
Easy Database Setup the Serverless Way
![]() |
Serverless Slackbot with Db2 |
Tuesday, January 17, 2017
Bluemix: Simplified Deployment of Complex Cloud Foundry Apps
![]() |
Two apps from single manifest |
Cloud Foundry allows multiple apps to be described with a single manifest file. That is, properties for several apps (or services) can be put together. For each app its name and the location where its code is found need to be specified. They are shown in blue in my sample manifest file. Each app can be deployed to a specific machine, identified by the host and domain name. For the example I chose a different approach. It is the relatively new "routes" property. It allows to combine those properties and even add paths information. The routing is highlighted in yellow below. All I needed to do is to execute a simple "cf push" command and the entire application with its multiple pieces got deployed.
Here is the sample manifest.yml file:
# This manifest deploys two applications.
#
# Both use the same host and domain name as defined
# by their respective route(s) property. The first app
# uses the root path, the second the "sub" and
# "lower" paths.
applications:
# The Python app starts here
- name: yourname-myapp
memory: 256M
command: python myapp.py
routes:
- route: yourname-myapp.mybluemix.net
path: ./top/
#
# The Node.js app starts here
#
- name: yourname-myapp-node
routes:
- route: yourname-myapp.mybluemix.net/lower
- route: yourname-myapp.mybluemix.net/sub
path: ./lower/
If you wonder how the entire project looks like, visit https://github.com/data-henrik/Bluemix-ContextPathRouting for the source code and a more detailed description. I put this repository together to showcase Context Path Routing on IBM Bluemix which I will discuss in an upcoming blog post.
Labels:
administration,
applications,
bluemix,
cloud,
cloudfoundry,
ibmcloud,
IT,
nodejs,
Python
Wednesday, August 12, 2015
Wired or weird Tweets? Doesn't matter to Bluemix, DB2, and Node-RED...
![]() |
Robot with a personality? |
created a Twitter service. It automatically can respond to tweets and can also store the incoming messages in a DB2 table. In my example it is just a, more or less, silly service right now, but it could be expanded to react to and log Twitter-based customer feedback, provide some basic interim reaction or acknowledgement. Let me show you how easy it is to get started...
To build the Twitter service you need the "Node-RED Starter" boilerplate from the Bluemix catalog as well as the "SQL Database" service. Create the Node-RED boilerplate first, then add the database service and directly bind it to the new application. Once everything has been provisioned, it is time for wiring up the Twitter service in the flow editor. The following picture gives an overview of the two flows when completed. I made the flows available in the Node-RED library.
Tuesday, April 21, 2015
My 10 Minute DB2 App on Bluemix
I needed some fun at the end of the workday today. Why not enhance my own skills, do some "coding", and try out Node-RED on Bluemix again (I performed a "phoney" test in October already). This time, I wanted to see whether a database like DB2 or dashDB is supported as backend.
To get started I logged into my free trial account on http://bluemix.net. I selected the "Node-RED Starter" from the catalog and created the app skeleton. After the app was staged (the resources allocated, files copied, and the skeleton app started), I could begin wiring up my application logic. My first look on the wiring board went to the list of supported storage nodes. What was new since my last test is support for dashDB and "sqldb" (DB2) as input and output nodes. That is, it is possible to store data in those two database systems (output) and bring data into the app by querying a database (input).
To use DB2 in Node-RED, you need to create a sqldb service in Bluemix first. This meant going back to the catalog, skipping to the Data Management section, selecting the sqldb service, and adding it to my application (see picture below). Thereafter, my application needed to be restaged (restarted), so that it could pick up the properties of the sqldb service.
Node-RED Starter |
![]() |
Node-RED storage nodes |
To use DB2 in Node-RED, you need to create a sqldb service in Bluemix first. This meant going back to the catalog, skipping to the Data Management section, selecting the sqldb service, and adding it to my application (see picture below). Thereafter, my application needed to be restaged (restarted), so that it could pick up the properties of the sqldb service.
Monday, October 13, 2014
Node-RED: Simple "phoney" JSON entries in Cloudant
![]() |
Node-RED Starter on IBM Bluemix |
The Node-RED boilerplate automatically creates a Node.js runtime environment on Bluemix and installs the Node-RED tool into it. In addition, a Cloudant JSON database is created. Once everything is deployed I opened the Node-RED tool in a Web browser. It offers a basic set of different input and output methods, processing nodes, and the ability to connect them in a flow graph. One of the input nodes is a listener for http requests. They help to react to Web service requests. I placed such http input node on the work sheet and labeled it "phone" (see screenshot).
![]() |
Node-RED tool on Bluemix |
How did I obtain information about callers and the numbers they called?
What I needed now was the data processing flow of the Web services request. On Friday I already tweeted the entire flow:
Easy. Cool. #NodeRED used to store #caller info coming from #sipgate API into #Cloudant on #Bluemix pic.twitter.com/MFkqFAdp5D
— Henrik Loeser (@data_henrik) October 10, 2014
On the left we see "phone" node as http input. Connected to it is the "ok" node which sends an http response back, telling the phone company's Web services that we received the information. The other connected node is a "json" processor which translates the payload (who called which number) into a meaningful JSON object. That object is then moved on to the "calls" node, a Cloudant output node. All we needed was to select the Cloudant service on Bluemix and to configure the database name.
![]() |
Cloudant Output Node, Node-RED on Bluemix |
![]() |
"Phoney" record in Cloudant |
Tuesday, August 19, 2014
Sample IBM Bluemix Application: Extended IP logging with node.js and DB2
As I wrote in my last blog article I have been playing around with node.js and DB2 on IBM Bluemix. Now I am done with my first server-side JavaScript application which I named "db2visitors".
When accessing the main page (index page), the app logs the visitor's IP address. Then a free geo location service is called to obtain extended information, such as country, region and city information of the visitor. This is how Google Analytics and other services know more about a website user, with the exception that many have their own database. That extended IP record is then inserted into a DB2 table and the information displayed on a "DB2 got you" welcome page. To report back about from where the visitors to my demo application came, I created a second page that returns the aggregated country and region information for all visitors so far. How does it work? Let's look into the details.
First of all, I uploaded my sample code to my Github "db2visitors" repository, so that you can get an impression of the directory structure and files. It is pretty simple and you will notice that I am new to node.js. The application consists of a main file "app.js" that sets up the general infrastructure and defines the handling of so-called routes. A route basically determines what needs to be executed for a specific request to the Web server. When a user visits the main or index page, the node/Express framework would serve the request by calling my new function getIP(). That function is implemented in a file "db2access.js" in the "routes" directory. The current version as of now is shown below.
The function getIP obtains the visitor's IP address. Then it uses that information to provide it to an external IP address geo location service. That service returns a JSON structure with country, region, city and other data it has on file for the IP address or the related address block. Sometimes it nails it, (fortunately) in many cases only the country is correct. Anyway, it is a free service and you get an idea of Google and other advertising companies can do with your data. Once that extended record is available, we call into the function insertIP(). There, a DB2 connection is opened, a SQL statement prepared and executed to insert the IP address data into a relational table IP.VISITORS (schema shown on the right, it was created using the Bluemix SQLDB Control Center). Some form of basic IP logging. Last in the function getIP, a function render() is called with the parameter "index". It tells the rendering engine to process the HTML templates and page segments for the view "index". All the view-related files are in exactly that directory (see my Github repository).
The last function in the file db2access.js is listCountries(). It demonstrates some basic reporting, i.e., how to issue a DB2 query from node.js using the ibm_db API, fetch the result and pass it to a template page. That page is displayed when going to the path "/visits" (as defined in app.js). You can test it here. The query uses a simple GROUP BY to aggregate the country and region data.
That is all for today. Let me know if you have questions (comment, tweet or email) and read my other database on Bluemix-related blog entries.
![]() |
Screenshot of db2visitors index page |
First of all, I uploaded my sample code to my Github "db2visitors" repository, so that you can get an impression of the directory structure and files. It is pretty simple and you will notice that I am new to node.js. The application consists of a main file "app.js" that sets up the general infrastructure and defines the handling of so-called routes. A route basically determines what needs to be executed for a specific request to the Web server. When a user visits the main or index page, the node/Express framework would serve the request by calling my new function getIP(). That function is implemented in a file "db2access.js" in the "routes" directory. The current version as of now is shown below.
![]() |
SQLDB Control Center with Table DDL |
The last function in the file db2access.js is listCountries(). It demonstrates some basic reporting, i.e., how to issue a DB2 query from node.js using the ibm_db API, fetch the result and pass it to a template page. That page is displayed when going to the path "/visits" (as defined in app.js). You can test it here. The query uses a simple GROUP BY to aggregate the country and region data.
That is all for today. Let me know if you have questions (comment, tweet or email) and read my other database on Bluemix-related blog entries.
1: // Written by Henrik Loeser
2: // Some functions to retrieve extended information for a IP address,
3: // to insert that extended IP record into a DB2 table, and to
4: // report some basic statistics as part of a second HTML page.
5:
6:
7:
8: // Insert the JSON record with the IP information as SQL record into DB2.
9: exports.insertIP = function(ibmdb,connString,ipinfo) {
10: console.log("insertIP called",ipinfo);
11: ibmdb.open(connString, function(err, conn) {
12: if (err ) {
13: res.send("error occurred " + err.message);
14: }
15: else {
16: // prepare the SQL statement
17: conn.prepare("INSERT INTO IP.VISITORS(vtime,ip,country_code,country,region_code,region,city,zip,latitude,longitude,metro,area) VALUES (current timestamp,?,?,?,?,?,?,?,?,?,?,?)", function(err, stmt) {
18: if (err) {
19: //could not prepare for some reason
20: console.log(err);
21: return conn.closeSync();
22: }
23:
24: //Bind and Execute the statment asynchronously
25: stmt.execute([ipinfo["ip"],ipinfo["country_code"],ipinfo["country_name"],ipinfo["region_code"],ipinfo["region_name"],ipinfo["city"],ipinfo["zipcode"], ipinfo["latitude"], ipinfo["longitude"],ipinfo["metro_code"],ipinfo["area_code"]], function (err, result) {
26: console.log(err);
27: // Close the connection to the database
28: conn.close(function(){
29: console.log("Connection Closed");
30: });
31: });
32: });
33: }
34: })};
35:
36:
37: // Get the caller's IP address from runtime environment and call
38: // geo location service to obtain extended data
39: exports.getIP=function(request,ibmdb,connString) {
40: return function(req, res) {
41: var ip = req.headers['x-client-ip'] || req.connection.remoteAddress;
42: var ipurl='/http://freegeoip.net/json/' + ip;
43: console.log("yes, called");
44: // fetch ip info
45: request.get( {
46: url: ipurl,
47: json : true},
48: function(error, response, body) {
49: var ipinfo;
50: if (!error) {
51: ipinfo=body;
52: // insert IP info into DB2
53: exports.insertIP(ibmdb,connString,ipinfo);
54: // finish by rendering the HTML page
55: res.render('index',{ ipinfo : ipinfo});
56: }
57: });
58: }
59: };
60:
61:
62:
63: // Very simple country/region-based reporting done using GROUP BY.
64: exports.listCountries = function(ibmdb,connString) {
65: return function(req, res) {
66:
67: ibmdb.open(connString, function(err, conn) {
68: if (err ) {
69: res.send("error occurred " + err.message);
70: }
71: else {
72: conn.query("SELECT country, region, count(region) as rcount FROM ip.visitors group by country,region order by 3 desc", function(err, tables, moreResultSets) {
73:
74:
75: if ( !err ) {
76: res.render('tablelist', {
77: "tablelist" : tables
78:
79: });
80:
81:
82: } else {
83: res.send("error occurred " + err.message);
84: }
85:
86: /*
87: Close the connection to the database
88: param 1: The callback function to execute on completion of close function.
89: */
90: conn.close(function(){
91: console.log("Connection Closed");
92: });
93: });
94: }
95: } );
96:
97: }
98: }
Monday, August 18, 2014
Accessing DB2 from node.js on IBM Bluemix and locally
Some days ago I started experimenting with node.js. Other than JSON and some click functions on webpages I don't have much experience with JavaScript. The reason for this "adventure" is that node.js is offered as one of several programming languages on IBM Bluemix, IBM's platform-as-a-service (PaaS). I wanted to find out how complex or easy it would be to bring both node.js and DB2 (IBM's relational and in-memory database system) together.
When I start with some new language I typically produce errors. Thus I wanted to avoid pushing my app to Bluemix all the time, but instead wanted to test it locally first. Hence I downloaded and installed a local node.js environment, including the so-called node.js package manager "npm" first. npm allows you to install additional modules/code libraries. They are placed into the directory "node_modules". Within the program (or script), the modules are included and referenced via the "require" statement:
var express = require('express');
The above binds the "ExpressJS Web Application Framework for node". That framework is part of the node.js starter application on IBM Bluemix. With that basic application which is offered for download you can easily test whether the local installation work ok:
node app.js
The command which I executed in a regular shell launches the node.js runtime with the sample application. Based on the configuration it provides a small web application available on my laptop on port 3000. Accessing "http://127.0.0.1:3000" in my web browser shows the demo page. All ok.
To combine node.js and DB2 I require the DB2 database driver:
var ibmdb = require('ibm_db');
Just running the application again would return an error because the module has not been installed. Hence my next step in the command shell is:
npm install ibm_db
This invokes the node package manager and instructs it to download and install the IBM database client driver and related node.js API. Waiting for a minute it returned an error because it couldn't find the file "sqlcli1.h". This is an indicator that my local DB2 was missing the application development environment. Running "db2setup" again (as root), selecting "work with existing" and marking the application development package for installation solved the issue. After db2setup finished, I ran "npm install ibm_db" again and it was able to download, build and install that module.
To test my small app both locally and on Bluemix, I needed to obtain user and DB2 instance information for either the local environment or the Bluemix SQLDB service (DB2). This is done with the following code snippet (not that beauty as I just started...):
In the code I first search for the object with the Bluemix environment information. If it is not found the code assumes it is a local invocation. In that case the DB2 access information is loaded from the file "db2cred.json". It is a file I created in the application directory with a content like here:
{
"hostname": "127.0.0.1",
"host": "127.0.0.1",
"port": 50000,
"username": "hloeser",
"password": "mytopsecretpassword",
"db": "CLOUDDB"
}
The code uses the information about the hostname, port, and the user/password combination to create a connection string. That information together with the IBM Database Driver interface can be passed to a request handler in the node.js/Express runtime infrastructure (the "app.get()" call).
My small test application runs successfully both on my laptop as well as on IBM Bluemix. I plan to write more about it over the next days and to upload the code to my Github account. Bluemix-related posts can be accessed by this link.
Update: The follow-up article has been published here, showing geo IP lookup and logging into DB2.
When I start with some new language I typically produce errors. Thus I wanted to avoid pushing my app to Bluemix all the time, but instead wanted to test it locally first. Hence I downloaded and installed a local node.js environment, including the so-called node.js package manager "npm" first. npm allows you to install additional modules/code libraries. They are placed into the directory "node_modules". Within the program (or script), the modules are included and referenced via the "require" statement:
var express = require('express');
The above binds the "ExpressJS Web Application Framework for node". That framework is part of the node.js starter application on IBM Bluemix. With that basic application which is offered for download you can easily test whether the local installation work ok:
node app.js
The command which I executed in a regular shell launches the node.js runtime with the sample application. Based on the configuration it provides a small web application available on my laptop on port 3000. Accessing "http://127.0.0.1:3000" in my web browser shows the demo page. All ok.
To combine node.js and DB2 I require the DB2 database driver:
var ibmdb = require('ibm_db');
Just running the application again would return an error because the module has not been installed. Hence my next step in the command shell is:
npm install ibm_db
This invokes the node package manager and instructs it to download and install the IBM database client driver and related node.js API. Waiting for a minute it returned an error because it couldn't find the file "sqlcli1.h". This is an indicator that my local DB2 was missing the application development environment. Running "db2setup" again (as root), selecting "work with existing" and marking the application development package for installation solved the issue. After db2setup finished, I ran "npm install ibm_db" again and it was able to download, build and install that module.
To test my small app both locally and on Bluemix, I needed to obtain user and DB2 instance information for either the local environment or the Bluemix SQLDB service (DB2). This is done with the following code snippet (not that beauty as I just started...):
1: // get DB2 SQLDB service information
2: function findKey(obj,lookup) {
3: for (var i in obj) {
4: if (typeof(obj[i])==="object") {
5: if (i.toUpperCase().indexOf(lookup) > -1) {
6: // Found the key
7: return i;
8: }
9: findKey(obj[i],lookup);
10: }
11: }
12: return -1;
13: }
14: var env = null;
15: var key = -1;
16: var db2creds=null;
17: if (process.env.VCAP_SERVICES) {
18: env = JSON.parse(process.env.VCAP_SERVICES);
19: key = findKey(env,'SQLDB');
20: }
21: if (!env) {
22: console.log("We are local");
23: var file = __dirname + '/db2cred.json';
24: try {
25: db2creds = require(file);
26: } catch(err) {
27: return {};
28: }
29: // db2creds = JSON.parse(fileJSON);
30: console.log(db2creds);
31: } else {
32: var db2creds = env[key][0].credentials;
33:
34: }
35: var connString = "DRIVER={DB2};DATABASE=" + db2creds.db + ";UID=" + db2creds.username + ";PWD=" + db2creds.password + ";HOSTNAME=" + db2creds.hostname + ";port=" + db2creds.port;
36:
37: app.get('/db2', routes.db2test(ibmdb,connString));
38:
39:
In the code I first search for the object with the Bluemix environment information. If it is not found the code assumes it is a local invocation. In that case the DB2 access information is loaded from the file "db2cred.json". It is a file I created in the application directory with a content like here:
![]() |
Logo for my DB2 node.js app |
{
"hostname": "127.0.0.1",
"host": "127.0.0.1",
"port": 50000,
"username": "hloeser",
"password": "mytopsecretpassword",
"db": "CLOUDDB"
}
The code uses the information about the hostname, port, and the user/password combination to create a connection string. That information together with the IBM Database Driver interface can be passed to a request handler in the node.js/Express runtime infrastructure (the "app.get()" call).
My small test application runs successfully both on my laptop as well as on IBM Bluemix. I plan to write more about it over the next days and to upload the code to my Github account. Bluemix-related posts can be accessed by this link.
Update: The follow-up article has been published here, showing geo IP lookup and logging into DB2.
Subscribe to:
Posts (Atom)