All files / service AuditsDataSourceService.ts

32.14% Statements 9/28
0% Branches 0/28
0% Functions 0/4
26.92% Lines 7/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72  3x 3x   3x 3x 3x 3x     3x                                                                                                                          
 
import { DynamoDBClient, PutItemCommand, ScanCommand } from "@aws-sdk/client-dynamodb"; // ES Modules 
import { marshall, unmarshall } from '@aws-sdk/util-dynamodb';
import { FlowAudit, Logger, LoggerFactory, PaginatedResults } from 'shared_types';
import { AppConfiguration } from 'src/common/configuration/AppConfiguration';
import RuleConfigError from "src/common/RuleConfigError";
import { inject, injectable } from 'tsyringe';
import { v4 as uuidv4 } from 'uuid';
type FlowAuditInput = Omit<FlowAudit, 'id'>;
@injectable()
export class AuditsDataSourceService {
 
    logger: Logger;
    auditTableName: string;
    constructor(@inject('LoggerFactory') loggerFactory: LoggerFactory,
        @inject('DynamoDBClient') private dynamoDBClient: DynamoDBClient,
        @inject('AppConfiguration') private appConfiguration: AppConfiguration,
    ) {
        this.logger = loggerFactory.getLogger('AuditsDataSourceService');
        this.auditTableName = this.appConfiguration.getDefinitionSourceFor('AUDIT')?.tableName ?? '';
    }
 
    public async getAudits(limit?: number, nextToken?: string): Promise<PaginatedResults<FlowAudit>> {
        this.logger.info(`Scanning table ${this.auditTableName} with ${limit} and nextToken ${nextToken}`);
        const scanTableCommand: ScanCommand = new ScanCommand(
            {
                TableName: this.auditTableName,
                ...(limit && { Limit: limit }),
                ...(nextToken && { ExclusiveStartKey: marshall({ id: nextToken }) })
            }
        );
        const response = await this.dynamoDBClient.send(scanTableCommand);
        const lastEvaluatedKey = response.LastEvaluatedKey?.id ? unmarshall(response.LastEvaluatedKey) : undefined;
        return {
            results: response.Items?.map(i => unmarshall(i) as FlowAudit) ?? [],
            ...(lastEvaluatedKey && { nextToken: lastEvaluatedKey['id'] })
        };
    }
 
    public async createAuditEntry(audit: FlowAuditInput): Promise<FlowAudit> {
        const id = uuidv4();
        this.logger.info(`Adding new audit record ${id} `);
        const input: FlowAudit = { ...audit, id: id, requestedTimestamp: new Date().toISOString() };
        const getItemCommand: PutItemCommand = new PutItemCommand(
            {
                Item: marshall(input),
                TableName: this.auditTableName,
                ConditionExpression: "attribute_not_exists(#id)",
                ExpressionAttributeNames: {
                    "#id": "id",
                },
            }
        );
        try {
            await this.dynamoDBClient.send(getItemCommand);
        } catch (error) {
            this.logger.error(
                'Error occurred when inserting a new object into database ',
                error
            );
            throw new RuleConfigError(
                'An error occurred when saving the new object',
                500,
                true
            );
        }
        return input;
    }
 
}