How to set and map environment data in loopback js? - node.js

I have followed loopback documentation to setup deployment & environment specific configuration.
https://loopback.io/doc/en/lb3/Environment-specific-configuration.html
There is a place where i need to get data source connector, for that i have configured and accessing data source throughout in the application. and it is working fine.
module.exports.DataSources = app.dataSources.hmsDs.connector;
But after configure for deploying application in production as documentation says. I am getting error.
module.exports.DataSources = app.dataSources.applianceDs.connector;
^
TypeError: Cannot read property 'connector' of undefined
datasource.production.js
module.exports = {
applianceDs: {
hostname: process.env.DB_HOST,
port: process.env.DB_PORT || 27017,
database: 'applianceDB',
user: process.env.DB_USER || "",
password: process.env.DB_PASSWORD || "",
name: "applianceDs",
connector: 'mongodb',
}
}
and when i tried to access data source as follow,
var { applianceDs }= require('../datasource.production');
module.exports.DataSources = applianceDs.connector;
then getting error like this.
AssertionError [ERR_ASSERTION]: User is referencing a dataSource that does not exist: "applianceDs"
Steps that i have followed at terminal
$ export PRODUCTION=true
$ export DB_HOST="127.0.0.1"
$ export DB_USER="me"
$ export DB_PASSWORD="0000"
$ nodemon app.js
Which step I am missing ? Is there something hidden in loopback js?
Please help.
Thanks

Some advice which can help:
Configure NODE_ENV="production" env variable. I'm not sure, but loopback takes this value as the config postfix.
Try to pass env variables to run operation directly as it can be not inherited from the console (to check this point print process.env[$VARIABLE_NAME])
To pass env variables to operation:
PRODUCTION=true DB_HOST="127.0.0.1" DB_USER="me" DB_PASSWORD="0000" nodemon app.js

Related

role postgres does not exist - attempting to connect to psql inside Express app

There are similar questions with the one I have, but I'm still having trouble figuring out this issue.
I've added psql bin path to my bash_profile (on Mac) and I can run psql by:
psql -U postgres
The problem I have is that I can't run it inside my Express app. following the instructions on Express documentations, I have the following code:
const dotenv = require('dotenv').config();
var pgp = require('pg-promise')();
var db = pgp(
`postgres://
${process.env.DB_USER}:${process.env.DB_PASSWORD}
#
${process.env.DB_HOST}:5432/${process.env.DB_DATABASE}`
);
module.exports = db;
Then I try to make the db connection in app.js by
var db = require('./models/dbConnection/postgres')
db.one('SELECT $1 AS value', 123)
.then(function (data) {
console.log('DATA:', data.value)
})
.catch(function (error) {
console.log('ERROR:', error)
})
I have defined my environment variables in my .env file as follows:
DB_CONLIMIT=50
DB_HOST=127.0.0.1
DB_USER=postgres
DB_PASSWORD=
DB_DATABASE=mydatabase
when I run the app, I get:
[nodemon] starting node ./bin/www local-library:server Listening
on port 3000 +0ms ERROR: error: role "
postgres" does not exist
at Parser.parseErrorMessage
looking at my user table in psql when I run it via terminal:
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
What am I missing?

Error: Unable to read configuration file newrelic.js

