172 lines
5.7 KiB
TypeScript
172 lines
5.7 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { InjectModel } from '@nestjs/mongoose';
|
|
import { readFileSync } from 'fs';
|
|
import * as yaml from 'js-yaml';
|
|
import { Model } from 'mongoose';
|
|
import { join } from 'path';
|
|
import { SemanticVersionDto } from 'src/versioning/dto/semanticversion.dto';
|
|
import { VersioningService } from '../versioning/versioning.service';
|
|
import { LoggingService } from 'src/logging/logging.service';
|
|
import { PerformanceDocument } from './models/performance.model';
|
|
|
|
const COMPONENT_NAME = 'performance';
|
|
|
|
enum UpdateReturnCodes {
|
|
Updated,
|
|
Ignored,
|
|
Failure,
|
|
}
|
|
|
|
@Injectable()
|
|
export class PerformanceService {
|
|
private static readPerformanceFile(): Record<string, any> {
|
|
return yaml.load(
|
|
readFileSync(join(process.cwd(), 'config/performance.yaml'), 'utf8'),
|
|
) as Record<string, any>;
|
|
}
|
|
|
|
private async updatePerformanceData(
|
|
performanceData: Record<string, any>,
|
|
version: SemanticVersionDto,
|
|
): Promise<string[]> {
|
|
return this.performanceModel.deleteMany({}).then(async () => {
|
|
const invalidEntries: string[] = [];
|
|
|
|
for (const key in performanceData) {
|
|
if (key !== 'FILEINFO') {
|
|
const validAircraft =
|
|
performanceData[key]['speedabovefl240'] !== undefined &&
|
|
performanceData[key]['rodabovefl240'] !== undefined &&
|
|
performanceData[key]['speedabovefl100'] !== undefined &&
|
|
performanceData[key]['rodabovefl100'] !== undefined &&
|
|
performanceData[key]['speedbelowfl100'] !== undefined &&
|
|
performanceData[key]['rodbelowfl100'] !== undefined &&
|
|
performanceData[key]['speedapproach'] !== undefined;
|
|
|
|
if (!validAircraft) {
|
|
invalidEntries.push(key);
|
|
} else {
|
|
await this.performanceModel.create({
|
|
icaoCode: key,
|
|
aboveFL240: {
|
|
speed: performanceData[key]['speedabovefl240'],
|
|
rateOfDescend: performanceData[key]['rodabovefl240'],
|
|
},
|
|
aboveFL100: {
|
|
speed: performanceData[key]['speedabovefl100'],
|
|
rateOfDescend: performanceData[key]['rodabovefl100'],
|
|
},
|
|
belowFL100: {
|
|
speed: performanceData[key]['speedbelowfl100'],
|
|
rateOfDescend: performanceData[key]['rodbelowfl100'],
|
|
},
|
|
minimalApproachSpeed: performanceData[key]['speedapproach'],
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
await this.versioningService.updateComponent(
|
|
COMPONENT_NAME,
|
|
performanceData['FILEINFO']['createdAt'],
|
|
version,
|
|
);
|
|
|
|
return invalidEntries;
|
|
});
|
|
}
|
|
|
|
private async validateAndUpdatePerformanceData(): Promise<{
|
|
status: UpdateReturnCodes;
|
|
ignored: string[];
|
|
}> {
|
|
// read the performance file and validate the version length
|
|
const data = PerformanceService.readPerformanceFile();
|
|
if (data['FILEINFO'] === undefined) {
|
|
this.loggingService.addInfoMessage(
|
|
COMPONENT_NAME,
|
|
`The fileinfo block is missing`,
|
|
);
|
|
return { status: UpdateReturnCodes.Failure, ignored: [] };
|
|
}
|
|
if (data['FILEINFO']['createdAt'] === undefined) {
|
|
this.loggingService.addInfoMessage(
|
|
COMPONENT_NAME,
|
|
`The createdAt of the fileinfo block is missing`,
|
|
);
|
|
return { status: UpdateReturnCodes.Failure, ignored: [] };
|
|
}
|
|
|
|
const versionParts = (data['FILEINFO']['version'] as string).split('.');
|
|
if (versionParts.length !== 3) {
|
|
this.loggingService.addInfoMessage(
|
|
COMPONENT_NAME,
|
|
`The version of fileinfo is missing or wrong: ${data['FILEINFO']['version']}. Expected: x.y.z`,
|
|
);
|
|
return { status: UpdateReturnCodes.Failure, ignored: [] };
|
|
}
|
|
|
|
// create the fileversion
|
|
const fileversion: SemanticVersionDto = {
|
|
main: parseInt(versionParts[0]),
|
|
major: parseInt(versionParts[1]),
|
|
minor: parseInt(versionParts[2]),
|
|
};
|
|
|
|
return this.versioningService
|
|
.findComponent(COMPONENT_NAME)
|
|
.then(async (resp) => {
|
|
if (
|
|
resp === null ||
|
|
VersioningService.newerVersion(
|
|
{
|
|
main: resp.versionMain,
|
|
major: resp.versionMajor,
|
|
minor: resp.versionMinor,
|
|
},
|
|
fileversion,
|
|
)
|
|
) {
|
|
return {
|
|
status: UpdateReturnCodes.Updated,
|
|
ignored: await this.updatePerformanceData(data, fileversion),
|
|
};
|
|
}
|
|
|
|
return { status: UpdateReturnCodes.Ignored, ignored: [] };
|
|
})
|
|
.catch(async () => ({
|
|
status: UpdateReturnCodes.Updated,
|
|
ignored: await this.updatePerformanceData(data, fileversion),
|
|
}));
|
|
}
|
|
|
|
constructor(
|
|
@InjectModel('performance')
|
|
private readonly performanceModel: Model<PerformanceDocument>,
|
|
private readonly versioningService: VersioningService,
|
|
private readonly loggingService: LoggingService,
|
|
) {
|
|
this.validateAndUpdatePerformanceData().then(async (response) => {
|
|
response.ignored.forEach(async (entry) => {
|
|
await this.loggingService.addInfoMessage(
|
|
COMPONENT_NAME,
|
|
`Ignored ${entry}. Required entries: speedabovefl240, rodabovefl240, speedabovefl100, rodabovefl100, speedbelowfl100, rodbelowfl100, speedapproach`,
|
|
);
|
|
});
|
|
|
|
if (response.status === UpdateReturnCodes.Ignored) {
|
|
await this.loggingService.addInfoMessage(
|
|
COMPONENT_NAME,
|
|
`Ignored the performance file due to the file version`,
|
|
);
|
|
} else if (response.status === UpdateReturnCodes.Failure) {
|
|
await this.loggingService.addInfoMessage(
|
|
COMPONENT_NAME,
|
|
`Wasn't able to update the performance database`,
|
|
);
|
|
}
|
|
});
|
|
}
|
|
}
|