Skip to content

Commit

Permalink
Add datasource to rest for primary sql instance (#10153)
Browse files Browse the repository at this point in the history
* add datasource pointing to primary instance

---------

Signed-off-by: Jesse Nelson <[email protected]>
  • Loading branch information
jnels124 authored Jan 21, 2025
1 parent 0fe6957 commit 17133f5
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 28 deletions.
3 changes: 3 additions & 0 deletions charts/hedera-mirror/templates/secret-passwords.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ stringData:
HEDERA_MIRROR_REST_DB_HOST: "{{ $dbHost }}"
HEDERA_MIRROR_REST_DB_NAME: "{{ $dbName }}"
HEDERA_MIRROR_REST_DB_PASSWORD: "{{ $restPassword }}"
{{ if .Values.stackgres.enabled -}}
HEDERA_MIRROR_REST_DB_PRIMARYHOST: "{{ $dbHostPrimary }}"
{{- end }}
HEDERA_MIRROR_REST_DB_USERNAME: "{{ $restUsername }}"
HEDERA_MIRROR_RESTJAVA_DB_HOST: "{{ $dbHost }}"
HEDERA_MIRROR_RESTJAVA_DB_NAME: "{{ $dbName }}"
Expand Down
1 change: 1 addition & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ value, it is recommended to only populate overridden properties in the custom `a
| `hedera.mirror.rest.db.pool.maxConnections` | 10 | The maximum number of clients the database pool can contain |
| `hedera.mirror.rest.db.pool.statementTimeout` | 20000 | The number of milliseconds to wait before timing out a query statement |
| `hedera.mirror.rest.db.port` | 5432 | The port used to connect to the database |
| `hedera.mirror.rest.db.primaryHost` | "" | Optional IP or hostname used to connect to the primary instance |
| `hedera.mirror.rest.db.sslMode` | DISABLE | The ssl level of protection against Eavesdropping, Man-in-the-middle (MITM) and Impersonation on the db connection. Accepts either DISABLE, ALLOW, PREFER, REQUIRE, VERIFY_CA or VERIFY_FULL. |
| `hedera.mirror.rest.db.tls.ca` | "" | The path to the certificate authority used by the database for secure connections |
| `hedera.mirror.rest.db.tls.cert` | "" | The path to the public key the client should use to securely connect to the database |
Expand Down
1 change: 1 addition & 0 deletions hedera-mirror-rest/__tests__/integrationDbOps.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ const createPool = async () => {
password: readOnlyPassword,
user: readOnlyUser,
});
global.primaryPool = global.pool;
};

/**
Expand Down
1 change: 1 addition & 0 deletions hedera-mirror-rest/config/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ hedera:
maxConnections: 10
statementTimeout: 20000
port: 5432
primaryHost: ""
sslMode: DISABLE
tls:
ca: ""
Expand Down
63 changes: 63 additions & 0 deletions hedera-mirror-rest/dbpool.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (C) 2025 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import config from './config.js';
import fs from 'fs';
import {getPoolClass} from './utils.js';

const poolConfig = {
user: config.db.username,
host: config.db.host,
database: config.db.name,
password: config.db.password,
port: config.db.port,
connectionTimeoutMillis: config.db.pool.connectionTimeout,
max: config.db.pool.maxConnections,
statement_timeout: config.db.pool.statementTimeout,
};

if (config.db.tls.enabled) {
poolConfig.ssl = {
ca: fs.readFileSync(config.db.tls.ca).toString(),
cert: fs.readFileSync(config.db.tls.cert).toString(),
key: fs.readFileSync(config.db.tls.key).toString(),
rejectUnauthorized: false,
};
}

const Pool = getPoolClass();

const handlePoolError = (dbPool) => {
dbPool.on('error', (error) => {
logger.error(`error event emitted on pool for host ${dbPool.options.host}. ${error.stack}`);
});
};

const initializePool = () => {
global.pool = new Pool(poolConfig);
handlePoolError(global.pool);

if (config.db.primaryHost) {
const primaryPoolConfig = {...poolConfig};
primaryPoolConfig.host = config.db.primaryHost;
global.primaryPool = new Pool(primaryPoolConfig);
handlePoolError(global.primaryPool);
} else {
global.primaryPool = pool;
}
};

export {initializePool};
29 changes: 2 additions & 27 deletions hedera-mirror-rest/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import {createTerminus} from '@godaddy/terminus';
import {addAsync} from '@awaitjs/express';
import cors from 'cors';
import httpContext from 'express-http-context';
import fs from 'fs';
import compression from 'compression';

// local files
Expand Down Expand Up @@ -53,6 +52,7 @@ import {
// routes
import {AccountRoutes, BlockRoutes, ContractRoutes, NetworkRoutes} from './routes';
import {handleRejection, handleUncaughtException} from './middleware/httpErrorHandler';
import {initializePool} from './dbpool.js';

// use a dummy port for jest unit tests
const port = isTestEnv() ? 3000 : config.port;
Expand All @@ -62,32 +62,7 @@ if (port === undefined || Number.isNaN(Number(port))) {
}

// Postgres pool
const poolConfig = {
user: config.db.username,
host: config.db.host,
database: config.db.name,
password: config.db.password,
port: config.db.port,
connectionTimeoutMillis: config.db.pool.connectionTimeout,
max: config.db.pool.maxConnections,
statement_timeout: config.db.pool.statementTimeout,
};

if (config.db.tls.enabled) {
poolConfig.ssl = {
ca: fs.readFileSync(config.db.tls.ca).toString(),
cert: fs.readFileSync(config.db.tls.cert).toString(),
key: fs.readFileSync(config.db.tls.key).toString(),
rejectUnauthorized: false,
};
}

const Pool = getPoolClass();
const pool = new Pool(poolConfig);
pool.on('error', (error) => {
logger.error(`error event emitted on pg pool. ${error.stack}`);
});
global.pool = pool;
initializePool();

// Express configuration. Prior to v0.5 all sets should be configured before use or they won't be picked up
const app = addAsync(express());
Expand Down
6 changes: 5 additions & 1 deletion hedera-mirror-rest/service/baseService.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class BaseService {
}

async getRows(query, params) {
return (await pool.queryQuietly(query, params)).rows;
return (await this.pool().queryQuietly(query, params)).rows;
}

async getSingleRow(query, params) {
Expand Down Expand Up @@ -105,6 +105,10 @@ class BaseService {
limitClause,
].join('\n');
}

pool() {
return pool;
}
}

export default BaseService;
5 changes: 5 additions & 0 deletions hedera-mirror-rest/service/recordFileService.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ class RecordFileService extends BaseService {
order by ${filters.orderBy} ${filters.order}
limit ${filters.limit}
`;

const rows = await super.getRows(query, params);
return rows.map((recordFile) => new RecordFile(recordFile));
}
Expand Down Expand Up @@ -214,6 +215,10 @@ class RecordFileService extends BaseService {
order: orderFilterValues.ASC,
};
}

pool() {
return primaryPool;
}
}

export default new RecordFileService();

0 comments on commit 17133f5

Please sign in to comment.