Connection pool in OrientJS - javascript

I want to use OrientJS with Express.js. How do I configure a connection pool before any http request is made, acquire and release a connection from the pool during the request/response cycle, and finish the pool when I shutdown the app?

I've looked a bit into OrientJS source and actually found a way to use the built-in ConnectionPool.
You don't need any generic resource pooling module (as I mentioned in my comment above). Basically, it's very straightforward. All you need to do is:
var OrientDB = require('orientjs');
var server = OrientDB({
host: 'localhost',
port: 2424,
username: 'root',
password: 'yourpassword',
pool: {
max: 10
}
});
Now your server object is using the built in ConnectionPool, and max allowed connections are 10.
If you check server.transport.pool, you'll see the internal pool object.
To actually check how many connections are made (or in use), you can check the length of server.transport.pool.connections (which is an array).
Another way to watch connections' use is a simple bash command:
$ watch -n 0.1 'netstat -p tcp -an | grep 2424'
And you'll see the connections.
From this point, you can start querying right away and the connection pool will be used automatically.

Related

How to host a node js / express server with MySQL on Elastic Beanstalk AWS

I am trying to host my Node js / express server on AWS Elastic Beanstalk. My express server is connected to a MySQL database. So far, I have hosted the MySQL database on an RDS instance on AWS. I have also created an elastic beanstalk environment and "deployed" the Node js server using a CodePipeline (which in connected to GitHub). I have found this process very interesting and feel like I am very close. However, I am running into trouble with the MySQL connection. Here are the relevant lines of code from my Node server:
const express = require("express");
const mysql = require("mysql");
const cors = require("cors")
const formData = require("express-form-data");
const { PORT = 5000 } = process.env
const app = express();
app.use(cors());
app.use(formData.parse({maxFieldSize: '10mb'}));
var mysqlConnection = mysql.createConnection({
host: "my-rds-dbconnection-endpoint",
user: "my-username",
password: "****",
database: "nameOfSchema"
})
mysqlConnection.connect((err) => {
if(err) {
console.log('THIS IS NOT CONNECTING #20')
throw err;
}
console.log("Connected to AWS!")
})
console.log('PORT', PORT)
app.get('/', (request, response) => {
response.send('Hello World!')
console.log('hello from /')
});
app.listen(PORT, function() {
console.log(`App listening on port ${PORT}`);
});
When I run the server using Node in my command prompt for testing purposes, I make it all the way to the message "connected to AWS" and it seems to make the connection to the database. However, when I connect to the environment URL, I get the expected output 'Hello World', but when I download the logs to see what happens, the 'THIS IS NOT CONNECTING' statement prints. Obviously, when I access this node server from the elastic beanstalk environment, it is not connecting to my database. I am unsure why. Does anyone have any ideas about what I could be missing? I sure would appreciate your experience/help!!!
Seeing that you can connect from your local environment and not in your Elastic Beanstalk environment, I assume it's a connectivity issue. There are a few things you can try.
1. RDS Instance - Security Group: Temporarily allow all connections
See if the security group for the RDS instance allows connection from your Elastic Beanstalk environment. You may have whitelisted your own local PC but may not have for other IPs/Security Groups. As an easy check you can allow all connection temporarily to see if this is the issue.
2. RDS Instance - Public Accessibility: Set to Yes/True
For this, I believe it's already configured to True, since you can connect from your local environment with the code provided. Mentioning it here just in case.
3. Elastic Beanstalk - VPC: Set it to be the same as RDS
Connecting EC2(by Elastic Beanstalk) & RDS in different VPC is more complex. Also it makes sense to put them together if you own both environments. After configuring the VPC settings in the Elastic Beanstalk Console, you can set up the security group for the DB and EC2 in the same VPC.
4. Elastic Beanstalk - Security Group: Temporarily allow all connections
While your Elastic Beanstalk environment may accept HTTP/S(TCP Ports 80/443) requests, it may not have been configured for RDS connectivity (TCP Port 3306). Also check if it allows connectivity for your RDS instance (More info.
Note on security: The above two might help get the connection working for now, but is not a proper setting for production environment (not for development either). It's best practice to set RDS public accessibility to No/False. If you haven't planned to already, I recommend setting up a more secure DB environment by SSH Tunnelling using a Bastion Host. Be aware that this will add costs for the EC2 instance, but you can use the free tier instance for the Bastion Host for small projects.

Can't connect to Azure Cache for Redis from Azure Web App

I have NodeJS Web App which trying to connect to the Azure Cache for Redis which is part of the same subscription.
const redis = require('redis')
const redisConnectionConfig = {
host: REDIS_HOST,
port: REDIS_PORT,
auth_pass: REDIS_PASSWORD
tls: { servername: REDIS_HOST }
}
...
redis.createClient(redisConnectionConfig)
I'm able to connect to Redis from my local machine after adding my IP to the Redis Firewall rules.
Also, I've added all 'Outbound IPs and Additional Outbound IP Addresses' from the Service App Properties.
I've tried even to allow access from all IPs
still not pass
But it is not connected and if I try to use Redis I receive the following connection error:
MaxRetriesPerRequestError: Reached the max retries per request limit (which is 20). Refer to "maxRetriesPerRequest" option for details.
Something similar solved for the VM here. But in the case of the App Service Azure managed that layer.
Looks like it's not connectivity issue.
Network part you always can check via WebApp->Console and use command
tccping redisservername:redisserverport
tcpping_example
Probably something with your redis cache size. What size are you using now?
You can find azure redis limits here

ER_NOT_SUPPORTED_AUTH_MODE - MySQL server

Failed at Connecting Node.js Server to MySQL-Database
       
I had MariaDB" installed on a "Node.js Server", but decided that I wanted to use a SQL Database instead. I uninstalled, and completely removed "MariaDB", after which, I proceeded to install the "Community Ed." "MySQL Database". After going through the entire *'MySQL Setup Process'**, I made several attempts to connect to the database via a JavaScript document that implemented the de facto code snippet for a JS DB Connection — my DB-connection document is posted as a code snippet bellow — shown in the code snippet bellow. Disappointingly, the JS/SQL connection failed at each attempt.
Here is the Failed Connection Error Message that I received:
"ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication
protocol requested by server. Consider upgrading MariaDB client."
JS/SQL Connection Snippet that I am using:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '********',
database : 'foobarDb'
});
For MySQL v8.0 use the following:
ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY 'password'
You need to reconfigure the Quick Action Settings by clicking the "Reconfigure Link" as shown in the screenshot below. From there, select "Legacy password" for v5.1.
The cause of the error:
You installed the latest "MySQL Version", v8.0. The latest version has a different encryption plugin for authenticating users at login. 5.6, and 5.1 revert to the prior encryption algorithms. Please note, 5.6 & 5.1 have several security vulnerabilities reported by oracle.
The top-rated answers in this Q/A thread are for the most part valid, but they are unorganized, which is to say the least. A solution is here, however, the solution is bits and pieces amongst three other answers. To offer an answer that is a single solution, more helpfull, and is a time saver, I'll make an attempt to write an answer myself in a way that is clear, concise, and orderly. I will cover the whole problem that Ubuntu users experiance, and in addition, I will add information that's helpfull, and not included in any other answer, that will help readers understand the issue that persist for them.
To Start: The Issue is not a SQL Problem, it is an Ubuntu Problem
The issue that persist for you, has to do with the fact (a fact most software developers/I.T. professionals are probably all already aware of) the 'ROOT' user doesn't have a password in Ubuntu, and is accessible by anyone with $ sudo privileges. To offer clarity for anyone experiencing this issue who might be new to some of the semantics that I am throwing out there; Ubuntu users use the sudo -i command to register as the Root-user, whereas, every other Linux distribution in existence uses a User-ID w/ a Password. In truth, I cannot remember ever needing to be a ROOT user for anything other than Database Management, and always only when I am first installing a Database to a server, though my experience is probably far limited in comparison to some IT professionals out there. My point is, typically using sudo for everything does the Job, but in this case it is problematic, so the important thing to note is the following:
PROBLEM:
Ubuntu lacks a 'ROOT PASSWORD' and this is why everyone experiencing the issue that we are discussing runs a Distribution of the Ubuntu OS/SHELL. And unless we rewrite the Ubuntu kernel, and the practically everything else in the operating system, we cannot give Ubuntu SHELL a "root password".
SOLUTION:
We may not be able to give the Ubuntu SHELL a root password, but we can, and we will, give MySQL a 'ROOT PASSWORD'.
TO EXECUTE THE SOLUTION YOU NEED TO HAVE THE FOLLOWING:
Node.js v12+
NPM (Probably need v5+ but don't quote me on that)
MySQL v8.0+ (obviously)
The MySQL Driver (from npm)
CONFIRMATION:
If you don't already have everything on the list you honestly can't say that this is the issue your dealing with.
If you do have everything on the list
and you are running an Ubuntu distro, then you should be getting an error message that probably looks somthing like the one I got when I had to fix this issue.
My error message read:
ERROR: (28000): Access denied for user 'ajc'#'localhost'
ERROR: ERROR_NOT_SUPPORTED_AUTH_MODE: Client does not support
authentication protocol requested by server; consider upgrading
MySQL client
'Client does not support authentication protocol requested by server; consider upgrading MySQL client
If your still reading then your likely in the right place.
To start fixing the problem create an empty Node.js project, and install the MySQL driver as a dependency to it using NPM (you should know how to do this, as you had to do that to have this issue). Add a JavaScript .js file. Call the file, sqltest.js or whatever something like that.
Add the code below to the file you just created.
let mysql = require('mysql');
let connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '********',
database : 'DB_App_00',
});
connection.connect(function(err) {
if (err) {
return console.error('error: ' + err.message);
}
console.log('Connected to the MySQL server.');
});
In the method called 'createConnection' is a JSON OBJ parameter holding the credential values to make a valid connection to the MySQL database server. The user has to equal to 'root', and the database has to exist. Also for a later test add a testing table to the database, with some BS data."
Now open a terminal window, and do your typical updates & upgrades, this is important, which is why every tutorial asks you to do them.
~$: sudo apt update
~$: sudo apt upgrade
After you do your upgrades enter the following command into your terminal:
~$: sudo mysql -u root
It should prompt you for your Ubuntu Password, type it and [ENTER].
The next step is critically important:
Now here is the step that could be considered the medicine and/or the cure to the problem. Your terminal should be open, and you should be inside of the MYSQL Server, under the user 'root'. The terminal should have the cursor flashing at a blank mysql command-line. Within the CMDL copy & paste this:
mysql> ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY 'ChoosePassword';
mysql> FLUSH PRIVILEGES;
The next part is obvious, change 'ChoosePassword' to a password you will remember while leaving the password within single quotation marks. Change absolutely nothing else, press [ENTER]
If you followed the steps correctly, you now have a MySQL 'ROOT USER' with its own password now. Test it by copy and paste the following at the Ubuntu CMDL:
~$: mysql -u root -p
It will prompt you for your new password, type it and [ENTER]
...you should be in, now exit.
mysql>exit
Back to your 'testsql.js' file, alter the credentials to root for the user, password to your password, a valid database, and host to localhost, unless you have a unique need for a different hostname.
let connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '********',
database : 'DB_App_00',
});
now use node to run the node test file
~$: node testsql.js
Final Thought:
If it doesn't say connected you did something wrong, but if all went well, you should connect. It took some effort before I got it to work, but this answer should save you some time from reading all the other half written answers.
You can use the package mysql2 instead of mysql. I ran into the same issue and using mysql2 worked for me.
You can install this package using npm i mysql2
You can either alter an existing user to use mysql_native_password, or create a new user,
CREATE USER 'new_user'#'%' IDENTIFIED WITH mysql_native_password BY '***';
GRANT USAGE ON *.* TO 'new_user'#'%';
ALTER USER 'new_user'#'%' REQUIRE NONE WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;
GRANT ALL PRIVILEGES ON `new_user`.* TO 'new_user'#'%';
FLUSH PRIVILEGES;
replace new_user with your new user name, and set your password.
Now you can access mysql from node using the mysql package,
npm install mysql
recommended to use pool connection for this package.
I figure that some MySQL versions have the authentication for the establishment of a connection a bit messed up. All I had to do was add the line "insecureAuth" : true to the CreateConnection(...) credentials.
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '********',
database : 'vod_bill_database',
insecureAuth : true
});
The error is gone now, and the client is successfully connecting.
1st run this code ->
ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
2nd
flush privileges;
try the older version of mysql like 5.6.40, it uses by default SHA256_password auth where new version 8.0. uses by default sha2_password auth which is more secure and throw this authentication protocol error.
MYSQL installer 5.6.40
yellow yow bros !
// mysql.ts
const pool = mysql.createPool({
connectionLimit: 10,
host: "localhost",
user: "root",
password: "password",
database: "rest-resume-api",
});
and then I have a docker-compose file such as
# docker-compose.yml
version: '3.3'
services:
db:
image: mysql
restart: always
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_DATABASE: 'rest-resume-api'
MYSQL_USER: 'root'
MYSQL_ROOT_PASSWORD: 'password'
ports:
- '3306:3306'
expose:
- '3306'
volumes:
- my-db:/var/lib/mysql2
volumes:
my-db:
you can do it
ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY 'password'
ALTER USER 'root'#'%' IDENTIFIED WITH mysql_native_password BY 'password'
FLUSH PRIVILEGES;
check mysql root user IDENTIFIED
select user,host,plugin from user;
+------------------+-----------+-----------------------+
| user | host | plugin |
+------------------+-----------+-----------------------+
| root | % | mysql_native_password |
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session | localhost | caching_sha2_password |
| mysql.sys | localhost | caching_sha2_password |
| root | localhost | mysql_native_password |
+------------------+-----------+-----------------------+
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '********',
database : 'vod_bill_database',
port : 3308
});
I had the same error and since i changed my port in phpmyadmin from 3306 to 3308 therefore here also i had to write port: 3308 and it started working.
in order to overcome this error use the following code:
var connectionString = 'mysql://*root:*password#*localhost/*database?charset=utf8_general_ci&timezone=-0700';
var connection= mysql.createConnection(connectionString);
but make sure that you changed the * marks in the connectionString based on your setup.
just create a new user on MySQL
CREATE USER 'foo'#'localhost' IDENTIFIED WITH mysql_native_password BY 'bar';

