Источники данных couchdb добавлены в event-emitter

This commit is contained in:
Pavel Gnedov 2022-07-18 12:05:39 +07:00
parent d567bfc914
commit 562f50bd7d
11 changed files with 13448 additions and 5313 deletions

1
.gitignore vendored
View file

@ -34,3 +34,4 @@ lerna-debug.log*
!.vscode/launch.json !.vscode/launch.json
!.vscode/extensions.json !.vscode/extensions.json
configs/main-config.jsonc configs/main-config.jsonc
configs/issue-event-emitter-config.jsonc

View file

@ -0,0 +1,28 @@
import { Injectable, Logger } from '@nestjs/common';
import * as nano from 'nano';
import configuration from '../configs/main-config';
const config = configuration();
@Injectable()
export class CouchDb {
private static logger = new Logger(CouchDb.name);
private static couchdb: nano.ServerScope | null = null;
private static initialized = false;
static getCouchDb(): nano.ServerScope | null {
if (CouchDb.initialized) {
return CouchDb.couchdb;
}
CouchDb.initialized = true;
const url = config.couchDb?.url;
if (!url) {
return null;
} else {
const n = nano(url);
CouchDb.logger.log(`CouchDb connected by url ${url} ...`);
CouchDb.couchdb = n;
return n;
}
}
}

View file

@ -0,0 +1,33 @@
import { RedmineTypes } from '@app/redmine-types/index';
import { Injectable, Logger } from '@nestjs/common';
import configuration from '../configs/main-config';
import nano = require('nano');
import { CouchDb } from './couchdb';
const config = configuration();
@Injectable()
export class Issues {
private static logger = new Logger(Issues.name);
private static issuesDb = null;
private static initialized = false;
static async getDatasource(): Promise<nano.DocumentScope<RedmineTypes.Issue> | null> {
if (Issues.initialized) {
return Issues.issuesDb;
}
Issues.initialized = true;
const n = CouchDb.getCouchDb();
if (!n) {
return null;
}
const issueDbName = config.couchDb?.dbs.issues || 'issues';
const dbs = await n.db.list();
if (!dbs.includes(issueDbName)) {
await n.db.create(issueDbName);
}
Issues.issuesDb = await n.db.use(issueDbName);
Issues.logger.log(`Connected to issues db - ${issueDbName}`);
return Issues.issuesDb;
}
}

View file

@ -0,0 +1,33 @@
import { RedmineTypes } from '@app/redmine-types/index';
import { Injectable, Logger } from '@nestjs/common';
import nano from 'nano';
import { CouchDb } from './couchdb';
import configuration from '../configs/main-config';
const config = configuration();
@Injectable()
export class Users {
private static logger = new Logger(Users.name);
private static usersDb = null;
private static initialized = false;
static async getDatasource(): Promise<nano.DocumentScope<RedmineTypes.User> | null> {
if (Users.initialized) {
return Users.usersDb;
}
Users.initialized = true;
const n = CouchDb.getCouchDb();
if (!n) {
return null;
}
const usersDbName = config.couchDb?.dbs.users;
const dbs = await n.db.list();
if (!dbs.includes(usersDbName)) {
await n.db.create(usersDbName);
}
Users.usersDb = await n.db.use(usersDbName);
Users.logger.log(`Connected to users db - ${usersDbName}`);
return Users.usersDb;
}
}

View file

@ -7,11 +7,14 @@ import MainConfig from './configs/main-config';
import { ConfigModule } from '@nestjs/config'; import { ConfigModule } from '@nestjs/config';
import { RedmineDataLoader } from './redmine-data-loader/redmine-data-loader'; import { RedmineDataLoader } from './redmine-data-loader/redmine-data-loader';
import { MainController } from './main/main.controller'; import { MainController } from './main/main.controller';
import { MainConfigModel } from './models/main-config-model'; import { ModuleParams } from './models/module-params';
import { CouchDb } from './couchdb-datasources/couchdb';
import { Users } from './couchdb-datasources/users';
import { Issues } from './couchdb-datasources/issues';
@Module({}) @Module({})
export class EventEmitterModule { export class EventEmitterModule {
static register(params?: { config?: MainConfigModel }): DynamicModule { static register(params?: ModuleParams): DynamicModule {
return { return {
module: EventEmitterModule, module: EventEmitterModule,
imports: [ imports: [
@ -20,8 +23,22 @@ export class EventEmitterModule {
}), }),
ConfigModule.forRoot({ load: [() => params?.config || MainConfig()] }), ConfigModule.forRoot({ load: [() => params?.config || MainConfig()] }),
], ],
providers: [EventEmitterService, RedmineEventsGateway, RedmineDataLoader], providers: [
exports: [EventEmitterService, RedmineEventsGateway, RedmineDataLoader], EventEmitterService,
RedmineEventsGateway,
RedmineDataLoader,
CouchDb,
Users,
Issues,
],
exports: [
EventEmitterService,
RedmineEventsGateway,
RedmineDataLoader,
CouchDb,
Users,
Issues,
],
controllers: [MainController], controllers: [MainController],
}; };
} }

View file

@ -0,0 +1,5 @@
import { MainConfigModel } from './main-config-model';
export type ModuleParams = {
config?: MainConfigModel;
};