I’m getting this error:
Error: Unable to read configuration file newrelic.js.
A base configuration file can be copied from 536 and renamed to in the
directory from which you will start your application.
Project is Angular 7 SPA with SSR.
There are two solutions:
The first by bj97301 on official new relic forums.
in my webpack config file, make newrelic external:
externals: ['newrelic']
in my webpack config file, use commonjs as my output library target:
output: { libraryTarget: 'commonjs'}
change newrelic.js to use exports. instead of export:
was: export const config = {
now: exports.config = {
This methods won't work if you want to deploy a whole package to remove server since you excluded the new relic package.
To solve this, you can use the second method.
As a workaround, change newrelic.js to override Environment variable instead of exporting the config.
e.g.
process.env.NEW_RELIC_NO_CONFIG_FILE = 'true';
process.env.NEW_RELIC_APP_NAME = 'YOUR APP NAME';
process.env.NEW_RELIC_LICENSE_KEY = 'YOUR_KEY';
process.env.NEW_RELIC_LOG_LEVEL = 'warn';
process.env.NEW_RELIC_ALLOW_ALL_HEADERS = 'true';
console.log('New relic has been configurated.');
And you can remove the original config that was exported:
'use strict';
exports.config = {
app_name: [],
license_key: '',
logging: {
level: 'warning'
},
allow_all_headers: true
}
Don't forget to require on your server.ts, simply add:
require('./newrelic');
I hope it would save someone some hours.

Marklogic 9 + Roxy: can't connect to created database using Node.js

I'm trying out the Roxy deployer. The Roxy app was created using the default app-type. I setup a new ML 9 database, and I ran "ml local bootstrap" using the default ports (8040 and 8041)
Then I setup a node application. I tried the following (sample code from https://docs.marklogic.com/jsdoc/index.html)
var marklogic = require('marklogic');
var conn = {
host: '192.168.33.10',
port: 8040,
user: 'admin',
password: 'admin',
authType: 'DIGEST'
}
var db = marklogic.createDatabaseClient(conn);
db.createCollection(
'/books',
{author: 'Beryl Markham'},
{author: 'WG Sebald'}
)
.result(function(response) {
console.log(JSON.stringify(response, null, 2));
}, function (error) {
console.log(JSON.stringify(error, null, 2));
});
Running the script gave me an error like:
$ node test.js
{
"message": "write document list: cannot process response with 500 status",
"statusCode": 500,
"body": "<error:error xsi:schemaLocation=\"http://marklogic.com/xdmp/error error.xsd\" xmlns:error=\"http://marklogic.com/xdmp/error\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n <error:code>XDMP-IMPMODNS</error:code>\n <error:name>err:XQST0059</error:name>\n <error:xquery-version>1.0-ml</error:xquery-version>\n <error:message>Import module namespace mismatch</error:message>\n <error:format-string>XDMP-IMPMODNS: (err:XQST0059) Import module namespace http://marklogic.com/rest-api/endpoints/config does not match target namespace http://marklogic.com/rest-api/endpoints/config_DELETE_IF_UNUSED of imported module /MarkLogic/rest-api/endpoints/config.xqy</error:format-string>\n <error:retryable>false</error:retryable>\n <error:expr/>\n <error:data>\n <error:datum>http://marklogic.com/rest-api/endpoints/config</error:datum>\n <error:datum>http://marklogic.com/rest-api/endpoints/config_DELETE_IF_UNUSED</error:datum>\n <error:datum>/MarkLogic/rest-api/endpoints/config.xqy</error:datum>\n </error:data>\n <error:stack>\n <error:frame>\n <error:uri>/roxy/lib/rewriter-lib.xqy</error:uri>\n <error:line>5</error:line>\n <error:column>0</error:column>\n <error:xquery-version>1.0-ml</error:xquery-version>\n </error:frame>\n </error:stack>\n</error:error>\n"
}
If I change the port to 8000 (the default appserver that inserts into Documents), the node function executes correctly as expected. I'm not sure if I need to configure anything else with the Roxy-created appserver so that it works with the node.js application.
I'm not sure where the "DELETE_IF_UNUSED" part in the error message is coming from either. There doesn't seem to be any such text in the configuration files generated by Roxy.
Edit: When accessing 192.168.33.10:8040 via the browser, I get a an xml with a similar error:
<error:error xsi:schemaLocation="http://marklogic.com/xdmp/error error.xsd" xmlns:error="http://marklogic.com/xdmp/error" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<error:code>XDMP-IMPMODNS</error:code>
<error:name>err:XQST0059</error:name>
<error:xquery-version>1.0-ml</error:xquery-version>
<error:message>Import module namespace mismatch</error:message>
<error:format-string>XDMP-IMPMODNS: (err:XQST0059) Import module namespace http://marklogic.com/rest-api/endpoints/config does not match target namespace http://marklogic.com/rest-api/endpoints/config_DELETE_IF_UNUSED of imported module /MarkLogic/rest-api/endpoints/config.xqy</error:format-string>
<error:retryable>false</error:retryable>
<error:expr/>
<error:data>
<error:datum>http://marklogic.com/rest-api/endpoints/config</error:datum>
<error:datum>http://marklogic.com/rest-api/endpoints/config_DELETE_IF_UNUSED</error:datum>
<error:datum>/MarkLogic/rest-api/endpoints/config.xqy</error:datum>
</error:data>
<error:stack>
<error:frame>
<error:uri>/roxy/lib/rewriter-lib.xqy</error:uri>
<error:line>5</error:line>
<error:column>0</error:column>
<error:xquery-version>1.0-ml</error:xquery-version>
</error:frame>
</error:stack>
</error:error>
If it matters, MarkLogic version is 9.0-3.1. It's a fresh install too.
Any advice?
Based on the comments, it looks like the problem is that the Node.js Client API expects to talk to a REST API endpoint, but the default Roxy configuration is an MVC application. If you haven't already done anything major with your Roxy app, I'd remove it and create one with --app-type=rest.
$ ml new my-app --app-type=rest --server-version=9
$ ml local bootstrap
$ ml local deploy modules
Then try your Node app.

my .env variables wont return for database login in node.js

Having a problem with .env variables in node.js, am using dotenv to handle the variables.
straight forward
require('dotenv').load()
and then checked console log to see if I can access then variables like so
console.log("database Name: "+process.env.DB_NAME);
console.log("database Username: "+process.env.DB_USER);
etc and all return fine.
the part of the code that calls the db is the following-
var Sequelize = require('sequelize');
module.exports = new Sequelize('dbname, 'username', 'password', {
host: 'hostname',
dialect: 'mssql',
dialectOptions: {
instanceName: 'namehere'
}
});
I replace the dbname with process.env.DB_NAME and all is fine, nothing falls over but the moment I try and use DB_USER in there then it fails to connect and shows user as ' ' in the log.
module.exports = new Sequelize(process.env.DB_NAME, process.env.USER_DB, 'password', { etc
the .env file itself is very straight forward and nothing out of the ordinary. structured as
NAME="value"
NAME2="value2"
etc. I though maybe once a value has been console logged it wont be available and turned off the console logs, but no luck. I also tried changing the name of the value encase that was reserved. please advise.
nevermind I was being silly. I presumed it only needed to be required once but not the case.

How exactly does eval work with nodejs?

Let's say I do:
eval(
db_config = {
host: 'localhost',
user: 'root',
database: 'forum',
password: 'test'
}
);
var gamefunctions = require('gamefunctions.js');
I can use db_config anywhere inside gamefunctions.js without having to pass it through a parameter. That's pretty neat. But, is this bad practice?
Reason I ask this is because if I do:
var db_config = {
host: 'localhost',
user: 'root',
database: 'forum',
password: 'test'
}
var gamefunctions = require('gamefunctions.js');
db_config becomes undefined anytime I use it in gamefunctions.js. And I would have to pass it through a parameter on each different function which just seems like evaling it first would save time and code, any downside to this?
Does eval basically just define the variables in a global scope for you, so they can be used in any file in nodejs?
You're doing 2 things wrong and there's much more elegant solution to this.
To explain what you're doing wrong, first is the use of globals. Second is that you're storing sensitive information in your code - your database password! And besides, it won't be very portable. Suppose you want to run it on another machine that has some other database credentials you'll end up changing your code unnecessarily.
You need to store it as environment variables. And if you end up hosting it some environments automatically have those set for you so you could use them in your app. For example openshift would have an $OPENSHIFT_MONGODB_DB_HOST that it tells you to use in your app to connect to its database.
And you need to create a separate file to store your db_config which you can require from other files.
So you might create a db_config.js which would look like this
var config = {};
config.host = process.env.HOST || 'localhost';
config.user = process.env.USER || 'root';
config.password = process.env.password;
module.exports = config;
Then you can safely just pass it the sensitive information like password from console
$ password=pass
$ node index.js
And as for having that information in your gamefunctions.js all you gotta do is require it
var db_config = require('./db_config');

Resources