0
votes

I want to connect to oracle database hosted in RDS inside aws lambda nodejs runtime . after research i found out that i need to download node-oracledb package and create a layer for node module and binary lib files. so i created folder structure as shown below, and zip folder and uploaded to aws layer and attached layer to lambda, however i get "errorMessage": "Cannot find module 'oracledb' any clue Why AWS node cannot find module?, thank you

Lambda-Layer-1(version 1)
|
|__lib
|     |__libaio.so.1
|     |__libclntsh.so.12.1
|     |__libclntschcore.so.12.1
|     |__libipc1.so
|     |__libmql1.so
|     |__libnnz12.so
|     |__libociicus.so
|     |__libons.so
|
|__nodejs
      |
      |__node_modules
               |
               |__oracledb

Error from lambda:

  "errorMessage": "Cannot find module 'oracledb'",
  "errorType": "Error",
  "stackTrace": [
    "Module.require (module.js:596:17)",
    "require (internal/module.js:11:18)",
    "Object.<anonymous> (/var/task/src/services/oracleDb.service.js:10:18)",
    "Module._compile (module.js:652:30)",
    "Object.Module._extensions..js (module.js:663:10)",
    "Module.load (module.js:565:32)",



AWS runtime: 
Nodejs:8.10 
node-oracledb:"3.1.2"

code:

 const oracledb = require("oracledb");
  let connection;
    static async init() {
        try {
            if (!connection) {
                const connectionAtrribute = {
                    connectionString: 'uat-*******',
                    password: '*******',
                    user: '*******'
                };
                connection = await oracledb.getConnection(connectionAtrribute);
            }
        }
        catch (error) {
            console.log('ERROR', JSON.stringify(error));
        }
    }
1
Refer to this link. It helped me resolve the issue for me. medium.com/@jimmdd/… - Nagarajan S R
rehanvdm.com/blog/an-unexpected-journey-with-lambda-oracledb is also useful. In short, download the (linux zipped) light client from oracle.com/database/technologies/instant-client/… . Unzip to lib dir in your project directory. Add libaio.so or libaio.so.1 (downloaded from linux repo) to lib dir. Remove libcIntsh.so.x.1 and libocci.so.x.1 files for versions you don't need (and .jar files can go too I think). With these files in place, regular oracledb module works in a lambda. Also, for space, remember aws-sdk is included in lambda env. - phhu

1 Answers

1
votes

There is an another library “oracledb_for_lambda” to connect oracle DB from lambda

npm i oracledb-for-lambda

Now, In the Project folder, Create a folder named “nodejs” and You need to move the “node_modules” folder into this “nodejs” folder. Then, Copy the “lib” folder inside “/node_modules/oracledb-for-lambda” and paste it outside in the main project directory.

Finally, you will get a folder structure like the below image.

Final folder sctructure

That’s it, Zip the files inside the folder and Upload the Zip to S3

And you can connect using below code

'use strict';
var os = require('os');
var fs = require('fs');
var oracledb = require('oracledb-for-lambda');
exports.handler = async (event, context) => {
    let str_host = os.hostname() + ' localhost\n';
    fs.writeFileSync(process.env.HOSTALIASES, str_host, function(err) {
        if (err) throw err;
    });
    var connAttr = {
        user: process.env.USERNAME,
        password: process.env.PASSWORD,
        connectString: process.env.CONNECTION_STRING
    };

    const promise = new Promise(function(resolve, reject) {
        oracledb.getConnection(connAttr, function(err, connection) {
            if (err) {
                reject({
                    status: "ERROR"
                });
            }
            resolve({
                status: "SUCCESS"
            });
        });
    });
    return promise;
}