Skip to content
This repository was archived by the owner on Jan 14, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 3 additions & 14 deletions app/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const { databaseService } = require('./lib/database/DatabaseService.js');

// Server
const { webUiServer } = require('./lib/server/WebUiServer.js');
const { isInDevMode, isInTestMode } = require('./lib/utils/env-utils.js');

// Extract important
const EP = config.public.endpoints;
Expand Down Expand Up @@ -53,8 +54,8 @@ class RunConditionTableApplication {

httpServer.post(EP.login, (req, res) => databaseService.loginSession(req, res));
httpServer.post(EP.logout, (req, res) => databaseService.logoutSession(req, res));
httpServer.get(EP.rctData, (req, res) => databaseService.pgExecFetchData(req, res));
httpServer.post(EP.insertData, (req, res) => databaseService.pgExecDataInsert(req, res));
httpServer.get(EP.rctData, (req, res) => databaseService.pgExecFetchData(req, res), { public: isInDevMode() || isInTestMode() });
httpServer.post(EP.insertData, (req, res) => databaseService.pgExecDataInsert(req, res), { public: isInDevMode() || isInTestMode() });
httpServer.get(EP.sync, async (_req, _res) => this.syncManager.syncAll());
}

Expand Down Expand Up @@ -94,18 +95,6 @@ class RunConditionTableApplication {
}
}

static isInTestMode() {
return process.env.ENV_MODE === 'test';
}

static isInDevMode() {
return process.env.ENV_MODE === 'dev';
}

static getEnvMode() {
return process.env.ENV_MODE;
}

get httpServer() {
return this.webUiServer.httpServer;
}
Expand Down
39 changes: 24 additions & 15 deletions app/lib/database/DatabaseService.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const { Log } = require('@aliceo2/web-ui');
const { Pool } = require('pg');
const { PGQueryBuilder } = require('./utilities');
const config = require('./../config/configProvider.js');
const {distinct} = require('../utils')
const {distinct, isInDevMode, isInTestMode} = require('../utils')

const DRP = config.public.dataReqParams;
const DRF = config.public.dataResponseFields;
Expand Down Expand Up @@ -106,13 +106,9 @@ class DatabaseService {
}

async pgExecFetchData(req, res) {
const userData = this.loggedUsers.tokenToUserData[req.query.token];
if (!userData) {
const mess = 'SESSION_ERROR:: no user with such token';
this.logger.error(mess, req.query);
this.responseWithStatus(res, 400, mess);
if (!this.checkToken(req, res)) {
return;
}
};

const params = {...req.query, ...req.params}

Expand Down Expand Up @@ -140,30 +136,32 @@ class DatabaseService {

const dbResErrorHandler = (e) => {
this.logger.error(e.message + ' :: ' + e.stack)
this.responseWithStatus(res, 500, e.code);
this.responseWithStatus(res, 400, e.message);
}

try {
const query = PGQueryBuilder.buildSelect(params);
await this.pgExec(query, connectErrorHandler, dbResponseHandler, dbResErrorHandler);
} catch (e) {
this.logger.error(e.stack)
this.responseWithStatus(res, 400, e)
this.logger.error(e.message + " :: " + e.stack)
this.responseWithStatus(res, 500)
}
}


async pgExecDataInsert(req, res) {
this.checkToken(req, res);
if (!this.checkToken(req, res)) {
return;
};
const dbResponseHandler = (dbRes) => {
return res.json({data: dbRes})
}
const dbResErrorHandler = (e) => {
this.logger.error(e.message + ' :: ' + e.stack)
this.responseWithStatus(res, 500, e.code);
this.responseWithStatus(res, 400, e.message);
}
const connectErrorHandler = (connectErr) => {
this.logger.error('Error acquiring client:: ' + connectErr.stack)
this.logger.error('Error acquiring client:: ' + connectErr.message)
this.responseWithStatus(res, 500, connectErr.message);
}

Expand All @@ -174,9 +172,20 @@ class DatabaseService {
dbResponseHandler,
dbResErrorHandler);
} catch (e) {
this.logger.error(e.stack)
this.responseWithStatus(res, 400, e)
this.logger.error(e.message + ' :: ' + e.stack)
this.responseWithStatus(res, 400, e.message)
}
}

checkToken(req, res) {
const userData = this.loggedUsers.tokenToUserData[req.query.token];
if (!userData && !(isInDevMode() || isInTestMode())) {
const mess = 'SESSION_ERROR:: no user with such token';
this.logger.error(mess, req.query);
this.responseWithStatus(res, 400, mess);
return false;
}
return true;
}

