From eea4f3c818eda5957b1a420e0bf0a4a335677f47 Mon Sep 17 00:00:00 2001 From: marian2js Date: Sun, 6 Aug 2023 16:40:24 +0100 Subject: [PATCH] feat: publish workflow trigger lifecycles --- .../services/workflow-trigger.service.ts | 29 ++++++++++ .../workflow-triggers.module.ts | 2 + libs/common/src/cache/redis-pubsub.service.ts | 29 ++++++++++ package.json | 2 + yarn.lock | 58 ++++++++++++++++++- 5 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 libs/common/src/cache/redis-pubsub.service.ts diff --git a/apps/api/src/workflow-triggers/services/workflow-trigger.service.ts b/apps/api/src/workflow-triggers/services/workflow-trigger.service.ts index a9c35750..a051bbdc 100644 --- a/apps/api/src/workflow-triggers/services/workflow-trigger.service.ts +++ b/apps/api/src/workflow-triggers/services/workflow-trigger.service.ts @@ -1,4 +1,5 @@ import { BaseService } from '@app/common/base/base.service' +import { RedisPubSubService } from '@app/common/cache/redis-pubsub.service' import { isEmptyObj } from '@app/common/utils/object.utils' import { IntegrationDefinitionFactory } from '@app/definitions' import { generateSchemaFromObject } from '@app/definitions/schema/utils/jsonSchemaUtils' @@ -44,6 +45,7 @@ export class WorkflowTriggerService extends BaseService { @Inject(forwardRef(() => IntegrationDefinitionFactory)) protected integrationDefinitionFactory: IntegrationDefinitionFactory, protected operationRunnerService: OperationRunnerService, + protected redisPubSubService: RedisPubSubService, ) { super(model) } @@ -159,6 +161,15 @@ export class WorkflowTriggerService extends BaseService { await this.workflowService.updateUsedIntegrations(workflow) + this.redisPubSubService.publish( + 'workflowTriggerCreated', + JSON.stringify({ + id: createdEntity.id, + integrationKey: integration.key, + integrationTriggerKey: integrationTrigger.key, + }), + ) + return createdEntity } @@ -308,6 +319,15 @@ export class WorkflowTriggerService extends BaseService { ) } + this.redisPubSubService.publish( + 'workflowTriggerUpdated', + JSON.stringify({ + id, + integrationKey: integration.key, + integrationTriggerKey: integrationTrigger.key, + }), + ) + return updatedEntity } @@ -360,6 +380,15 @@ export class WorkflowTriggerService extends BaseService { ) await this.workflowService.updateUsedIntegrations(workflow) + this.redisPubSubService.publish( + 'workflowTriggerDeleted', + JSON.stringify({ + id, + integrationKey: integration.key, + integrationTriggerKey: integrationTrigger.key, + }), + ) + return deletedEntity } diff --git a/apps/api/src/workflow-triggers/workflow-triggers.module.ts b/apps/api/src/workflow-triggers/workflow-triggers.module.ts index 0922667f..831d52c7 100644 --- a/apps/api/src/workflow-triggers/workflow-triggers.module.ts +++ b/apps/api/src/workflow-triggers/workflow-triggers.module.ts @@ -1,3 +1,4 @@ +import { CommonModule } from '@app/common' import { NestjsQueryTypegooseModule } from '@app/common/NestjsQueryTypegooseModule' import { forwardRef, Module } from '@nestjs/common' import { NestjsQueryGraphQLModule } from '@ptc-org/nestjs-query-graphql' @@ -31,6 +32,7 @@ import { WorkflowUsedIdService } from './services/workflow-used-id.service' ], dtos: [{ DTOClass: WorkflowTrigger }, { DTOClass: WorkflowUsedId }], }), + CommonModule, AuthModule, UsersModule, IntegrationsModule, diff --git a/libs/common/src/cache/redis-pubsub.service.ts b/libs/common/src/cache/redis-pubsub.service.ts new file mode 100644 index 00000000..641419bf --- /dev/null +++ b/libs/common/src/cache/redis-pubsub.service.ts @@ -0,0 +1,29 @@ +import { Injectable, OnModuleDestroy } from '@nestjs/common' +import { ConfigService } from '@nestjs/config' +import Redis, { Redis as RedisType } from 'ioredis' + +@Injectable() +export class RedisPubSubService implements OnModuleDestroy { + private readonly client: RedisType + + constructor(private configService: ConfigService) { + const redisUrl = this.configService.get('REDIS_URL') + if (!redisUrl) { + throw new Error('Redis URL not defined') + } + + this.client = new Redis(redisUrl) + } + + onModuleDestroy(): void { + this.client.quit() + } + + publish(channel: string, message: string): void { + this.client.publish(channel, message) + } + + subscribe(channel: string) { + return this.client.subscribe(channel) + } +} diff --git a/package.json b/package.json index 4399b49f..75a4d109 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "graphql-relay": "0.10.0", "graphql-subscriptions": "2.0.0", "graphql-type-json": "^0.3.2", + "ioredis": "^5.3.2", "js-yaml": "^3.14.0", "json-schema-generator": "^2.0.6", "json-schema-merge-allof": "^0.7.0", @@ -143,6 +144,7 @@ "@types/express": "^4.17.3", "@types/express-session": "^1.17.5", "@types/graphql-type-json": "^0.3.2", + "@types/ioredis": "^5.0.0", "@types/jest": "26.0.14", "@types/js-yaml": "^3.12.5", "@types/json-schema": "^7.0.5", diff --git a/yarn.lock b/yarn.lock index 7e35395b..0e809acf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2422,6 +2422,11 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@ioredis/commands@^1.1.1": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11" + integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -4333,6 +4338,13 @@ dependencies: graphql "^14.5.3" +"@types/ioredis@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/ioredis/-/ioredis-5.0.0.tgz#c1ea7e2f3e2c5a942a27cfee6f62ddcfb23fb3e7" + integrity sha512-zJbJ3FVE17CNl5KXzdeSPtdltc4tMT3TzC6fxQS0sQngkbFZ6h+0uTafsRqu+eSLIugf6Yb0Ea0SUuRr42Nk9g== + dependencies: + ioredis "*" + "@types/is-stream@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@types/is-stream/-/is-stream-1.1.0.tgz#b84d7bb207a210f2af9bed431dc0fbe9c4143be1" @@ -6613,7 +6625,7 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= -cluster-key-slot@1.1.2: +cluster-key-slot@1.1.2, cluster-key-slot@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== @@ -7237,7 +7249,7 @@ delimit-stream@0.1.0: resolved "https://registry.yarnpkg.com/delimit-stream/-/delimit-stream-0.1.0.tgz#9b8319477c0e5f8aeb3ce357ae305fc25ea1cd2b" integrity sha512-a02fiQ7poS5CnjiJBAsjGLPp5EwVoGHNeu9sziBd9huppRfsAFIpv5zNLv0V1gbop53ilngAf5Kf331AwcoRBQ== -denque@^2.0.1: +denque@^2.0.1, denque@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== @@ -9812,6 +9824,21 @@ io-ts@^2.0.0: resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-2.2.17.tgz#19531c9d49abcebc935d85d282e1db95adb01901" integrity sha512-RkQY06h6rRyADVEI46OCAUYTP2p18Vdtz9Movi19Mmj7SJ1NhN/yGyW7CxlcBVxh95WKg2YSbTmcUPqqeLuhXw== +ioredis@*, ioredis@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.3.2.tgz#9139f596f62fc9c72d873353ac5395bcf05709f7" + integrity sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA== + dependencies: + "@ioredis/commands" "^1.1.1" + cluster-key-slot "^1.1.0" + debug "^4.3.4" + denque "^2.1.0" + lodash.defaults "^4.2.0" + lodash.isarguments "^3.1.0" + redis-errors "^1.2.0" + redis-parser "^3.0.0" + standard-as-callback "^2.1.0" + ip@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" @@ -10999,6 +11026,11 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== +lodash.defaults@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== + lodash.defaultsdeep@^4.6.1: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" @@ -11014,6 +11046,11 @@ lodash.get@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= +lodash.isarguments@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== + lodash.isempty@4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" @@ -13152,6 +13189,18 @@ recursive-readdir@^2.2.2: dependencies: minimatch "3.0.4" +redis-errors@^1.0.0, redis-errors@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" + integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w== + +redis-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" + integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A== + dependencies: + redis-errors "^1.0.0" + redis@4.6.5, redis@^4.3.1: version "4.6.5" resolved "https://registry.yarnpkg.com/redis/-/redis-4.6.5.tgz#f32fbde44429e96f562bb0c9b1db0143ab8cfa4f" @@ -14092,6 +14141,11 @@ stacktrace-parser@^0.1.10: dependencies: type-fest "^0.7.1" +standard-as-callback@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" + integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== + state-toggle@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe"