mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
Refactor Redis, Postgres, and Clickhouse connection check methods
This commit is contained in:
@@ -16,65 +16,74 @@ import StatusServiceHandler from './Service/Status';
|
||||
import DataTypeServiceHandler from './Service/DataType';
|
||||
import Dictionary from 'Common/Types/Dictionary';
|
||||
import { StaticPath } from './Utils/Config';
|
||||
import FeatureSet from 'CommonServer/Types/FeatureSet';
|
||||
|
||||
const init: VoidFunction = () => {
|
||||
const ResourceDictionary: Dictionary<ModelDocumentation> =
|
||||
ResourceUtil.getResourceDictionaryByPath();
|
||||
const APIReferenceFeatureSet: FeatureSet = {
|
||||
init: async (): Promise<void> => {
|
||||
const ResourceDictionary: Dictionary<ModelDocumentation> =
|
||||
ResourceUtil.getResourceDictionaryByPath();
|
||||
|
||||
const app: ExpressApplication = Express.getExpressApp();
|
||||
const app: ExpressApplication = Express.getExpressApp();
|
||||
|
||||
app.use('/reference', ExpressStatic(StaticPath, { maxAge: 2592000 }));
|
||||
app.use('/reference', ExpressStatic(StaticPath, { maxAge: 2592000 }));
|
||||
|
||||
// Index page
|
||||
app.get(['/reference'], (_req: ExpressRequest, res: ExpressResponse) => {
|
||||
return res.redirect('/reference/introduction');
|
||||
});
|
||||
// Index page
|
||||
app.get(
|
||||
['/reference'],
|
||||
(_req: ExpressRequest, res: ExpressResponse) => {
|
||||
return res.redirect('/reference/introduction');
|
||||
}
|
||||
);
|
||||
|
||||
app.get(
|
||||
['/reference/page-not-found'],
|
||||
(req: ExpressRequest, res: ExpressResponse) => {
|
||||
return PageNotFoundServiceHandler.executeResponse(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
// All Pages
|
||||
app.get(
|
||||
['/reference/:page'],
|
||||
(req: ExpressRequest, res: ExpressResponse) => {
|
||||
const page: string | undefined = req.params['page'];
|
||||
|
||||
if (!page) {
|
||||
app.get(
|
||||
['/reference/page-not-found'],
|
||||
(req: ExpressRequest, res: ExpressResponse) => {
|
||||
return PageNotFoundServiceHandler.executeResponse(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
const currentResource: ModelDocumentation | undefined =
|
||||
ResourceDictionary[page];
|
||||
// All Pages
|
||||
app.get(
|
||||
['/reference/:page'],
|
||||
(req: ExpressRequest, res: ExpressResponse) => {
|
||||
const page: string | undefined = req.params['page'];
|
||||
|
||||
if (req.params['page'] === 'permissions') {
|
||||
return PermissionServiceHandler.executeResponse(req, res);
|
||||
} else if (req.params['page'] === 'authentication') {
|
||||
return AuthenticationServiceHandler.executeResponse(req, res);
|
||||
} else if (req.params['page'] === 'pagination') {
|
||||
return PaginationServiceHandler.executeResponse(req, res);
|
||||
} else if (req.params['page'] === 'errors') {
|
||||
return ErrorServiceHandler.executeResponse(req, res);
|
||||
} else if (req.params['page'] === 'introduction') {
|
||||
return IntroductionServiceHandler.executeResponse(req, res);
|
||||
} else if (req.params['page'] === 'status') {
|
||||
return StatusServiceHandler.executeResponse(req, res);
|
||||
} else if (req.params['page'] === 'data-types') {
|
||||
return DataTypeServiceHandler.executeResponse(req, res);
|
||||
} else if (currentResource) {
|
||||
return ModelServiceHandler.executeResponse(req, res);
|
||||
if (!page) {
|
||||
return PageNotFoundServiceHandler.executeResponse(req, res);
|
||||
}
|
||||
|
||||
const currentResource: ModelDocumentation | undefined =
|
||||
ResourceDictionary[page];
|
||||
|
||||
if (req.params['page'] === 'permissions') {
|
||||
return PermissionServiceHandler.executeResponse(req, res);
|
||||
} else if (req.params['page'] === 'authentication') {
|
||||
return AuthenticationServiceHandler.executeResponse(
|
||||
req,
|
||||
res
|
||||
);
|
||||
} else if (req.params['page'] === 'pagination') {
|
||||
return PaginationServiceHandler.executeResponse(req, res);
|
||||
} else if (req.params['page'] === 'errors') {
|
||||
return ErrorServiceHandler.executeResponse(req, res);
|
||||
} else if (req.params['page'] === 'introduction') {
|
||||
return IntroductionServiceHandler.executeResponse(req, res);
|
||||
} else if (req.params['page'] === 'status') {
|
||||
return StatusServiceHandler.executeResponse(req, res);
|
||||
} else if (req.params['page'] === 'data-types') {
|
||||
return DataTypeServiceHandler.executeResponse(req, res);
|
||||
} else if (currentResource) {
|
||||
return ModelServiceHandler.executeResponse(req, res);
|
||||
}
|
||||
// page not found
|
||||
return PageNotFoundServiceHandler.executeResponse(req, res);
|
||||
}
|
||||
// page not found
|
||||
return PageNotFoundServiceHandler.executeResponse(req, res);
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
app.get('/reference/*', (req: ExpressRequest, res: ExpressResponse) => {
|
||||
return PageNotFoundServiceHandler.executeResponse(req, res);
|
||||
});
|
||||
app.get('/reference/*', (req: ExpressRequest, res: ExpressResponse) => {
|
||||
return PageNotFoundServiceHandler.executeResponse(req, res);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default { init };
|
||||
export default APIReferenceFeatureSet;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,79 +10,84 @@ import DocsNav, { NavGroup, NavLink } from './Utils/Nav';
|
||||
import LocalFile from 'CommonServer/Utils/LocalFile';
|
||||
import DocsRender from './Utils/Render';
|
||||
import logger from 'CommonServer/Utils/Logger';
|
||||
import FeatureSet from 'CommonServer/Types/FeatureSet';
|
||||
|
||||
const init: VoidFunction = (): void => {
|
||||
const app: ExpressApplication = Express.getExpressApp();
|
||||
const DocsFeatureSet: FeatureSet = {
|
||||
init: async (): Promise<void> => {
|
||||
const app: ExpressApplication = Express.getExpressApp();
|
||||
|
||||
app.get('/docs', (_req: ExpressRequest, res: ExpressResponse) => {
|
||||
res.redirect('/docs/introduction/getting-started');
|
||||
});
|
||||
app.get('/docs', (_req: ExpressRequest, res: ExpressResponse) => {
|
||||
res.redirect('/docs/introduction/getting-started');
|
||||
});
|
||||
|
||||
app.get(
|
||||
'/docs/:categorypath/:pagepath',
|
||||
async (_req: ExpressRequest, res: ExpressResponse) => {
|
||||
try {
|
||||
const fullPath: string =
|
||||
`${_req.params['categorypath']}/${_req.params['pagepath']}`.toLowerCase();
|
||||
app.get(
|
||||
'/docs/:categorypath/:pagepath',
|
||||
async (_req: ExpressRequest, res: ExpressResponse) => {
|
||||
try {
|
||||
const fullPath: string =
|
||||
`${_req.params['categorypath']}/${_req.params['pagepath']}`.toLowerCase();
|
||||
|
||||
// read file from Content folder.
|
||||
let contentInMarkdown: string = await LocalFile.read(
|
||||
`${ContentPath}/${fullPath}.md`
|
||||
);
|
||||
// read file from Content folder.
|
||||
let contentInMarkdown: string = await LocalFile.read(
|
||||
`${ContentPath}/${fullPath}.md`
|
||||
);
|
||||
|
||||
// remove first line from content because we dont want to show title in content. Title is already in nav.
|
||||
// remove first line from content because we dont want to show title in content. Title is already in nav.
|
||||
|
||||
contentInMarkdown = contentInMarkdown
|
||||
.split('\n')
|
||||
.slice(1)
|
||||
.join('\n');
|
||||
contentInMarkdown = contentInMarkdown
|
||||
.split('\n')
|
||||
.slice(1)
|
||||
.join('\n');
|
||||
|
||||
const renderedContent: string = await DocsRender.render(
|
||||
contentInMarkdown
|
||||
);
|
||||
const renderedContent: string = await DocsRender.render(
|
||||
contentInMarkdown
|
||||
);
|
||||
|
||||
const currentCategory: NavGroup | undefined = DocsNav.find(
|
||||
(category: NavGroup) => {
|
||||
return category.links.find((link: NavLink) => {
|
||||
const currentCategory: NavGroup | undefined = DocsNav.find(
|
||||
(category: NavGroup) => {
|
||||
return category.links.find((link: NavLink) => {
|
||||
return link.url
|
||||
.toLocaleLowerCase()
|
||||
.includes(fullPath);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
const currrentNavLink: NavLink | undefined =
|
||||
currentCategory?.links.find((link: NavLink) => {
|
||||
return link.url
|
||||
.toLocaleLowerCase()
|
||||
.includes(fullPath);
|
||||
});
|
||||
|
||||
if (!currentCategory || !currrentNavLink) {
|
||||
// render not found.
|
||||
|
||||
res.status(404);
|
||||
return res.render(`${ViewsPath}/NotFound`, {
|
||||
nav: DocsNav,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
const currrentNavLink: NavLink | undefined =
|
||||
currentCategory?.links.find((link: NavLink) => {
|
||||
return link.url.toLocaleLowerCase().includes(fullPath);
|
||||
res.render(`${ViewsPath}/Index`, {
|
||||
nav: DocsNav,
|
||||
content: renderedContent,
|
||||
category: currentCategory,
|
||||
link: currrentNavLink,
|
||||
githubPath: fullPath,
|
||||
});
|
||||
|
||||
if (!currentCategory || !currrentNavLink) {
|
||||
// render not found.
|
||||
|
||||
res.status(404);
|
||||
return res.render(`${ViewsPath}/NotFound`, {
|
||||
} catch (err) {
|
||||
logger.error(err);
|
||||
res.status(500);
|
||||
return res.render(`${ViewsPath}/ServerError`, {
|
||||
nav: DocsNav,
|
||||
});
|
||||
}
|
||||
|
||||
res.render(`${ViewsPath}/Index`, {
|
||||
nav: DocsNav,
|
||||
content: renderedContent,
|
||||
category: currentCategory,
|
||||
link: currrentNavLink,
|
||||
githubPath: fullPath,
|
||||
});
|
||||
} catch (err) {
|
||||
logger.error(err);
|
||||
res.status(500);
|
||||
return res.render(`${ViewsPath}/ServerError`, {
|
||||
nav: DocsNav,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
app.use('/docs/static', ExpressStatic(StaticPath));
|
||||
app.use('/docs/static', ExpressStatic(StaticPath));
|
||||
},
|
||||
};
|
||||
|
||||
export default { init };
|
||||
export default DocsFeatureSet;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,25 +5,27 @@ import SsoAPI from './API/SSO';
|
||||
import ResellerAPI from './API/Reseller';
|
||||
import StatusPageSsoAPI from './API/StatusPageSSO';
|
||||
import StatusPageAuthenticationAPI from './API/StatusPageAuthentication';
|
||||
import { VoidFunction } from 'Common/Types/FunctionTypes';
|
||||
import FeatureSet from 'CommonServer/Types/FeatureSet';
|
||||
|
||||
const init: VoidFunction = () => {
|
||||
const app: ExpressApplication = Express.getExpressApp();
|
||||
const IdentityFeatureSet: FeatureSet = {
|
||||
init: async (): Promise<void> => {
|
||||
const app: ExpressApplication = Express.getExpressApp();
|
||||
|
||||
const APP_NAME: string = 'api/identity';
|
||||
const APP_NAME: string = 'api/identity';
|
||||
|
||||
app.use([`/${APP_NAME}`, '/'], AuthenticationAPI);
|
||||
app.use([`/${APP_NAME}`, '/'], AuthenticationAPI);
|
||||
|
||||
app.use([`/${APP_NAME}`, '/'], ResellerAPI);
|
||||
app.use([`/${APP_NAME}`, '/'], ResellerAPI);
|
||||
|
||||
app.use([`/${APP_NAME}`, '/'], SsoAPI);
|
||||
app.use([`/${APP_NAME}`, '/'], SsoAPI);
|
||||
|
||||
app.use([`/${APP_NAME}`, '/'], StatusPageSsoAPI);
|
||||
app.use([`/${APP_NAME}`, '/'], StatusPageSsoAPI);
|
||||
|
||||
app.use(
|
||||
[`/${APP_NAME}/status-page`, '/status-page'],
|
||||
StatusPageAuthenticationAPI
|
||||
);
|
||||
app.use(
|
||||
[`/${APP_NAME}/status-page`, '/status-page'],
|
||||
StatusPageAuthenticationAPI
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export default { init };
|
||||
export default IdentityFeatureSet;
|
||||
|
||||
@@ -7,15 +7,18 @@ import SmsAPI from './API/SMS';
|
||||
import CallAPI from './API/Call';
|
||||
import SMTPConfigAPI from './API/SMTPConfig';
|
||||
import './Utils/Handlebars';
|
||||
import FeatureSet from 'CommonServer/Types/FeatureSet';
|
||||
|
||||
const init: VoidFunction = () => {
|
||||
const APP_NAME: string = 'api/notification';
|
||||
const app: ExpressApplication = Express.getExpressApp();
|
||||
const NotificationFeatureSet: FeatureSet = {
|
||||
init: async (): Promise<void> => {
|
||||
const APP_NAME: string = 'api/notification';
|
||||
const app: ExpressApplication = Express.getExpressApp();
|
||||
|
||||
app.use([`/${APP_NAME}/email`, '/email'], MailAPI);
|
||||
app.use([`/${APP_NAME}/sms`, '/sms'], SmsAPI);
|
||||
app.use([`/${APP_NAME}/call`, '/call'], CallAPI);
|
||||
app.use([`/${APP_NAME}/smtp-config`, '/smtp-config'], SMTPConfigAPI);
|
||||
app.use([`/${APP_NAME}/email`, '/email'], MailAPI);
|
||||
app.use([`/${APP_NAME}/sms`, '/sms'], SmsAPI);
|
||||
app.use([`/${APP_NAME}/call`, '/call'], CallAPI);
|
||||
app.use([`/${APP_NAME}/smtp-config`, '/smtp-config'], SMTPConfigAPI);
|
||||
},
|
||||
};
|
||||
|
||||
export default { init };
|
||||
export default NotificationFeatureSet;
|
||||
|
||||
@@ -13,11 +13,14 @@ export default class ComponentCodeAPI {
|
||||
|
||||
public constructor() {
|
||||
this.router = Express.getRouter();
|
||||
}
|
||||
|
||||
public init(): void {
|
||||
// init all component code.
|
||||
/// Get all the components.
|
||||
for (const key in Components) {
|
||||
const ComponentCode: ComponentCode | undefined = Components[key];
|
||||
|
||||
if (ComponentCode instanceof TriggerCode) {
|
||||
const instance: TriggerCode = ComponentCode;
|
||||
instance
|
||||
|
||||
@@ -5,7 +5,7 @@ import Express, {
|
||||
} from 'CommonServer/Utils/Express';
|
||||
import logger from 'CommonServer/Utils/Logger';
|
||||
import ManualAPI from './API/Manual';
|
||||
import ComponentCode from './API/ComponentCode';
|
||||
import ComponentCodeAPI from './API/ComponentCode';
|
||||
import { QueueJob, QueueName } from 'CommonServer/Infrastructure/Queue';
|
||||
import QueueWorker from 'CommonServer/Infrastructure/QueueWorker';
|
||||
import RunWorkflow from './Services/RunWorkflow';
|
||||
@@ -16,27 +16,30 @@ import FeatureSet from 'CommonServer/Types/FeatureSet';
|
||||
|
||||
const APP_NAME: string = 'api/workflow';
|
||||
|
||||
const app: ExpressApplication = Express.getExpressApp();
|
||||
|
||||
app.use(`/${APP_NAME}/manual`, new ManualAPI().router);
|
||||
|
||||
app.use(`/${APP_NAME}`, new WorkflowAPI().router);
|
||||
|
||||
app.get(
|
||||
`/${APP_NAME}/docs/:componentName`,
|
||||
(req: ExpressRequest, res: ExpressResponse) => {
|
||||
res.sendFile(
|
||||
'/usr/src/app/FeatureSet/Workflow/Docs/ComponentDocumentation/' +
|
||||
req.params['componentName']
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
app.use(`/${APP_NAME}`, new ComponentCode().router);
|
||||
|
||||
const WorkflowFeatureSet: FeatureSet = {
|
||||
init: async (): Promise<void> => {
|
||||
try {
|
||||
const componentCodeAPI: ComponentCodeAPI = new ComponentCodeAPI();
|
||||
componentCodeAPI.init();
|
||||
|
||||
const app: ExpressApplication = Express.getExpressApp();
|
||||
|
||||
app.use(`/${APP_NAME}/manual`, new ManualAPI().router);
|
||||
|
||||
app.use(`/${APP_NAME}`, new WorkflowAPI().router);
|
||||
|
||||
app.get(
|
||||
`/${APP_NAME}/docs/:componentName`,
|
||||
(req: ExpressRequest, res: ExpressResponse) => {
|
||||
res.sendFile(
|
||||
'/usr/src/app/FeatureSet/Workflow/Docs/ComponentDocumentation/' +
|
||||
req.params['componentName']
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
app.use(`/${APP_NAME}`, componentCodeAPI.router);
|
||||
|
||||
// Job process.
|
||||
QueueWorker.getWorker(
|
||||
QueueName.Workflow,
|
||||
|
||||
@@ -98,6 +98,32 @@ export default class ClickhouseDatabase {
|
||||
this.dataSource = null;
|
||||
}
|
||||
}
|
||||
|
||||
public async checkConnnectionStatus(): Promise<boolean> {
|
||||
// Ping clickhouse to check if the connection is still alive
|
||||
try {
|
||||
const result: PingResult | undefined =
|
||||
await this.getDataSource()?.ping();
|
||||
|
||||
if (!result) {
|
||||
throw new DatabaseNotConnectedException(
|
||||
'Clickhouse Database is not connected'
|
||||
);
|
||||
}
|
||||
|
||||
if (result?.success === false) {
|
||||
throw new DatabaseNotConnectedException(
|
||||
'Clickhouse Database is not connected'
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
logger.error('Clickhouse Connection Lost');
|
||||
logger.error(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const ClickhouseAppInstance: ClickhouseDatabase =
|
||||
|
||||
@@ -71,6 +71,23 @@ export default class Database {
|
||||
this.dataSource = null;
|
||||
}
|
||||
}
|
||||
|
||||
public async checkConnnectionStatus(): Promise<boolean> {
|
||||
// check popstgres connection to see if it is still alive
|
||||
|
||||
try {
|
||||
await this.dataSource?.query(
|
||||
`SELECT COUNT(key) FROM ${
|
||||
this.getDatasourceOptions().database
|
||||
}.GreenlockChallenge`
|
||||
); // this is a dummy query to check if the connection is still alive
|
||||
return true;
|
||||
} catch (err) {
|
||||
logger.error('Postgres Connection Lost');
|
||||
logger.error(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const PostgresAppInstance: Database = new Database();
|
||||
|
||||
@@ -122,4 +122,16 @@ export default abstract class Redis {
|
||||
this.client = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static async checkConnnectionStatus(): Promise<boolean> {
|
||||
// Ping redis to check if the connection is still alive
|
||||
try {
|
||||
await this.client?.ping();
|
||||
return true;
|
||||
} catch (err) {
|
||||
logger.error('Redis Connection Lost');
|
||||
logger.error(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user