From dd3c281af9cb9c098d79925dd97813662338398b Mon Sep 17 00:00:00 2001
From: Fedor Katurov <gotham48@gmail.com>
Date: Wed, 12 May 2021 14:24:56 +0700
Subject: [PATCH] #5 added healthcheck

---
 docker/docker-compose.yml        |  4 ++++
 src/api/http/index.ts            | 12 +++++++++---
 src/service/db/index.ts          |  1 +
 src/service/db/postgres/index.ts |  4 ++++
 src/service/telegram/index.ts    | 13 ++++++++++++-
 src/service/vk/index.ts          |  7 +++++++
 6 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index 6fb4343..4464231 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -27,6 +27,10 @@ services:
     entrypoint: ./wait-for-it.sh -t 90 db:5432 -- node ./index.js
     depends_on:
       - db
+    healthcheck:
+      test: [ "CMD", "curl", "-f", "http://localhost", "||", "kill", "-s", "2", "1" ]
+      interval: 5m
+      timeout: 1m
 volumes:
   bot-db:
   node_modules:
diff --git a/src/api/http/index.ts b/src/api/http/index.ts
index d2faae8..cffdea7 100644
--- a/src/api/http/index.ts
+++ b/src/api/http/index.ts
@@ -53,11 +53,12 @@ export class HttpApi {
       const url = new URL(this.webhook.url);
       logger.info(`using webhook at ${url.pathname}`);
       this.app.post(url.pathname, this.handleWebhook);
-      this.app.get(url.pathname, this.testWebhook);
+      this.app.get(url.pathname, this.healthcheck);
     }
 
     // VK event handler
     this.app.post(this.vk.endpoint, this.vk.handle);
+    this.app.get("/", this.healthcheck);
   }
 
   /**
@@ -71,7 +72,12 @@ export class HttpApi {
   /**
    * Just returns 200
    */
-  private testWebhook = async (req: Request, res: Response) => {
-    res.sendStatus(200);
+  private healthcheck = async (req: Request, res: Response) => {
+    try {
+      await Promise.all([this.telegram.healthcheck(), this.vk.healthcheck()]);
+      res.sendStatus(200);
+    } catch (e) {
+      res.sendStatus(501);
+    }
   };
 }
diff --git a/src/service/db/index.ts b/src/service/db/index.ts
index 149d934..9884ae3 100644
--- a/src/service/db/index.ts
+++ b/src/service/db/index.ts
@@ -43,4 +43,5 @@ export interface Storage {
     vkPostId: number
   ): Promise<Post | undefined>;
   findPostByEvent(eventId: number): Promise<Post | undefined>;
+  healthcheck(): Promise<void>;
 }
diff --git a/src/service/db/postgres/index.ts b/src/service/db/postgres/index.ts
index 8acd303..49306fc 100644
--- a/src/service/db/postgres/index.ts
+++ b/src/service/db/postgres/index.ts
@@ -127,4 +127,8 @@ export class PostgresDB implements Storage {
   createPost = async (eventId: number, text: string, vkPostId: number) => {
     return this.posts.save({ eventId, text, vkPostId });
   };
+
+  healthcheck = async () => {
+    await this.connection.query("SELECT 1");
+  };
 }
diff --git a/src/service/telegram/index.ts b/src/service/telegram/index.ts
index 666243d..667804e 100644
--- a/src/service/telegram/index.ts
+++ b/src/service/telegram/index.ts
@@ -96,11 +96,22 @@ export class TelegramService {
     });
   };
 
-  stop = (signal: string) => {
+  /**
+   * Stops service
+   * @param signal
+   */
+  public stop = (signal: string) => {
     if (!this.isWebhookEnabled) {
       return;
     }
 
     this.bot.stop(signal);
   };
+
+  /**
+   * Performs healthcheck for telegram
+   */
+  public healthcheck = async () => {
+    await this.bot.telegram.getMe();
+  };
 }
diff --git a/src/service/vk/index.ts b/src/service/vk/index.ts
index 2062782..60839bd 100644
--- a/src/service/vk/index.ts
+++ b/src/service/vk/index.ts
@@ -133,4 +133,11 @@ export class VkService {
       )
     );
   }
+
+  /**
+   * Performs healthcheck for telegram
+   */
+  public healthcheck = async () => {
+    await this.db.healthcheck();
+  };
 }