Skip to content

Commit

Permalink
add conection resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Matheus Martins committed Oct 7, 2019
1 parent 087ebeb commit 5351b56
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 8 deletions.
10 changes: 3 additions & 7 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@ services:
env_file:
- .env
common-db:
container_name: common-db
container_name: common_db
image: postgres
environment:
POSTGRES_USER: common_db
POSTGRES_PASSWORD: common_db
PGDATA: /data/postgres
volumes:
- ./data/db/common/:/data/postgres
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5432:5432"
Expand All @@ -33,9 +31,8 @@ services:
environment:
POSTGRES_USER: tenant-1-db
POSTGRES_PASSWORD: tenant-1-db
PGDATA: /data/postgres
volumes:
- ./data/db/tenant-1:/data/postgres
- ./tenant_1_data.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5433:5432"
restart: unless-stopped
Expand All @@ -45,9 +42,8 @@ services:
environment:
POSTGRES_USER: tenant-2-db
POSTGRES_PASSWORD: tenant-2-db
PGDATA: /data/postgres
volumes:
- ./data/db/tenant-2:/data/postgres
- ./tenant_2_data.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5434:5432"
restart: unless-stopped
1 change: 0 additions & 1 deletion init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,3 @@ CREATE TABLE tenants (
INSERT INTO tenants (slug, db_name, db_host, db_username, db_password, db_port) VALUES
('tenant1', 'tenant-1-db', 'tenant-1-db', 'tenant-1-db', 'tenant-1-db', 5433),
('tenant2', 'tenant-2-db', 'tenant-2-db', 'tenant-2-db', 'tenant-2-db', 5434);
view rawblock4.sql hosted with ❤ by GitHub
12 changes: 12 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import express from 'express';
import bodyParser from 'body-parser';
import * as userService from './services/users';
import { connectAllDb } from './infra/connectionManager';
import * as connectionResolver from './middlewares/connectionResolver';

const PORT = 8080;

Expand All @@ -15,3 +18,12 @@ app.get('/', (req, res) => {
app.listen(PORT, () => {
console.log(`Express server started at port: ${PORT}`);
});

app.use(bodyParser.json());

connectAllDb();

app.use(connectionResolver.resolve);

app.get('/users', userService.getAll);

53 changes: 53 additions & 0 deletions src/infra/connectionManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import knex from 'knex';

import commonDBConnection from './commonDBConnection';
import { getNamespace } from 'continuation-local-storage';

let connectionMap;

export const connectAllDb = async () => {
let tenants;
try {
tenants = await commonDBConnection.select('*').from('tenants');
} catch (e) {
console.log('error', e);
return;
}
connectionMap =
tenants
.map(tenant => {
return {
[tenant.slug]: knex(createConnectionConfig(tenant))
}
})
.reduce((prev, next) => {
return Object.assign({}, prev, next);
}, {});
}

const createConnectionConfig = (tenant) => {
return {
client: process.env.DB_CLIENT,
connection: {
host: tenant.db_host,
port: tenant.db_port,
user: tenant.db_username,
database: tenant.db_name,
password: tenant.db_password
},
pool: {min: 2, max: 20}
};
}

export const getConnectionBySlug = (slug) => {
return connectionMap ? connectionMap[slug] : null;
}

export const getConnection = () => {
const nameSpace = getNamespace('unique context');
const conn = nameSpace.get('connection');
if (!conn) {
throw 'Connection is not set for any tenant database.';
}
return conn;
}
19 changes: 19 additions & 0 deletions src/middlewares/connectionResolver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { createNamespace } from 'continuation-local-storage';

import { getConnectionBySlug } from '../infra/connectionManager';


let nameSpace = createNamespace('unique context');


export const resolve = (req, res, next) => {
const slug = req.query.slug;
if (!slug) {
res.json({ message: `Please provide tenant's slug to connect.` });
return;
}
nameSpace.run(() => {
nameSpace.set('connection', getConnectionBySlug(slug));
next();
});
}
5 changes: 5 additions & 0 deletions src/services/users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {getConnection} from '../infra/connectionManager';

export const getAll = async (req, res) => {
res.json({body: await getConnection().select('*').from('users')});
}
10 changes: 10 additions & 0 deletions tenant_1_data.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CREATE TABLE users(
id INT PRIMARY KEY,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
address VARCHAR(400)
);

INSERT INTO users(id,first_name, last_name, email, address) VALUES
(1,'Kevin', 'Martins', 'kevinmmartins@gmail.com', 'BR');
10 changes: 10 additions & 0 deletions tenant_2_data.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CREATE TABLE users(
id INT PRIMARY KEY,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
address VARCHAR(400)
);

INSERT INTO users(id,first_name, last_name, email, address) VALUES
(1,'Kauan', 'Martins', 'kauanmmartins@egmail.com', 'USA');

0 comments on commit 5351b56

Please sign in to comment.