Node.js connect ECONNREFUSED 127.0.0.1:8000 DynamoDB Local Error

I'm using this NPM plugin to handle creating a local DynamoDB local server within my Node app. For some reason sometimes it gives me the following error. Can't figure out why but it seems to always happen when running tests during a specific section of tests.
It definitely doesn't happen every time. Maybe 50% or so. Very strange.
I have read that the error means starting the DynamoDB local server failed. But I have no idea why since it doesn't give any more details.
DynamoDB Local failed to start with code 1
{ Error: connect ECONNREFUSED 127.0.0.1:8000
at Object.exports._errnoException (util.js:1012:11)
at exports._exceptionWithHostPort (util.js:1035:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1080:14)
message: 'connect ECONNREFUSED 127.0.0.1:8000',
code: 'NetworkingError',
errno: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 8000,
region: 'us-west-2',
hostname: 'localhost',
retryable: true,
time: 2016-09-13T03:26:05.804Z }
Oh and here is my code to create the server.
dynamodbLocal.start({port : dbport, /* Port to listen on. Default: 8000 */
cors : '*', /* Enable CORS support (cross-origin resource sharing) for JavaScript. You must provide a comma-separated "allow" list of specific domains. The default setting for cors is an asterisk (*), which allows public access. */
inMemory : false, /* DynamoDB; will run in memory, instead of using a database file. When you stop DynamoDB;, none of the data will be saved. Note that you cannot specify both dbPath and inMemory at once. */
dbPath : __dirname + '/dynamodb/', /* The directory where DynamoDB will write its database file. If you do not specify this option, the file will be written to the current directory. Note that you cannot specify both dbPath and inMemory at once. For the path, current working directory is <projectroot>/node_modules/dynamodb-localhost/dynamob. For example to create <projectroot>/node_modules/dynamodb-localhost/dynamob/<mypath> you should specify '<mypath>/' with a forwardslash at the end. */
sharedDb : false, /* DynamoDB will use a single database file, instead of using separate files for each credential and region. If you specify sharedDb, all DynamoDB clients will interact with the same set of tables regardless of their region and credential configuration. */
delayTransientStatuses : false, /* Causes DynamoDB to introduce delays for certain operations. DynamoDB can perform some tasks almost instantaneously, such as create/update/delete operations on tables and indexes; however, the actual DynamoDB service requires more time for these tasks. Setting this parameter helps DynamoDB simulate the behavior of the Amazon DynamoDB web service more closely. (Currently, this parameter introduces delays only for global secondary indexes that are in either CREATING or DELETING status.) */
optimizeDbBeforeStartup : true /* Optimizes the underlying database tables before starting up DynamoDB on your computer. You must also specify -dbPath when you use this parameter. */
});
Any ideas?

