Skip to content

Commit

Permalink
fix(oianalytics): send oibus info to oianalytics on engine name or ve…
Browse files Browse the repository at this point in the history
…rsion update
  • Loading branch information
burgerni10 committed Jun 10, 2024
1 parent fb5de79 commit 314f8ff
Show file tree
Hide file tree
Showing 24 changed files with 1,043 additions and 32 deletions.
35 changes: 35 additions & 0 deletions backend/src/db/entity-migrations/v3.3.7-add-oia-message.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Knex } from 'knex';
import { OIANALYTICS_MESSAGE_TABLE } from '../../repository/oianalytics-message.repository';
import { ENGINES_TABLE } from '../../repository/engine.repository';
import { version } from '../../../package.json';
import CreateTableBuilder = Knex.CreateTableBuilder;
import { OIANALYTICS_MESSAGE_STATUS } from '../../../../shared/model/oianalytics-message.model';

function createDefaultEntityFields(table: CreateTableBuilder): void {
table.uuid('id').primary();
table.timestamps(false, true);
}

export async function up(knex: Knex): Promise<void> {
await createOIAMessageTable(knex);
await addVersionInEngineSettings(knex);
}

async function createOIAMessageTable(knex: Knex): Promise<void> {
await knex.schema.createTable(OIANALYTICS_MESSAGE_TABLE, table => {
createDefaultEntityFields(table);
table.string('type').notNullable();
table.json('content').notNullable();
table.datetime('completed_date');
table.string('error');
table.enum('status', OIANALYTICS_MESSAGE_STATUS).notNullable().defaultTo('PENDING');
});
}

async function addVersionInEngineSettings(knex: Knex) {
await knex.schema.raw(`ALTER TABLE ${ENGINES_TABLE} ADD oibus_version NOT NULL DEFAULT "${version}"`);
}

export async function down(knex: Knex): Promise<void> {
await knex.schema.dropTable(OIANALYTICS_MESSAGE_TABLE);
}
14 changes: 13 additions & 1 deletion backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import HomeMetricsService from './service/home-metrics.service';
import CommandService from './service/oia/command.service';
import RegistrationService from './service/oia/registration.service';
import ProxyServer from './web-server/proxy-server';
import OIAnalyticsMessageService from './service/oia/message.service';

const CONFIG_DATABASE = 'oibus.db';
const CRYPTO_DATABASE = 'crypto.db';
Expand Down Expand Up @@ -107,7 +108,15 @@ const LOG_DB_NAME = 'logs.db';
loggerService.logger!
);

const commandService = new CommandService(repositoryService, encryptionService, loggerService.logger!, binaryFolder);
const oianalyticsMessageService = new OIAnalyticsMessageService(repositoryService, encryptionService, loggerService.logger!);
oianalyticsMessageService.start();
const commandService = new CommandService(
repositoryService,
encryptionService,
oianalyticsMessageService,
loggerService.logger!,
binaryFolder
);
commandService.start();

const oibusService = new OIBusService(engine, historyQueryEngine);
Expand Down Expand Up @@ -138,13 +147,15 @@ const LOG_DB_NAME = 'logs.db';
engine,
historyQueryEngine,
oibusService,
oianalyticsMessageService,
proxyServer
);

