Google Cloud Functions - Connect to Cloud SQL via SSL - javascript

The GCF Cloud SQL documentation does not show how to connect via the socket using SSL. Here is my config, however when I try to connect I get an ECONNREFUSED error. But when I try to connect to a non-SSL database it works fine. Any ideas?
const mysql = require('mysql');
const mysqlConfig = {
connectionLimit: 1,
user: dbUser,
password: dbPassword,
database: dbName,
ssl: {
ca: await getFileContents(bucketName, ssl.ca_filename),
key: await getFileContents(bucketName, ssl.key_filename),
cert: await getFileContents(bucketName, ssl.cert_filename)
}
};
if (process.env.NODE_ENV === 'production') {
mysqlConfig.socketPath = `/cloudsql/${connectionName}`;
}
// Connection pools reuse connections between invocations,
// and handle dropped or expired connections automatically.
let mysqlPool;
exports.mysqlDemo = (req, res) => {
// Initialize the pool lazily, in case SQL access isn't needed for this
// GCF instance. Doing so minimizes the number of active SQL connections,
// which helps keep your GCF instances under SQL connection limits.
if (!mysqlPool) {
mysqlPool = mysql.createPool(mysqlConfig);
}
mysqlPool.query('SELECT NOW() AS now', (err, results) => {
if (err) {
console.error(err);
res.status(500).send(err);
} else {
res.send(JSON.stringify(results));
}
});
};

Connections between Cloud Functions and Cloud SQL work in the same way as connections from App Engine . As such SSL/TLS connections are needed only when you are connecting to Cloud SQL using public IP addresses. If Cloud SQL Proxy or the Java Socket Library, is used, setting up SSL is not required encryption happen by default.
How to set this up is set in the following document:
https://cloud.google.com/functions/docs/sql#connecting_to_cloud_sq
For an explanation as to how the connections are implemented please have a look at:
https://cloud.google.com/sql/docs/mysql/configure-ssl-instance

Related

How to establish a remote connection with node potsgres?

I am trying to create an API where I can query information from a database. The DB is hosted on my university's computer cluster. Here is the code I currently have
const Pool = require('pg').Pool
const pool = new Pool({
user: 'username',
host: 'hostname-of-school-computer',
database: 'db-name',
password: 'pass',
port: 5432
})
const getUsers = (request, response) => {
pool.query('SELECT * FROM Inventory ORDER BY ingredient_id ASC', (error, results) => {
if (error) {
throw error.message
}
response.status(200).json(results.rows)
})
}
When I run this code and make a request on localhost, I get the error
no pg_hba.conf entry for host "165.xx.xx.172", user "username", database "db-name", SSL off
I tried adding ssl: true to the pool config but then got the error self signed certificate in certificate chain. Additionally, I have tried editing pg_hba.conf to listen to my school's host IP and that neither worked.
These are the lines I added to pg_hba.conf:
# TYPE DATABASE USER ADDRESS METHOD
host all all 0.0.0.0/0 md5
host all all 165.xx.xx.172/0 md5
I am kind of a noob when it comes to JS and postgres so please any help would be greatly appreciated.

How to deploy Next JS App with Mongoose(MongoDB) connection on Vercel?

I am facing issue while deploying my next js app on vercel with mongodb connection. I have added env variable also on vercel site where we deploy next js app. Is there something going wrong in the below file ?
next.config.js
module.exports = {
env: {
MONGODB_URI: "mongodb://localhost/tasksdb",
},
};
I have add env variable as well into my next js project
.env.local
MONGODB_URI = "mongodb://localhost/tasksdb"
I establish this mongodb connection from this doc https://mongoosejs.com/. It's provide us to connect with mongodb straightaway .
And this my mongodb connection establish code
import { connect, connection } from "mongoose";
const conn = {
isConnected: false,
};
export async function dbConnect() {
if (conn.isConected) return;
const db = await connect(process.env.MONGODB_URI);
conn.isConnected = db.connections[0].readyState;
// console.log(conn.isConnected);
// console.log(db.connection.db.databaseName)
}
connection.on("connected", () => {
console.log("Mongodb connected to db");
});
connection.on("error", (err) => {
console.error("Mongodb connected to", err.message);
});
Is there something wrong by creating the database this way because in local everything working fine ?
I don't think vercel's servers can comunicate with your localhost. You can try hosting your database in the mongodb cloud
The code seems to be fine, but you can not connect to Vercel using localhost. You can use Serverless Atlas version of MongoDB which is free you can host your database there and then connect using the link they will provide.
See : https://www.mongodb.com/pricing

adding files to heroku app with a database addon in node.js