View file

@ -0,0 +1,9 @@
import { RedmineTypes } from 'libs/redmine-types';
// TODO: Переименовать в IssueCacheSaveResponse
export type SaveResponse = {
prev: RedmineTypes.Issue | null;
current: RedmineTypes.Issue;
journalsDiff: RedmineTypes.Journal[];
};

13288
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -28,6 +28,7 @@
"@nestjs/platform-socket.io": "^8.4.4", "@nestjs/platform-socket.io": "^8.4.4",
"@nestjs/serve-static": "^2.2.2", "@nestjs/serve-static": "^2.2.2",
"@nestjs/websockets": "^8.4.4", "@nestjs/websockets": "^8.4.4",
"axios": "^0.27.2",
"imap-simple": "^5.1.0", "imap-simple": "^5.1.0",
"nano": "^10.0.0", "nano": "^10.0.0",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",

View file

@ -1,9 +1,5 @@
import { EventEmitterModule } from '@app/event-emitter'; import { EventEmitterModule } from '@app/event-emitter';
import { MainController } from '@app/event-emitter/main/main.controller'; import { MainController } from '@app/event-emitter/main/main.controller';
import {
RedmineIssuesCacheWriterModule,
RedmineIssuesCacheWriterService,
} from '@app/redmine-issues-cache-writer';
import { Logger, Module, OnModuleInit } from '@nestjs/common'; import { Logger, Module, OnModuleInit } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config'; import { ConfigModule } from '@nestjs/config';
import { AppController } from './app.controller'; import { AppController } from './app.controller';
@ -11,24 +7,15 @@ import { AppService } from './app.service';
import { Issues } from './datasources/issues'; import { Issues } from './datasources/issues';
import configuration from './configs/app'; import configuration from './configs/app';
import { RedmineEventsGateway } from '@app/event-emitter/events/redmine-events.gateway'; import { RedmineEventsGateway } from '@app/event-emitter/events/redmine-events.gateway';
import { RedmineTypes } from '@app/redmine-types/index';
import { CouchDb } from './datasources/couchdb'; import { CouchDb } from './datasources/couchdb';
import { Users } from './datasources/users'; import { Users } from './datasources/users';
import { RedmineDataLoaderModule } from '@app/redmine-data-loader';
@Module({ @Module({
imports: [ imports: [
EventEmitterModule.register({ EventEmitterModule.register({
config: configuration().redmineIssueEventEmitterConfig, config: configuration().redmineIssueEventEmitterConfig,
}), }),
RedmineIssuesCacheWriterModule.register({
issueDocumentScopeProvider: Issues.getDatasource,
}),
ConfigModule.forRoot({ load: [configuration] }), ConfigModule.forRoot({ load: [configuration] }),
RedmineDataLoaderModule.register({
issueDocumentScopeProvider: Issues.getDatasource,
userDocumentScopeProvider: Users.getDatasource,
}),
], ],
controllers: [AppController, MainController], controllers: [AppController, MainController],
providers: [AppService, Issues, CouchDb, Users], providers: [AppService, Issues, CouchDb, Users],
@ -36,38 +23,35 @@ import { RedmineDataLoaderModule } from '@app/redmine-data-loader';
export class AppModule implements OnModuleInit { export class AppModule implements OnModuleInit {
private logger = new Logger(AppModule.name); private logger = new Logger(AppModule.name);
constructor( constructor(private redmineEventsGateway: RedmineEventsGateway) {}
private redmineEventsGateway: RedmineEventsGateway,
private redmineIssuesCacheWriterService: RedmineIssuesCacheWriterService,
) {}
onModuleInit() { onModuleInit() {
const queue = this.redmineEventsGateway.getIssuesChangesQueue(); // const queue = this.redmineEventsGateway.getIssuesChangesQueue();
const subj = queue.queue; // const subj = queue.queue;
subj.subscribe(async (issues: any) => { // subj.subscribe(async (issues: any) => {
this.logger.debug(`Changed issues = ${JSON.stringify(issues)}`); // this.logger.debug(`Changed issues = ${JSON.stringify(issues)}`);
//
for (let i = 0; i < issues.length; i++) { // for (let i = 0; i < issues.length; i++) {
const issue: RedmineTypes.Issue = issues[i]; // const issue: RedmineTypes.Issue = issues[i];
//
try { // try {
this.logger.debug( // this.logger.debug(
`Save issue #${issue.id} - ${JSON.stringify(issue)}`, // `Save issue #${issue.id} - ${JSON.stringify(issue)}`,
); // );
//
const response = await this.redmineIssuesCacheWriterService.saveIssue( // const response = await this.redmineIssuesCacheWriterService.saveIssue(
issue, // issue,
); // );
//
this.logger.debug( // this.logger.debug(
`Save issue #${issue.id} response = ${JSON.stringify(response)}`, // `Save issue #${issue.id} response = ${JSON.stringify(response)}`,
); // );
} catch (ex) { // } catch (ex) {
this.logger.error(`Saving issue error - ${ex}`, null, { // this.logger.error(`Saving issue error - ${ex}`, null, {
issue: issue, // issue: issue,
}); // });
} // }
} // }
}); // });
} }
} }

5264
yarn.lock

File diff suppressed because it is too large Load diff