Skip to content
This repository has been archived by the owner on Mar 14, 2024. It is now read-only.

Commit

Permalink
get module imports and dependencies aligned so that system starts
Browse files Browse the repository at this point in the history
  • Loading branch information
sleidig committed Feb 14, 2024
1 parent d52272a commit 56199d8
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 17 deletions.
4 changes: 3 additions & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
SENTRY_DSN=
PORT=
DATABASE_URL=http://127.0.0.1:5984
DATABASE_ADMIN=admin
DATABASE_USER=admin
DATABASE_PASSWORD=admin
QUERY_URL=http://127.0.0.1:4984
SCHEMA_CONFIG_ID=_design/sqlite:config
REPORT_DATABASE_URL=http://127.0.0.1:5984
REPORT_DATABASE_NAME=app
13 changes: 7 additions & 6 deletions src/couchdb/couch-db-client.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ import { Injectable, Logger } from '@nestjs/common';
import { catchError, map, Observable, of, switchMap } from 'rxjs';
import { HttpService } from '@nestjs/axios';
import { AxiosHeaders } from 'axios';
import { CouchDbChangesResponse } from "./dtos";
import { CouchDbChangesResponse } from './dtos';

@Injectable()
@Injectable({})
export class CouchDbClient {
private readonly logger = new Logger(CouchDbClient.name);

constructor(private httpService: HttpService) {
}
constructor(private httpService: HttpService) {}

headDatabaseDocument(
databaseUrl: string,
Expand Down Expand Up @@ -121,14 +120,16 @@ export class CouchDbClient {
this.logger.debug(err);
}


changes(
databaseUrl: string,
databaseName: string,
config?: any,
): Observable<CouchDbChangesResponse> {
return this.httpService
.get<CouchDbChangesResponse>(`${databaseUrl}/${databaseName}/_changes`, config)
.get<CouchDbChangesResponse>(
`${databaseUrl}/${databaseName}/_changes`,
config,
)
.pipe(
map((response) => {
return response.data;
Expand Down
1 change: 1 addition & 0 deletions src/notification/notification.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import { NotificationService } from './core/notification.service';

@Module({
providers: [NotificationService],
exports: [NotificationService],
})
export class NotificationModule {}
13 changes: 6 additions & 7 deletions src/report-changes/core/couchdb-report-changes.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,26 @@ import { NotificationService } from '../../notification/core/notification.servic
import { Reference } from '../../domain/reference';
import { ReportDataChangeEvent } from '../../domain/report-data-change-event';
import { ReportCalculation } from '../../domain/report-calculation';
import { CouchDbClient } from '../../couchdb/couch-db-client.service';
import {
CouchDbChangeResult,
CouchDbChangesResponse,
} from '../../couchdb/dtos';
import { Report } from '../../domain/report';
import { ReportChangesService } from './report-changes.service';
import { ReportStorage } from '../../report/core/report-storage';
import { CouchdbChangesRepositoryService } from '../repository/couchdb-changes-repository.service';
import { DefaultReportStorage } from '../../report/storage/report-storage.service';

@Injectable()
export class CouchdbReportChangesService implements ReportChangesService {
private reportMonitors = new Map<string, ReportChangeDetector>();

constructor(
private notificationService: NotificationService,
private reportStorage: ReportStorage,
private couchDbClient: CouchDbClient,
private reportStorage: DefaultReportStorage,
private couchdbChangesRepository: CouchdbChangesRepositoryService,
) {
// (!) TODO: where to get databaseUrl and databaseName from? Can we centralize this ...?
this.couchDbClient
.changes('TODO', 'app')
this.couchdbChangesRepository
.fetchChanges()
.subscribe((changes: CouchDbChangesResponse) => {
// TODO: ensure continued fetching until all changes done
// TODO: collect a batch of changes for a while before checking?
Expand Down
1 change: 0 additions & 1 deletion src/report-changes/core/report-changes.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/**
* Monitor all changes to the application database and check if they affect any report's results.
*/

export interface ReportChangesService {}
13 changes: 12 additions & 1 deletion src/report-changes/report-changes.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import { Module } from '@nestjs/common';
import { CouchdbReportChangesService } from './core/couchdb-report-changes.service';
import { CouchdbChangesRepositoryService } from './repository/couchdb-changes-repository.service';
import { NotificationModule } from '../notification/notification.module';
import { ReportModule } from '../report/report.module';
import { CouchDbClient } from '../couchdb/couch-db-client.service';
import { HttpModule } from '@nestjs/axios';

@Module({
providers: [CouchdbReportChangesService],
imports: [NotificationModule, ReportModule, HttpModule],
providers: [
CouchdbReportChangesService,
CouchdbChangesRepositoryService,
CouchDbClient, // TODO: pack this into a CouchDbModule together with HttpModule import etc.
],
exports: [CouchdbReportChangesService],
})
export class ReportChangesModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Test, TestingModule } from '@nestjs/testing';
import { CouchdbChangesRepositoryService } from './couchdb-changes-repository.service';
import { HttpModule } from '@nestjs/axios';
import { ConfigService } from '@nestjs/config';

describe('CouchdbChangesRepositoryService', () => {
let service: CouchdbChangesRepositoryService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [HttpModule],
providers: [
CouchdbChangesRepositoryService,
{
provide: ConfigService,
useValue: {
getOrThrow: jest.fn((key) => {
return 'foo';
}),
},
},
],
}).compile();

service = module.get<CouchdbChangesRepositoryService>(
CouchdbChangesRepositoryService,
);
});

it('should be defined', () => {
expect(service).toBeDefined();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {
ForbiddenException,
Injectable,
NotFoundException,
UnauthorizedException,
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { catchError, Observable } from 'rxjs';
import { CouchDbClient } from '../../couchdb/couch-db-client.service';
import { CouchDbChangesResponse } from '../../couchdb/dtos';

@Injectable()
export class CouchdbChangesRepositoryService {
// TODO: centralize this config by refactoring couchdbClient and providing configured clients through DI
// TODO: check if this is the correct db for our changes from app
private dbUrl: string = this.configService.getOrThrow('DATABASE_URL');
private databaseName: string = 'app'; // TODO: move to config and clean up .env, clarifying different DBs there
private databaseUser: string = this.configService.getOrThrow('DATABASE_USER');
private databasePassword: string =
this.configService.getOrThrow('DATABASE_PASSWORD');

private authHeaderValue: string;

constructor(
private couchdbClient: CouchDbClient,
private configService: ConfigService,
) {
const authHeader = Buffer.from(
`${this.databaseUser}:${this.databasePassword}`,
).toString('base64');
this.authHeaderValue = `Basic ${authHeader}`;
}

fetchChanges(): Observable<CouchDbChangesResponse> {
return this.couchdbClient
.changes(this.dbUrl, this.databaseName, {
headers: {
Authorization: this.authHeaderValue,
},
})
.pipe(
catchError((err, caught) => {
this.handleError(err);
throw caught;
}),
);
}

private handleError(err: any) {
if (err.response.status === 401) {
throw new UnauthorizedException();
}
if (err.response.status === 403) {
throw new ForbiddenException();
}
if (err.response.status === 404) {
throw new NotFoundException();
}
}
}
3 changes: 2 additions & 1 deletion src/report/controller/report.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ export class ReportController {
): Observable<ReportDto> {
return this.reportStorage
.fetchReport(new Reference(reportId), token)
.pipe(switchMap((report) => this.getReportDto(report)));
.pipe(switchMap((report) => this.getReportDto(report as any))); // TODO: fix for undefined report
}

private getReportDto(report: Report): Observable<ReportDto> {
return this.reportStorage
.isCalculationOngoing(new Reference(report.id))
Expand Down
1 change: 1 addition & 0 deletions src/report/report.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ import { CouchDbClient } from '../couchdb/couch-db-client.service';
SqsReportCalculator,
CouchDbClient,
],
exports: [DefaultReportStorage],
})
export class ReportModule {}

0 comments on commit 56199d8

Please sign in to comment.