I'm hosting my discord bot on heroku and i installed this database for adding files, because for what i understood heroku has a temporarly file system, and also things like fs don't work anymore. This is the addon i installed: https://elements.heroku.com/addons/heroku-postgresql
Here is an example of the code i used for appending to txts/json files:
// Json example
if (command === 'jsonExample') {
config.example = args[0]
var stringifiedConfig = JSON.stringify(config, null, 4);
fs.writeFileSync("./config.json", stringifiedConfig)
console.log(stringifiedConfig)
}
// Txt example
if (command === 'txtExample') {
fs.appendFileSync('folder/example.txt', data + "\r\n", (err) => {
if (err) throw (err)
})
}
console.log('File edited')
The thing is i don't know how i could adapt it to work with the database, i'm very new to heroku and i didn't really find anything for discord bots, i hope you can help.
PostgresSQL is a cloud SQL database. You use HTTP requests to talk to the API to upload/download files/data from the database.
PostgresSQL has a Node.js package, pg, which you use to interact with the database.
Using this database, your provided code might look like this:
const { Client } = require("pg"),
client = new Client({
// make sure you set your environment variables in the heroku dashboard
connectionString: process.env.DATABASE_URL,
ssl: { rejectUnauthorized: false }
});
client.connect();
async function commandCode(command, config, args, data) {
if (command === "jsonExample") {
config.example = args[0];
const stringifiedConfig = JSON.stringify(config);
await client.query(/* some SQL query here */);
console.log(stringifiedConfig);
} else if (command === "txtExample") {
await client.query(/* some SQL query here */);
console.log("File edited.");
}
}
You will need to know how to use SQL to use this database, which may or may not be what you are looking for.

NodeJS with socket.io and postgres LISTEN

I'm trying to get my frontend to watch for events whenever a certain table on my postgres db is altered.
The Postgres events fire perfectly and I'm able to relay them to through the Socker.io connection, but I'm having reliability issues. I'm getting (node:26) UnhandledPromiseRejectionWarning: Error: Client was closed and is not queryable errors on my server and often events are not emitted and caught by Socket. I'm assume it has to do with the way I connect to Socket / db clients.
pg config:
const {Pool} = require('pg');
const production = process.env.NODE_ENV === 'production';
const connectionString = `postgresql://${process.env.DB_USER}:${process.env.DB_PASSWORD}#${process.env.DB_HOST}:${process.env.DB_PORT}/${process.env.DB_DATABASE}`
const pool = new Pool({
connectionString: process.env.CONNECTION_STRING ? process.env.CONNECTION_STRING : connectionString,
ssl: production,
connectionTimeoutMillis : 5000,
idleTimeoutMillis : 30000
});
index.js
io.of("/marketDetails").on('connect', (socket) => {
pool.connect((err, client, release) => {
if (err) {
console.log(err);
return;
}
client.query('LISTEN update_table');
client.on('notification', async(data) => {
console.log("notified of table change")
handleDBEvent(socket, data);
})
socket.on("disconnect", () => {
client.query('UNLISTEN update_table');
})
release();
})
});
I get notified on certain table changes but very inconsistently.
You are immediately releaseing the database client that you acquired, before any notifications can happen, and you're getting the error message every time the socket disconnects and you try to run the UNLISTEN command on the released client whose connection was closed after 30s.
Instead, use
socket.on("disconnect", async () => {
try {
await client.query('UNLISTEN update_table');
} finally {
release();
}
});
Btw I would recommend not to acquire a new database connection for each socket.io client, the database is far too valuable for that. Instead, create a single client for your app (you might not even need a pool), have it listen to the update_table events (maybe only when sockets are connected), and then broadcast each event to all currently-connected sockets.

How to connect MySQL with nodejs controllers?

I have a server on sails nodejs and I am trying to connect my controllers with my MySQL db through a wrapper file that would create the connection pool. My purpose is that I use that pool everytime a function in any controller needs to interact with DB, and in such a way that connection is created at the time interaction starts and connection is closed at the time interaction is over. For this, I have created a wrapper file db.js
db.js
var mysql = require('mysql');
var connection = mysql.createConnection({
host:"localhost",
port: '3306',
user:"ye_old_username",
password:"ye_old_password",
database: "ye_old_schema"
});
module.exports = connection;
Now, I am creating a connection pool called ConnectionPool.js
ConnectionPool.js
var mysql = require('mysql'),
config = require("./db");
/*
* #sqlConnection
* Creates the connection, makes the query and close it to avoid concurrency conflicts.
*/
var sqlConnection = function sqlConnection(sql, values, next) {
// It means that the values hasnt been passed
if (arguments.length === 2) {
next = values;
values = null;
}
var connection = mysql.createConnection(config);
connection.connect(function(err) {
if (err !== null) {
console.log("[MYSQL] Error connecting to mysql:" + err+'\n');
}
});
connection.query(sql, values, function(err) {
connection.end();
if (err) {
throw err;
}
next.apply(this, arguments);
});
}
module.exports = sqlConnection;
I have followed the method answered on this question to create the connection pool: How to provide a mysql database connection in single file in nodejs
And finally, I am trying to run a function from a controller using the wrapper and the connection pool. The code inside the Controller is
var connPool = require('./ConnectionPool');
module.exports = {
testConn: function(req, res){
connPool('SELECT * from user where ?', {id: '1'}, function(err, rows) {
if(err){
sails.log.debug(err);
}else{
console.log(rows);
}
});
}
};
All the three files, the wrapper, the connection pool, and the controller are in the same Controllers folder.
Now, when I send a request to the URL through my client, that would invoke the testConn function inside the controller, I get the following response on server log:
[MYSQL] Error connecting to mysql:Error: ER_ACCESS_DENIED_ERROR: Access denied for user ''#'localhost' (using password: NO)
This error is coming from the line connection.connect(function(err) { in connection pool file.
When I try to log on my MySQL db through the same credentials on command line, I am through it. Therefore I believe that db.js file has some format related issue because of which a proper connection is not getting initiated. There can be other reason as well, but the reason I suspect seems to be very strong.
I need some guidance on solving this issue. Any help will be appreciated.

Categories

Resources