Vizzuality/landgriffon

View on GitHub
api/src/modules/api-events/api-events.service.ts

Summary

Maintainability
A
35 mins
Test Coverage
B
82%
import { Injectable, Logger, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { DeleteResult, Repository } from 'typeorm';
import {
  ApiEvent,
  apiEventResource,
  QualifiedEventTopic,
} from 'modules/api-events/api-event.entity';
import {
  ApiEventByTopicAndKind,
  LatestApiEventByTopicAndKind,
} from 'modules/api-events/api-event.topic+kind.entity';

import { isNil } from 'lodash';
import {
  AppBaseService,
  JSONAPISerializerConfig,
} from 'utils/app-base.service';
import { CreateApiEventDTO } from 'modules/api-events/dto/create.api-event.dto';
import { UpdateApiEventDTO } from 'modules/api-events/dto/update.api-event.dto';
import { AppInfoDTO } from 'dto/info.dto';

@Injectable()
/**
 * API Events
 */
export class ApiEventsService extends AppBaseService<
  ApiEvent,
  CreateApiEventDTO,
  UpdateApiEventDTO,
  AppInfoDTO
> {
  constructor(
    @InjectRepository(ApiEvent) readonly repo: Repository<ApiEvent>,
    @InjectRepository(LatestApiEventByTopicAndKind)
    readonly latestEventByTopicAndKindRepo: Repository<LatestApiEventByTopicAndKind>,
  ) {
    super(repo, apiEventResource.name.singular, apiEventResource.name.plural);
  }

  get serializerConfig(): JSONAPISerializerConfig<ApiEvent> {
    return {
      attributes: ['timestamp', 'topic', 'kind', 'data'],
      keyForAttribute: 'camelCase',
    };
  }

  /**
   * Given a `QualifiedEventTopic` (topic qualified by `kind` and `apiEvent`),
   * return the matching event with the latest timestamp.
   */
  public async getLatestEventForTopic(
    qualifiedTopic: QualifiedEventTopic,
  ): Promise<ApiEventByTopicAndKind | undefined> {
    const result: LatestApiEventByTopicAndKind | null =
      await this.latestEventByTopicAndKindRepo.findOne({
        where: { topic: qualifiedTopic.topic, kind: qualifiedTopic.kind },
      });
    if (!result) {
      throw new NotFoundException(
        `No events found for topic ${qualifiedTopic.topic} and kind ${qualifiedTopic.kind}.`,
      );
    }

    return result;
  }

  /**
   * Purge all events. Optionally this can be limited to events of a given
   * `QualifiedEventTopic` (i.e. a topic qualified by `kind` and `apiVersion`).
   */
  public async purgeAll(
    qualifiedTopic?: QualifiedEventTopic,
  ): Promise<DeleteResult> {
    if (!isNil(qualifiedTopic)) {
      this.logger.log(
        `Purging events for topic ${qualifiedTopic.topic}/${qualifiedTopic.kind}}`,
      );
      return this.repo.delete({
        topic: qualifiedTopic.topic,
        kind: qualifiedTopic.kind,
      });
    } else {
      this.logger.log(`Purging events`);
      await this.repo.clear();
      return new DeleteResult();
    }
  }
}