Cannot connect to live database in Nodejs Openshift Application - mysql

I have no trouble connecting to the live database locally using port forwarding, but when we go to connect from the openshift gear, we get errors. Let me begin with the code:
Here is the connection variable
var connectionpool = mysql.createPool({
host : process.env.OPENSHIFT_MYSQL_DB_HOST,
port : process.env.OPENSHIFT_MYSQL_DB_PORT,
user : process.env.OPENSHIFT_MYSQL_DB_USERNAME,
password : process.env.OPENSHIFT_MYSQL_DB_PASSWORD,
database : 'stembuds',
socket : process.env.OPENSHIFT_MYSQL_DB_SOCKET
});
Here is an example of a query:
app.get('/answerDB/:course?/:answerID?', function(req, res){
var course = req.param('course');
var answerID = req.param('answerID');
connectionpool.getConnection(function(err, connection){
if(err){
console.error('CONNECTION error: ',err);
res.statusCode = 503;
res.send({
result: 'error',
err: err.code
});
}
if (course === undefined && answerID === undefined) {
connection.query('SELECT * FROM questions WHERE counter = 0', function(err, rows, fields){
if (err) {
console.error(err);
res.statusCode = 500;
res.send({
result: 'error',
err: err.code
});
}
for(var i in rows){
var newCourse = rows[i].course;
newCourse = courses[newCourse];
rows[i].course = newCourse;
}
res.send(rows);
connection.release();
});
}
Here are some errors we receive.
First is an error in the console of Chrome:
GET http://**.rhcloud.com/answerDB 503 (Service Temporarily Unavailable)
But sometimes we get a proxy error:
GET http://**.rhcloud.com/exploreDB 502 (Proxy Error)
Additionally, I have been running the command rhc tail -a nodejs and here is the error I am receiving
CONNECTION error: { [Error: ER_ACCESS_DENIED_ERROR: Access denied for user 'adminMYXaSuf'#'127.11.28.130' (using password: YES)]
code: 'ER_ACCESS_DENIED_ERROR',
errno: 1045,
sqlState: '28000',
fatal: true }
TypeError: Cannot call method 'query' of undefined
at /var/lib/openshift/5303aee55973ca4092000084/app-root/runtime/repo/routes/site.js:172:15
at Pool.<anonymous> (/var/lib/openshift/5303aee55973ca4092000084/app- root/runtime/repo/node_modules/mysql/lib/Pool.js:49:16)
at Handshake.Sequence.end (/var/lib/openshift/5303aee55973ca4092000084/app-root/runtime/repo/node_modules/mysql/lib/protocol/sequences/Sequence.js:78:24)
at Handshake.ErrorPacket (/var/lib/openshift/5303aee55973ca4092000084/app-root/runtime/repo/node_modules/mysql/lib/protocol/sequences/Handshake.js:93:8)
at Protocol._parsePacket (/var/lib/openshift/5303aee55973ca4092000084/app-root/runtime/repo/node_modules/mysql/lib/protocol/Protocol.js:202:24)
at Parser.write (/var/lib/openshift/5303aee55973ca4092000084/app-root/runtime/repo/node_modules/mysql/lib/protocol/Parser.js:62:12)
at Protocol.write (/var/lib/openshift/5303aee55973ca4092000084/app-root/runtime/repo/node_modules/mysql/lib/protocol/Protocol.js:37:16)
at Socket.<anonymous> (/var/lib/openshift/5303aee55973ca4092000084/app-root/runtime/repo/node_modules/mysql/lib/Connection.js:72:28)
at Socket.EventEmitter.emit (events.js:95:17)
at Socket.<anonymous> (_stream_readable.js:720:14)
Now it says cannot call method query of undefined. We thought that was strange, so we changed 'connection.query' to 'connectionpool.query' and it then told us that it cannot call method release of undefined. So we changed 'connection.release()' to 'connectionpool.release()' and it told us that the object # has no method release. So I am taking that part of the error with a grain of salt.
We have no idea why it wont connect. Any information would be greatly appreciated - Thanks.

If your application code works locally while connecting to your remote OpenShift-hosted DB (using rhc port-forward), then I would suspect that your app may have some undocumented dependencies.
It could be that you've installed something locally (or globally) in your dev environment, without including that dep in your app's package.json file.
Make sure that everything your app needs in order to run in a fresh environment is included in your app's package.json file before pushing it to OpenShift.
npm install my_dependency --save
I've written up some additional notes that might be useful for testing locally with a port-forwarded connection to an OpenShift-hosted DB: https://www.openshift.com/blogs/set-up-local-access-to-openshift-hosted-services-with-port-forwarding

Did you create that database name? It should be the name of your application. You can use the OPENSHIFT_APP_NAME environment variable for your database name. Can you ssh into your gear and connect to mysql without any issues? Also, are you trying to connect to the database on your openshift gear from your local machine or from your openshift gear?

Related

npx knex migrate:latest --knexfile database/knexfile.js --> Returning a throw err; // Rethrow non-MySQL errors

I am trying to run a migration using Knex, to a Cloud Data Platform and I am coming across some issues.
I am following knex.org's documentation, so I added the following lines (with specific connection details which I have removed. I checked several times that the environment variables were correct.) to my knexfile.js file.
module.exports = {
development: {
client: 'mysql',
connection: {
port: 'port',
host: 'host',
database: 'database',
user: 'user',
password: 'password'
},
pool: {
min: 2,
max: 10,
},
migrations: {
tableName:'knex_migrations',
},
debug: false
}
};
My init file contains the following:
exports.up = function(knex) {
return knex.schema.createTable('person', table => {
table.increments('id');
table.string('email').notNullable().unique();
table.string('first_name').notNullable();
table.string('last_name').notNullable();
table.timestamps(true,true);
})
};
exports.down = function(knex) {
return knex.schema.dropTable('person');
};
When I run npx knex migrate:latest, from the terminal (Mac) as show here:
$ npx knex migrate:latest --knexfile database/knexfile.js
I obtain the following error, and I cannot seem to figure out where the error is coming from.
Working directory changed to ~/Desktop/knex-tutorial/database
Using environment: development
/Users/user/Desktop/knex-tutorial/node_modules/mysql/lib/protocol/Parser.js:437
throw err; // Rethrow non-MySQL errors
^
RangeError [ERR_OUT_OF_RANGE]: The value of "sourceStart" is out of range. It must be <= 9. Received 13
at new NodeError (node:internal/errors:388:5)
at _copy (node:buffer:237:11)
at Buffer.copy (node:buffer:780:12)
at Parser.parseBuffer (/Users/user/Desktop/knex-tutorial/node_modules/mysql/lib/protocol/Parser.js:272:16)
at HandshakeInitializationPacket.parse (/Users/user/Desktop/knex-tutorial/node_modules/mysql/lib/protocol/packets/HandshakeInitializationPacket.js:34:37)
at Protocol._parsePacket (/Users/user/Desktop/knex-tutorial/node_modules/mysql/lib/protocol/Protocol.js:272:12)
at Parser._parsePacket (/Users/user/Desktop/knex-tutorial/node_modules/mysql/lib/protocol/Parser.js:433:10)
at Parser.write (/Users/user/Desktop/knex-tutorial/node_modules/mysql/lib/protocol/Parser.js:43:10)
at Protocol.write (/Users/user/Desktop/knex-tutorial/node_modules/mysql/lib/protocol/Protocol.js:38:16)
at Socket.<anonymous> (/Users/user/Desktop/knex-tutorial/node_modules/mysql/lib/Connection.js:88:28) {
code: 'ERR_OUT_OF_RANGE'
}
Node.js v18.4.0
I have searched everywhere online and I came across these two posts (one points towards the other), and I did try this, but I had no success.
MySQL 8.0 - Client does not support authentication protocol requested by server; consider upgrading MySQL client
RangeError [ERR_OUT_OF_RANGE]: The value of "sourceStart" is out of range. It must be <= 9. Received 13
I am fairly new to all of this and I am learning.
I would appreciate any help possible.
If more info is needed, let me know what I can/should add for clarification.

Connect to SQL database (AWS RDS) from Node.js without ETIMEDOUT error

Trying to connect to a SQL database using javascript but I keep getting this error:
Database connection failed: Error: connect ETIMEDOUT
at Connection._handleConnectTimeout (/Users/------/PhpstormProjects/------/node_modules/mysql/lib/Connection.js:409:13)
at Object.onceWrapper (events.js:421:28)
at Socket.emit (events.js:315:20)
at Socket._onTimeout (net.js:480:8)
at listOnTimeout (internal/timers.js:549:17)
at processTimers (internal/timers.js:492:7)
Have scoured the web but cannot find any solution. What am I doing wrong? Here is my code:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : "----.---------.-------.amazonaws.com",
user : "--------",
password : "--------"
});
connection.connect(function(err) {
connection.end();
if (err) {
console.error('Database connection failed: ' + err.stack);
return;
}
console.log('Connected to database.');
});
This one I actually found out myself. I was using phpstorm as an IDE and trying to connect to sql through my app.js file. I also use an aws ec2 instance to connect to my database which had already established a connection previously. I used SSH to connect to my ec2 instance, then created an app.js in my /var/www/html folder and connected from there without a problem.

Heroku Deployment error:connection refused

I have deployed my app on heroku..but the problem is ,it is giving this error
Unhandled rejection SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:3306
my config.js file-
module.exports={
port:process.env.PORT || 8082,
production: {
use_env_variable: process.env.DATABASE_URL
},
authentication:{
jwtSecret: process.env.JWT_SECRET|| 'secret'
}
}
my database connection file-
const Sequelize=require('sequelize')
const config=require('../config/config')
let sequelize=null;
if(process.env.DATABASE_URL){
sequelize=new Sequelize(config.production.use_env_variable,{dialect:'mysql'})
}
else{
sequelize=new Sequelize('bloggy','root','12345678',{dialect:'mysql',host:'localhost'})
}
module.exports=sequelize
I am not understanding why it is throwing that error.. it was working fine locally?
can anyone please help?
Ensure that in Heroku you have set the DATABASE_URL in environment variable b running Heroku config:set DATABASE_URL=<your database url>. This will ensure the if statement will return true and execute the first block

Simple React with mySql fails to read table records

I created a React project by entering the following command prompt commands
mkdir mysql-test && cd mysql-test
npm init –y
npm install mysql –save
Then I created a file called app.js and I put in the following code:
// app.js
const mysql = require('mysql');
// First you need to create a connection to the db
const con = mysql.createConnection({
host: 'rds-mysql-wmcw.cgz0te1dlkah.us-east-1.rds.amazonaws.com',
user: 'masterUsername',
password: 'masterPassword',
database : 'db_wmcw'
});
//try to connect to the mySql database. If an error occurs, display an
error message on the console
con.connect((err) => {
if(err){
console.log('Error connecting to Db');
return;
}
//a connection has been established to the database. Now, run a query against the table 'homepage'
//to retrieve each row and all columns of the table
console.log('Connection established');
con.query('SELECT * FROM homepage', (err,rows) => {
//if an error occurs when reading the data from the table, display the error on the console
if(err) {
console.log(err);
return;
}
//data has been retrieved from the table. display the data to the console
console.log('Data received from Db:\n');
console.log(rows);
});
});
con.end((err) => {
// The connection is terminated gracefully
// Ensures all previously enqueued queries are still
// before sending a COM_QUIT packet to the MySQL server.
});
Before I added the con.query command, when I type in app.js at the command prompt, the response back is Connection established. So I know that I am connecting to the mySql database. When I include the con.query command, and I type in app.js at the command prompt, I get the following error:
Connection established
{ Error: Cannot enqueue Query after invoking quit.
at Protocol._validateEnqueue (C:\jrs\codercamp\mysql-test\node_modules\mysql\lib\protocol\Protocol.js:203:16)
at Protocol._enqueue (C:\jrs\codercamp\mysql-test\node_modules\mysql\lib\protocol\Protocol.js:138:13)
at Connection.query (C:\jrs\codercamp\mysql-test\node_modules\mysql\lib\Connection.js:200:25)
at Handshake.con.connect (C:\jrs\codercamp\mysql-test\app.js:21:7)
at Handshake. (C:\jrs\codercamp\mysql-test\node_modules\mysql\lib\Connection.js:502:10)
at Handshake._callback (C:\jrs\codercamp\mysql-test\node_modules\mysql\lib\Connection.js:468:16)
at Handshake.Sequence.end (C:\jrs\codercamp\mysql-test\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24)
at Handshake.Sequence.OkPacket (C:\jrs\codercamp\mysql-test\node_modules\mysql\lib\protocol\sequences\Sequence.js:92:8)
at Protocol._parsePacket (C:\jrs\codercamp\mysql-test\node_modules\mysql\lib\protocol\Protocol.js:278:23)
at Parser.write (C:\jrs\codercamp\mysql-test\node_modules\mysql\lib\protocol\Parser.js:76:12) code: 'PROTOCOL_ENQUEUE_AFTER_QUIT', fatal: false }
Right at the top of the error it states Cannot enqueue Query after invoking quit. I don't understand why the system thinks I am executing the query after invoking quit. I am not invoking quit unless that is what happens when I execute con.end but con.end is the last statement to execute. It is way after the query call.
Any assistance is greatly appreciated.
Thank you.
PS - I have included the host name, user ID, password, and database name to make debugging easier. There is no real important data in the database
Okay, so the alternative solution would be uninstall mysql package and change with mysql2 package instead. As the author said:
MySQL2 is mostly API compatible with mysqljs and supports majority of features
This answer is for the questioner's comment on his post
If you really wanna reassign the one row of data, you can do:
const { product_detail, product_description } = results[0];
That's basic syntax :D (ES6 maybe)

"mysql_clear_password" plugin error when using knex but not when using mysql2

I am trying to connect to MySQL server using the mysql_clear_password plugin. I set up the connection configuration for node-mysql2 as follows:
const connectionConfig = {
host: rwConfig.host,
user: rwConfig.user,
database: rwConfig.database,
ssl: {
ca: sslContent
},
password
}
Then to support the mysql_clear_password plugin I added the following (link of the reference i used: https://github.com/sidorares/node-mysql2/issues/438#issuecomment-255343793):
connectionConfig.authSwitchHandler = (data, cb) => {
console.log('In auth switch handler');
if (data.pluginName === 'mysql_clear_password') {
console.log(data);
console.log(data.pluginData.toString('utf8'));
console.log('In mysql clear password');
var tmppassword = connectionConfig.password + '\0';
var buffer = Buffer.from(tmppassword, 'base64');
cb(null, buffer);
}
};
This works when I attempt to connect to my database.
Now I try to do something similar using knexjs. I use the following configuration object:
const knexConfig = {
client: 'mysql2',
connection: connectionConfig,
pool: {
min: 0,
max: 20
},
acquireConnectionTimeout: 10000
};
The connectionConfig I passed in as the value for connection is the same object I used for connecting with node-mysql2. Then I create a knex connection:
const rwConnection = knex(knexConfig);
This for some reason throws this error:
{ Error: Client does not support authentication protocol requested by server; consider upgrading MySQL client
at Packet.asError (node_modules/mysql2/lib/packets/packet.js:703:13)
at ClientHandshake.Command.execute (node_modules/mysql2/lib/commands/command.js:28:22)
at Connection.handlePacket (node_modules/mysql2/lib/connection.js:515:28)
at PacketParser.onPacket (node_modules/mysql2/lib/connection.js:94:16)
at PacketParser.executeStart (node_modules/mysql2/lib/packet_parser.js:77:14)
at TLSSocket.<anonymous> (node_modules/mysql2/lib/connection.js:386:31)
at emitOne (events.js:96:13)
at TLSSocket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:176:18)
at TLSSocket.Readable.push (_stream_readable.js:134:10)
at TLSWrap.onread (net.js:547:20)
code: 'ER_NOT_SUPPORTED_AUTH_MODE',
errno: 1251,
sqlState: '#08004' }
I don't know why this is giving me the error. In the knex documentation (http://knexjs.org/) it says:
The connection options are passed directly to the appropriate database client to create the connection, and may be either an object, or a connection string
Based on that I thought it would just pass the configuration through and make the connection using node-mysql2. Any help would be appreciated.
I figured out the issue and it works now. Knex was not passing on all the attributes to the msyql2 client.
Here is what I did for anyone else who might run into this problem. I modified the configurations that knex was passing to mysql2 in the node_modules/knex/lib/dialect/mysql2 and added authSwitchHandler to the configOptions array.