responseWithStatus(res, status, message) {
Expand Down
4 changes: 3 additions & 1 deletion app/lib/database/utilities/PGQueryBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pageToViewName[PN.anchoragePerDatapass] = 'anchorage_per_data_pass_view'
pageToViewName[PN.mc] = 'mc_view'
pageToViewName[PN.anchoredPerMC] = 'anchored_per_mc_view'
pageToViewName[PN.flags] = 'flags_view'

const DEFUALT_LIMIT=50;
/**
* Class responsible for parsing url params, payloads of client request to sql queries
*/
Expand Down Expand Up @@ -113,7 +115,7 @@ class PGQueryBuilder {

static buildSelect(params) {
const dataSubsetQueryPart = (params) => params[DRP.countRecords] === 'true' ? '' :
`LIMIT ${params[DRP.itemsPerPage]} OFFSET ${params[DRP.itemsPerPage] * (params[DRP.pageNumber] - 1)}`;
`LIMIT ${params[DRP.itemsPerPage] || DEFUALT_LIMIT} OFFSET ${params[DRP.itemsPerPage] * (params[DRP.pageNumber] - 1) || 1}`;

const orderingPart = (params) => {
if (!params['sorting']) {
Expand Down
3 changes: 2 additions & 1 deletion app/lib/server/routers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const dataPassRouter = require('./dataPass.router.js');
const docsRouter = require('./docs.router.js');
const simulationPassRouter = require('./simulationPass.router.js');
const qualityControlRouter = require('./qualityControl.router.js');
const { isInDevMode, isInTestMode } = require('../../utils');

const routeTrees = [
docsRouter,
Expand All @@ -45,7 +46,7 @@ function buildRoute(controllerTree) {

const { method, controller, description } = constrollerSubtree;
if (constrollerSubtree.method && constrollerSubtree.controller) {
if (process.env.ENV_MODE === 'test' || process.env.ENV_MODE === 'dev') {
if (isInDevMode() || isInTestMode()) {
args.public = true;
}
routesStack.push({ method, path, controller: controllerHandlerWrapper(controller), args, description });
Expand Down
42 changes: 42 additions & 0 deletions app/lib/utils/env-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
*
* @license
* Copyright 2019-2020 CERN and copyright holders of ALICE O2.
* See http://alice-o2.web.cern.ch/copyright for details of the copyright holders.
* All rights not expressly granted are reserved.
*
* This software is distributed under the terms of the GNU General Public
* License v3 (GPL Version 3), copied verbatim in the file "COPYING".
*
* In applying this license CERN does not waive the privileges and immunities
* granted to it by virtue of its status as an Intergovernmental Organization
* or submit itself to any jurisdiction.
*/

function isInTestMode() {
return process.env.ENV_MODE === 'test';
}

function isInDevMode() {
return process.env.ENV_MODE === 'dev';
}

function getEnvMode() {
return process.env.ENV_MODE;
}

function getRunningEnv() {
return process.env.RUNNING_ENV;
}

function runsOnDocker() {
return getRunningEnv === 'DOCKER';
}

module.exports = {
isInDevMode,
isInTestMode,
getEnvMode,
getRunningEnv,
runsOnDocker,
};
2 changes: 2 additions & 0 deletions app/lib/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const sqlUtils = require('./sql-utils.js');
const errors = require('./errors.js');
const deepmerge = require('./deepmerge.js');
const adaptFindAndCountAllInService = require('./adaptFindAndCountAllInService.js');
const envUtils = require('./env-utils.js');

module.exports = {
ResProvider,
Expand All @@ -29,4 +30,5 @@ module.exports = {
...errors,
...deepmerge,
...adaptFindAndCountAllInService,
...envUtils,
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"start:dev:local": "(export RCT_DB_HOST=${RCT_DB_HOST:-localhost}; bash -c 'set -o allexport && ls && source ./docker/dev.env && set +o allexport && npm run start:dev')",
"deploy:db:local": "./database/setup-db.sh --env ./docker/dev.env",
"dev": "./rctmake rm,run,app:attach,stop --target dev",
"idev": "node -e \"app = require('./app/application.js'); const { databaseManager: dbm, syncManager: scm } = app\" -i",
"idev": "node -e \"app = require('./app/application.js'); const { databaseManager: dbm, syncManager: scm } = app; const cfg = require('./app/config');\" -i",
"node-dev-env": "(export RCT_DB_HOST=$(docker inspect o2rct_database-dev -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'); bash -c 'set -o allexport && ls && source ./docker/dev.env && set +o allexport && node')",
"test": "./rctmake rm,run --target test",
"rm": "./rctmake rm",
Expand Down
25 changes: 24 additions & 1 deletion test/lib/server/routes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const responseSchema = Joi.object({
data: Joi.array().required(),
});

const getSelfLink = () => `${config.http.tls ? 'https' : 'http'}://localhost:${config.http.port}`;

module.exports = () => {
describe('WebUiServerSuite', () => {
describe('Routes definitions', () => {
Expand All @@ -44,7 +46,7 @@ module.exports = () => {
describe('Endpoints for fetching data', () => {
routes.filter(({ method }) => method === 'get').map(async ({ path }) => {
// eslint-disable-next-line max-len
const url = new URL(`${config.http.tls ? 'https' : 'http'}://localhost:${config.http.port}/api${replaceAll(path, /:[^/]+/, '0')}`);
const url = new URL(`${getSelfLink()}/api${replaceAll(path, /:[^/]+/, '0')}`);
it(`should fetch from ${path} <${url}> without errors`, async () => {
await assert.doesNotReject(makeHttpRequestForJSON(url));
});
Expand All @@ -62,5 +64,26 @@ module.exports = () => {
}
});
});

describe('Legacy endpoints for fetching data', () => {
const params = {
periods: {},
dataPasses: { index: 'LHC22o' },
mc: { index: 'LHC22o' },
anchoredPerMC: { index: 'LHC22h1c2' },
anchoragePerDatapass: { index: 'LHC22t_apass4' },
runsPerPeriod: { index: 'LHC22t' },
runsPerDataPass: { index: 'LHC22t_apass4' },
flags: { run_numbers: 123456, detector: 'CPV', data_pass_name: 'LHC22t_apass4' },
};
Object.entries(params).map(([pageKey, seachQueryParams]) => {
const url = new URL(`${getSelfLink()}/api${config.public.endpoints.rctData}?page=${config.public.pageNames[pageKey]}`);
Object.entries(seachQueryParams).forEach(([k, v]) => url.searchParams.set(k, v));

it(`should fetch from legacy endpoint ${url} without errors`, async () => {
await assert.doesNotReject(makeHttpRequestForJSON(url));
});
});
});
});
};