summaryrefslogtreecommitdiff
path: root/Homework/cs5260/consumer/dao/S3WidgetDao.ts
blob: d5aee727cd5993c03d20b590e450b8d3b6d906d7 (plain) (blame)
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import { WidgetT, Widget } from "@/shared/schema";
import { WidgetDAO } from ".";
import {
  DeleteObjectCommand,
  GetObjectCommand,
  NoSuchKey,
  PutObjectCommand,
  S3Client,
} from "@aws-sdk/client-s3";
import { S3WidgetKeyGenerator } from "./keys";
import { TracingLogger } from "@/consumer/log";

export class S3WidgetDAO implements WidgetDAO {
  private bucket: string;
  private s3Client: S3Client;
  private widgetKeyGenerator: S3WidgetKeyGenerator;
  private logger: TracingLogger;

  constructor(
    bucket: string,
    s3Client: S3Client,
    widgetKeyGenerator: S3WidgetKeyGenerator,
    logger: TracingLogger
  ) {
    this.bucket = bucket;
    this.s3Client = s3Client;
    this.widgetKeyGenerator = widgetKeyGenerator;
    this.logger = logger;
  }

  public async retrieve(widget: WidgetT) {
    const key = this.widgetKeyGenerator.fromWidget(widget);

    this.logger.info(
      `getting Widget=(${widget.id}) in Bucket=(${this.bucket})`
    );

    const retrievalRequest = new GetObjectCommand({
      Bucket: this.bucket,
      Key: key,
    });

    try {
      const objectResp = await this.s3Client.send(retrievalRequest);
      const textRepr = await objectResp.Body?.transformToString();

      if (textRepr) {
        this.logger.info(`retrieved WidgetObject=(${widget.id}) from S3`);
        return Widget.parse(JSON.parse(textRepr));
      }
    } catch (e: unknown) {
      if (e instanceof NoSuchKey) {
        return;
      }
      throw e;
    }
  }

  public async save(widget: WidgetT) {
    const key = this.widgetKeyGenerator.fromWidget(widget);

    this.logger.info(`saving Widget=(${widget.id}) in Bucket=(${this.bucket})`);

    const putReq = new PutObjectCommand({
      Bucket: this.bucket,
      Key: key,
      Body: JSON.stringify(widget, null, 2),
    });

    await this.s3Client.send(putReq);

    this.logger.info(`successfully saved Widget=(${widget.id}) in S3`);
    return widget;
  }

  public async delete(widget: WidgetT) {
    const key = this.widgetKeyGenerator.fromWidget(widget);

    this.logger.info(
      `deleting Widget=(${widget.id}) in Bucket=(${this.bucket})`
    );

    const deleteReq = new DeleteObjectCommand({
      Key: key,
      Bucket: this.bucket,
    });

    await this.s3Client.send(deleteReq);

    this.logger.info(`successfully deleted Widget=(${widget.id}) in S3`);
    return widget;
  }
}