Azure Web Site starting my Hapi Node.js site with socket protocol

Whenever I deploy my Hapi.js web application to azure, it starts the server using the socket protocol (see output below).
socket:\\.\pipe\b5c0af85-9393-4dcb-bd9a-3ba9b41ed6fb
GET /
GET /{param*}
GET /api/employees
POST /api/employees
GET /api/employees/{id}
PUT /api/employees/{id}
DELETE /api/employees/{id}
POST /api/worklog
GET /login
POST /login
Hapi server started # socket:\\.\pipe\b5c0af85-9393-4dcb-bd9a-3ba9b41ed6fb
150914/214730.270, [response], socket:\\.\pipe\b5c0af85-9393-4dcb-bd9a-3ba9b41ed6fb: [1;32mget[0m / {} [32m200[0m (316ms)
However, whenever I am running this locally, it starts using http... I have not run into this issue using express or loopback, only Hapi. Is there some sort of configuration that I am missing? This is the server.connection function:
var server = new Hapi.Server();
var host = process.env.host || '0.0.0.0';
var port = process.env.port || 3000;
server.connection({host: host, port: port});
The reason this is a big deal is because I cannot pass socket://*<mydoamin>* to google as a callback URI for OAuth.
You shouldn't need to pass socket://<domain> to google, you'd pass the normal https://yourDomain.com or even the https://yourSiteName.azurewebsites.net to Google for OAuth callback and it should work as you would expect.
The fact that the node application is listening on a pipe rather than a normal tcp socket is just an implementation detail of iisnode. Basically the problem is that node has it's own webserver so you can't use it with other webservers like IIS, Apache, nginx, etc. iisnode bridges the gap between IIS and node in that it allows IIS to listen to the HTTP port on the machine 80 and when IIS gets a request on that port, it just forwards it to the node process that's listening on a named pipe. This allows you to manage your sites in IIS as you normally would on a Windows Server machine, while actually writing your app in node.
You can think of it as 2 webservers running on the box, one (IIS) is acting as a proxy for the other (node) where all the work is actually happening. The fact that the iisnode developer chose to use a named pipe instead of a normal tcp socket is odd (though kind of understandable since you can't easily reserve a port per se as you can a pipe), but it's the way it is.

Categories