const registrationService = new RegistrationService(
repositoryService,
encryptionService,
commandService,
oianalyticsMessageService,
reloadService,
loggerService.logger!
);
Expand Down Expand Up @@ -172,6 +183,7 @@ const LOG_DB_NAME = 'logs.db';
stopping = true;
await oibusService.stopOIBus();
await commandService.stop();
await oianalyticsMessageService.stop();
await proxyServer.stop();
await server.stop();
registrationService.stop();
Expand Down
11 changes: 10 additions & 1 deletion backend/src/repository/engine.repository.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ describe('Non-empty Engine repository', () => {
id: 'id1',
name: 'OIBus',
port: 2223,
version: '3.3.3',
proxyEnabled: false,
proxyPort: 9000,
consoleLogLevel: 'silent',
Expand Down Expand Up @@ -188,6 +189,7 @@ describe('Non-empty Engine repository', () => {
id: 'id1',
name: 'OIBus',
port: 2223,
version: '3.3.3',
proxyEnabled: false,
proxyPort: 9000,
logParameters: {
Expand Down Expand Up @@ -218,7 +220,7 @@ describe('Non-empty Engine repository', () => {
};
const engineSettings = repository.getEngineSettings();
expect(database.prepare).toHaveBeenCalledWith(
'SELECT id, name, port, proxy_enabled AS proxyEnabled, proxy_port AS proxyPort, log_console_level AS consoleLogLevel, log_file_level AS fileLogLevel, ' +
'SELECT id, name, port, oibus_version AS version, proxy_enabled AS proxyEnabled, proxy_port AS proxyPort, log_console_level AS consoleLogLevel, log_file_level AS fileLogLevel, ' +
'log_file_max_file_size AS fileLogMaxFileSize, log_file_number_of_files AS fileLogNumberOfFiles, ' +
'log_database_level AS databaseLogLevel, log_database_max_number_of_logs AS databaseLogMaxNumberOfLogs, ' +
'log_loki_level AS lokiLogLevel, log_loki_interval AS lokiLogInterval, log_loki_address AS lokiLogAddress, ' +
Expand Down Expand Up @@ -264,4 +266,11 @@ describe('Non-empty Engine repository', () => {
repository.createEngineSettings(command);
expect(generateRandomId).not.toHaveBeenCalled();
});

it('should update version', () => {
repository.updateVersion('3.4.0');

expect(database.prepare).toHaveBeenCalledWith('UPDATE engines SET oibus_version = ? WHERE rowid=(SELECT MIN(rowid) FROM engines);');
expect(run).toHaveBeenCalledWith('3.4.0');
});
});
12 changes: 11 additions & 1 deletion backend/src/repository/engine.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default class EngineRepository {
*/
getEngineSettings(): EngineSettingsDTO | null {
const query =
'SELECT id, name, port, proxy_enabled AS proxyEnabled, proxy_port AS proxyPort, ' +
'SELECT id, name, port, oibus_version AS version, proxy_enabled AS proxyEnabled, proxy_port AS proxyPort, ' +
'log_console_level AS consoleLogLevel, ' +
'log_file_level AS fileLogLevel, ' +
'log_file_max_file_size AS fileLogMaxFileSize, ' +
Expand All @@ -75,6 +75,7 @@ export default class EngineRepository {
id: results[0].id,
name: results[0].name,
port: results[0].port,
version: results[0].version,
proxyEnabled: Boolean(results[0].proxyEnabled),
proxyPort: results[0].proxyPort,
logParameters: {
Expand Down Expand Up @@ -152,6 +153,15 @@ export default class EngineRepository {
);
}

/**
* Update OIBus version
*/
updateVersion(version: string): void {
const query = `UPDATE ${ENGINES_TABLE} SET oibus_version = ? WHERE rowid=(SELECT MIN(rowid) FROM ${ENGINES_TABLE});`;

this.database.prepare(query).run(version);
}

/**
* Create engine settings in the database.
*/
Expand Down
176 changes: 176 additions & 0 deletions backend/src/repository/oianalytics-message.repository.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import SqliteDatabaseMock, { all, get, run } from '../tests/__mocks__/database.mock';
import { Database } from 'better-sqlite3';
import OianalyticsMessageRepository from './oianalytics-message.repository';
import { Page } from '../../../shared/model/types';
import { InfoMessageContent, OIAnalyticsMessageCommand, OIAnalyticsMessageDTO } from '../../../shared/model/oianalytics-message.model';

jest.mock('../tests/__mocks__/database.mock');
jest.mock('../service/utils', () => ({
generateRandomId: jest.fn(() => '123456')
}));
const nowDateString = '2020-02-02T02:02:02.222Z';

const existingMessage: OIAnalyticsMessageDTO = {
id: '1234',
status: 'ERRORED',
type: 'INFO',
content: {} as InfoMessageContent
};

let database: Database;
let repository: OianalyticsMessageRepository;
describe('OIAnalytics Message repository', () => {
beforeEach(() => {
jest.clearAllMocks();
database = new SqliteDatabaseMock();
all.mockReturnValue([existingMessage]);
database.prepare = jest.fn().mockReturnValue({
run,
get,
all
});
repository = new OianalyticsMessageRepository(database);
});

it('should create message', () => {
run.mockReturnValueOnce({ lastInsertRowid: 1 });
get.mockReturnValueOnce({ ...existingMessage, content: '{}' });
const command: OIAnalyticsMessageCommand = {
type: 'INFO',
content: {} as InfoMessageContent
};
repository.createOIAnalyticsMessages(command);
expect(database.prepare).toHaveBeenCalledWith('INSERT INTO oianalytics_messages (id, type, status, content) VALUES (?, ?, ?, ?);');
expect(run).toHaveBeenCalledWith('123456', command.type, 'PENDING', JSON.stringify(command.content));
});

it('should update message', () => {
const command: OIAnalyticsMessageCommand = {
type: 'INFO',
content: {} as InfoMessageContent
};
repository.updateOIAnalyticsMessages('id', command);
expect(database.prepare).toHaveBeenCalledWith('UPDATE oianalytics_messages SET content = ? WHERE id = ?;');
expect(run).toHaveBeenCalledWith(JSON.stringify(command.content), 'id');
});

it('should properly get messages page by search criteria', () => {
const expectedValue: Page<OIAnalyticsMessageDTO> = {
content: [
{
id: '1234',
creationDate: '2023-01-01T00:00:00.000Z',
type: 'INFO',
status: 'PENDING',
content: {} as InfoMessageContent
},
{
id: '1234',
creationDate: '2024-01-01T00:00:00.000Z',
type: 'INFO',
status: 'ERRORED',
content: {} as InfoMessageContent
}
],
size: 50,
number: 0,
totalElements: 2,
totalPages: 1
};
all.mockReturnValueOnce([
{
id: '1234',
creationDate: '2023-01-01T00:00:00.000Z',
type: 'INFO',
status: 'PENDING',
content: '{}'
},
{
id: '1234',
creationDate: '2024-01-01T00:00:00.000Z',
type: 'INFO',
status: 'ERRORED',
content: '{}'
}
]);
get.mockReturnValueOnce({ count: 2 });
const logs = repository.searchMessagesPage(
{
types: ['INFO'],
status: ['PENDING', 'ERRORED'],
start: '2023-01-01T00:00:00.000Z',
end: '2023-01-02T00:00:00.000Z'
},
0
);
expect(database.prepare).toHaveBeenCalledWith(
'SELECT id, created_at as creationDate, completed_date as compeltedDate, type, status, error, content FROM oianalytics_messages WHERE id IS NOT NULL ' +
'AND type IN (?) AND status IN (?,?) AND created_at >= ? AND created_at <= ? ORDER BY created_at DESC LIMIT 50 OFFSET ?;'
);
expect(logs).toEqual(expectedValue);

expect(database.prepare).toHaveBeenCalledWith(
'SELECT COUNT(*) as count FROM oianalytics_messages WHERE id IS NOT NULL AND type IN (?) AND status IN (?,?) AND created_at >= ? AND created_at <= ?;'
);
});

it('should properly get messages list by search criteria', () => {
const expectedValue: Array<OIAnalyticsMessageDTO> = [
{
id: '1234',
creationDate: '2023-01-01T00:00:00.000Z',
type: 'INFO',
status: 'PENDING',
content: {} as InfoMessageContent
},
{
id: '1234',
creationDate: '2024-01-01T00:00:00.000Z',
type: 'INFO',
status: 'ERRORED',
content: {} as InfoMessageContent
}
];
all.mockReturnValueOnce([
{
id: '1234',
creationDate: '2023-01-01T00:00:00.000Z',
type: 'INFO',
status: 'PENDING',
content: '{}'
},
{
id: '1234',
creationDate: '2024-01-01T00:00:00.000Z',
type: 'INFO',
status: 'ERRORED',
content: '{}'
}
]);
const messages = repository.searchMessagesList({
types: ['INFO'],
status: ['PENDING', 'ERRORED'],
start: '2023-01-01T00:00:00.000Z',
end: '2023-01-02T00:00:00.000Z'
});
expect(database.prepare).toHaveBeenCalledWith(
'SELECT id, created_at as creationDate, completed_date as compeltedDate, type, status, error, content FROM oianalytics_messages WHERE id IS NOT NULL ' +
'AND type IN (?) AND status IN (?,?) AND created_at >= ? AND created_at <= ? ORDER BY created_at DESC;'
);
expect(messages).toEqual(expectedValue);
});

it('should mark a command as COMPLETED', () => {
repository.markAsCompleted('id1', nowDateString);
const query = `UPDATE oianalytics_messages SET status = 'COMPLETED', completed_date = ? WHERE id = ?;`;
expect(database.prepare).toHaveBeenCalledWith(query);
expect(run).toHaveBeenCalledWith(nowDateString, 'id1');
});

it('should mark a command as ERRORED', () => {
repository.markAsErrored('id1', nowDateString, 'not ok');
const query = `UPDATE oianalytics_messages SET status = 'ERRORED', completed_date = ?, error = ? WHERE id = ?;`;
expect(database.prepare).toHaveBeenCalledWith(query);
expect(run).toHaveBeenCalledWith(nowDateString, 'not ok', 'id1');
});
});

0 comments on commit 314f8ff

Please sign in to comment.