From b9aabfcdbc62ee5532159696be229aa35721aec2 Mon Sep 17 00:00:00 2001 From: Gitar Date: Mon, 7 Oct 2024 12:55:38 +0000 Subject: [PATCH 01/15] [Gitar] Updating TypeScript files --- src/lib/addons/datadog.ts | 10 ++++------ src/lib/addons/new-relic.ts | 10 ++++------ src/lib/addons/slack-app.ts | 10 ++++------ src/lib/addons/slack.ts | 10 ++++------ src/lib/addons/teams.ts | 10 ++++------ src/lib/addons/webhook.ts | 10 ++++------ src/lib/types/experimental.ts | 5 ----- src/server-dev.ts | 1 - 8 files changed, 24 insertions(+), 42 deletions(-) diff --git a/src/lib/addons/datadog.ts b/src/lib/addons/datadog.ts index 27cf38b7d703..4b91a7c81cc7 100644 --- a/src/lib/addons/datadog.ts +++ b/src/lib/addons/datadog.ts @@ -116,12 +116,10 @@ export default class DatadogAddon extends Addon { this.logger.warn(failedMessage); } - if (this.flagResolver.isEnabled('addonUsageMetrics')) { - this.eventBus.emit(ADDON_EVENTS_HANDLED, { - result: state, - destination: 'datadog', - }); - } + this.eventBus.emit(ADDON_EVENTS_HANDLED, { + result: state, + destination: 'datadog', + }); this.registerEvent({ integrationId, diff --git a/src/lib/addons/new-relic.ts b/src/lib/addons/new-relic.ts index eeebe3fcbe5c..f4d9a93a8427 100644 --- a/src/lib/addons/new-relic.ts +++ b/src/lib/addons/new-relic.ts @@ -120,12 +120,10 @@ export default class NewRelicAddon extends Addon { this.logger.warn(failedMessage); } - if (this.flagResolver.isEnabled('addonUsageMetrics')) { - this.eventBus.emit(ADDON_EVENTS_HANDLED, { - result: state, - destination: 'new-relic', - }); - } + this.eventBus.emit(ADDON_EVENTS_HANDLED, { + result: state, + destination: 'new-relic', + }); this.registerEvent({ integrationId, diff --git a/src/lib/addons/slack-app.ts b/src/lib/addons/slack-app.ts index 1df686f106f2..4d50be0357cd 100644 --- a/src/lib/addons/slack-app.ts +++ b/src/lib/addons/slack-app.ts @@ -182,12 +182,10 @@ export default class SlackAppAddon extends Addon { stateDetails.push(errorMessage); this.logger.warn(errorMessage, error); } finally { - if (this.flagResolver.isEnabled('addonUsageMetrics')) { - this.eventBus.emit(ADDON_EVENTS_HANDLED, { - result: state, - destination: 'slack-app', - }); - } + this.eventBus.emit(ADDON_EVENTS_HANDLED, { + result: state, + destination: 'slack-app', + }); this.registerEvent({ integrationId, diff --git a/src/lib/addons/slack.ts b/src/lib/addons/slack.ts index 86567632d9f3..25a9156345db 100644 --- a/src/lib/addons/slack.ts +++ b/src/lib/addons/slack.ts @@ -134,12 +134,10 @@ export default class SlackAddon extends Addon { this.logger.warn(successWithErrorsMessage); } - if (this.flagResolver.isEnabled('addonUsageMetrics')) { - this.eventBus.emit(ADDON_EVENTS_HANDLED, { - result: state, - destination: 'slack', - }); - } + this.eventBus.emit(ADDON_EVENTS_HANDLED, { + result: state, + destination: 'slack', + }); this.registerEvent({ integrationId, diff --git a/src/lib/addons/teams.ts b/src/lib/addons/teams.ts index 5c14d7204477..54cfc7b7d565 100644 --- a/src/lib/addons/teams.ts +++ b/src/lib/addons/teams.ts @@ -110,12 +110,10 @@ export default class TeamsAddon extends Addon { this.logger.warn(failedMessage); } - if (this.flagResolver.isEnabled('addonUsageMetrics')) { - this.eventBus.emit(ADDON_EVENTS_HANDLED, { - result: state, - destination: 'teams', - }); - } + this.eventBus.emit(ADDON_EVENTS_HANDLED, { + result: state, + destination: 'teams', + }); this.registerEvent({ integrationId, diff --git a/src/lib/addons/webhook.ts b/src/lib/addons/webhook.ts index ff8460704142..b388b30b4aaa 100644 --- a/src/lib/addons/webhook.ts +++ b/src/lib/addons/webhook.ts @@ -104,12 +104,10 @@ export default class Webhook extends Addon { this.logger.warn(failedMessage); } - if (this.flagResolver.isEnabled('addonUsageMetrics')) { - this.eventBus.emit(ADDON_EVENTS_HANDLED, { - result: state, - destination: 'webhook', - }); - } + this.eventBus.emit(ADDON_EVENTS_HANDLED, { + result: state, + destination: 'webhook', + }); const domain = new URL(url).hostname; this.logger.info(`Webhook invoked`, { diff --git a/src/lib/types/experimental.ts b/src/lib/types/experimental.ts index 41df802b1f95..4c0989d44ded 100644 --- a/src/lib/types/experimental.ts +++ b/src/lib/types/experimental.ts @@ -54,7 +54,6 @@ export type IFlagKey = | 'extendedMetrics' | 'removeUnsafeInlineStyleSrc' | 'originMiddleware' - | 'addonUsageMetrics' | 'onboardingMetrics' | 'onboardingUI' | 'projectRoleAssignment' @@ -270,10 +269,6 @@ const flags: IFlags = { process.env.UNLEASH_EXPERIMENTAL_ORIGIN_MIDDLEWARE, false, ), - addonUsageMetrics: parseEnvVarBoolean( - process.env.UNLEASH_EXPERIMENTAL_ADDON_USAGE_METRICS, - false, - ), onboardingMetrics: parseEnvVarBoolean( process.env.UNLEASH_EXPERIMENTAL_ONBOARDING_METRICS, false, diff --git a/src/server-dev.ts b/src/server-dev.ts index c132b9ec9965..46162ce699e5 100644 --- a/src/server-dev.ts +++ b/src/server-dev.ts @@ -51,7 +51,6 @@ process.nextTick(async () => { enableLegacyVariants: false, extendedMetrics: true, originMiddleware: true, - addonUsageMetrics: true, onboardingMetrics: true, onboardingUI: true, personalDashboardUI: true, From b198a9f6d6caf1af2e4ddc7dcf93acf76aabf996 Mon Sep 17 00:00:00 2001 From: David Leek Date: Wed, 9 Oct 2024 15:04:01 +0200 Subject: [PATCH 02/15] chore: add an emit method to the eventBus in addon tests --- src/lib/addons/datadog.test.ts | 4 +++- src/lib/addons/new-relic.test.ts | 4 +++- src/lib/addons/slack-app.test.ts | 4 +++- src/lib/addons/slack.test.ts | 4 +++- src/lib/addons/teams.test.ts | 4 +++- src/lib/addons/webhook.test.ts | 4 +++- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/lib/addons/datadog.test.ts b/src/lib/addons/datadog.test.ts index 933643146d15..281bb75c834e 100644 --- a/src/lib/addons/datadog.test.ts +++ b/src/lib/addons/datadog.test.ts @@ -26,7 +26,9 @@ const ARGS: IAddonConfig = { unleashUrl: 'http://some-url.com', integrationEventsService: {} as IntegrationEventsService, flagResolver: { isEnabled: (expName: IFlagKey) => false } as IFlagResolver, - eventBus: {} as any, + eventBus: { + emit: jest.fn(), + } as any, }; jest.mock( diff --git a/src/lib/addons/new-relic.test.ts b/src/lib/addons/new-relic.test.ts index 100912670602..857c4161421a 100644 --- a/src/lib/addons/new-relic.test.ts +++ b/src/lib/addons/new-relic.test.ts @@ -28,7 +28,9 @@ const ARGS: IAddonConfig = { unleashUrl: 'http://some-url.com', integrationEventsService: {} as IntegrationEventsService, flagResolver: { isEnabled: (expName: IFlagKey) => false } as IFlagResolver, - eventBus: {} as any, + eventBus: { + emit: jest.fn(), + } as any, }; jest.mock( diff --git a/src/lib/addons/slack-app.test.ts b/src/lib/addons/slack-app.test.ts index cac4d98dd88d..7d11ef782a8d 100644 --- a/src/lib/addons/slack-app.test.ts +++ b/src/lib/addons/slack-app.test.ts @@ -30,7 +30,9 @@ const ARGS: IAddonConfig = { unleashUrl: 'http://some-url.com', integrationEventsService: {} as IntegrationEventsService, flagResolver: { isEnabled: (expName: IFlagKey) => false } as IFlagResolver, - eventBus: {} as any, + eventBus: { + emit: jest.fn(), + } as any, }; let postMessage = jest.fn().mockImplementation((options) => { diff --git a/src/lib/addons/slack.test.ts b/src/lib/addons/slack.test.ts index eba87005c73e..b843bd7b5c73 100644 --- a/src/lib/addons/slack.test.ts +++ b/src/lib/addons/slack.test.ts @@ -27,7 +27,9 @@ const ARGS: IAddonConfig = { unleashUrl: 'http://some-url.com', integrationEventsService: {} as IntegrationEventsService, flagResolver: { isEnabled: (expName: IFlagKey) => false } as IFlagResolver, - eventBus: {} as any, + eventBus: { + emit: jest.fn(), + } as any, }; jest.mock( diff --git a/src/lib/addons/teams.test.ts b/src/lib/addons/teams.test.ts index 8c1b14c0bb46..ccab21c7b8cb 100644 --- a/src/lib/addons/teams.test.ts +++ b/src/lib/addons/teams.test.ts @@ -28,7 +28,9 @@ const ARGS: IAddonConfig = { unleashUrl: 'http://some-url.com', integrationEventsService: {} as IntegrationEventsService, flagResolver: { isEnabled: (expName: IFlagKey) => false } as IFlagResolver, - eventBus: {} as any, + eventBus: { + emit: jest.fn(), + } as any, }; jest.mock( diff --git a/src/lib/addons/webhook.test.ts b/src/lib/addons/webhook.test.ts index eb059e5ddfa0..6e8452471317 100644 --- a/src/lib/addons/webhook.test.ts +++ b/src/lib/addons/webhook.test.ts @@ -23,7 +23,9 @@ const ARGS: IAddonConfig = { unleashUrl: 'http://some-url.com', integrationEventsService: {} as IntegrationEventsService, flagResolver: { isEnabled: (expName: IFlagKey) => false } as IFlagResolver, - eventBus: {} as any, + eventBus: { + emit: jest.fn(), + } as any, }; jest.mock( From d32cc39da5d1fa1485d76d40acf364232dd85f05 Mon Sep 17 00:00:00 2001 From: David Leek Date: Thu, 10 Oct 2024 08:56:43 +0200 Subject: [PATCH 03/15] chore: move eventemitter out of addons into addon-service --- src/lib/addons/datadog.test.ts | 4 +--- src/lib/addons/datadog.ts | 6 ------ src/lib/addons/new-relic.test.ts | 4 +--- src/lib/addons/new-relic.ts | 6 ------ src/lib/addons/slack-app.test.ts | 4 +--- src/lib/addons/slack-app.ts | 6 ------ src/lib/addons/slack.test.ts | 4 +--- src/lib/addons/slack.ts | 6 ------ src/lib/addons/teams.test.ts | 4 +--- src/lib/addons/teams.ts | 6 ------ src/lib/addons/webhook.test.ts | 4 +--- src/lib/addons/webhook.ts | 6 ------ src/lib/services/addon-service.test.ts | 1 + src/lib/services/addon-service.ts | 4 ++++ 14 files changed, 11 insertions(+), 54 deletions(-) diff --git a/src/lib/addons/datadog.test.ts b/src/lib/addons/datadog.test.ts index 281bb75c834e..933643146d15 100644 --- a/src/lib/addons/datadog.test.ts +++ b/src/lib/addons/datadog.test.ts @@ -26,9 +26,7 @@ const ARGS: IAddonConfig = { unleashUrl: 'http://some-url.com', integrationEventsService: {} as IntegrationEventsService, flagResolver: { isEnabled: (expName: IFlagKey) => false } as IFlagResolver, - eventBus: { - emit: jest.fn(), - } as any, + eventBus: {} as any, }; jest.mock( diff --git a/src/lib/addons/datadog.ts b/src/lib/addons/datadog.ts index 4b91a7c81cc7..57b2666b2dc0 100644 --- a/src/lib/addons/datadog.ts +++ b/src/lib/addons/datadog.ts @@ -13,7 +13,6 @@ import { } from './feature-event-formatter-md'; import type { IEvent } from '../types/events'; import type { IntegrationEventState } from '../features/integration-events/integration-events-store'; -import { ADDON_EVENTS_HANDLED } from '../metric-events'; interface IDatadogParameters { url: string; @@ -116,11 +115,6 @@ export default class DatadogAddon extends Addon { this.logger.warn(failedMessage); } - this.eventBus.emit(ADDON_EVENTS_HANDLED, { - result: state, - destination: 'datadog', - }); - this.registerEvent({ integrationId, state, diff --git a/src/lib/addons/new-relic.test.ts b/src/lib/addons/new-relic.test.ts index 857c4161421a..100912670602 100644 --- a/src/lib/addons/new-relic.test.ts +++ b/src/lib/addons/new-relic.test.ts @@ -28,9 +28,7 @@ const ARGS: IAddonConfig = { unleashUrl: 'http://some-url.com', integrationEventsService: {} as IntegrationEventsService, flagResolver: { isEnabled: (expName: IFlagKey) => false } as IFlagResolver, - eventBus: { - emit: jest.fn(), - } as any, + eventBus: {} as any, }; jest.mock( diff --git a/src/lib/addons/new-relic.ts b/src/lib/addons/new-relic.ts index f4d9a93a8427..458a0de039f6 100644 --- a/src/lib/addons/new-relic.ts +++ b/src/lib/addons/new-relic.ts @@ -16,7 +16,6 @@ import { import { gzip } from 'node:zlib'; import { promisify } from 'util'; import type { IntegrationEventState } from '../features/integration-events/integration-events-store'; -import { ADDON_EVENTS_HANDLED } from '../metric-events'; const asyncGzip = promisify(gzip); @@ -120,11 +119,6 @@ export default class NewRelicAddon extends Addon { this.logger.warn(failedMessage); } - this.eventBus.emit(ADDON_EVENTS_HANDLED, { - result: state, - destination: 'new-relic', - }); - this.registerEvent({ integrationId, state, diff --git a/src/lib/addons/slack-app.test.ts b/src/lib/addons/slack-app.test.ts index 7d11ef782a8d..cac4d98dd88d 100644 --- a/src/lib/addons/slack-app.test.ts +++ b/src/lib/addons/slack-app.test.ts @@ -30,9 +30,7 @@ const ARGS: IAddonConfig = { unleashUrl: 'http://some-url.com', integrationEventsService: {} as IntegrationEventsService, flagResolver: { isEnabled: (expName: IFlagKey) => false } as IFlagResolver, - eventBus: { - emit: jest.fn(), - } as any, + eventBus: {} as any, }; let postMessage = jest.fn().mockImplementation((options) => { diff --git a/src/lib/addons/slack-app.ts b/src/lib/addons/slack-app.ts index 4d50be0357cd..a3f3cccdec31 100644 --- a/src/lib/addons/slack-app.ts +++ b/src/lib/addons/slack-app.ts @@ -25,7 +25,6 @@ import { } from './feature-event-formatter-md'; import type { IEvent } from '../types/events'; import type { IntegrationEventState } from '../features/integration-events/integration-events-store'; -import { ADDON_EVENTS_HANDLED } from '../metric-events'; interface ISlackAppAddonParameters { accessToken: string; @@ -182,11 +181,6 @@ export default class SlackAppAddon extends Addon { stateDetails.push(errorMessage); this.logger.warn(errorMessage, error); } finally { - this.eventBus.emit(ADDON_EVENTS_HANDLED, { - result: state, - destination: 'slack-app', - }); - this.registerEvent({ integrationId, state, diff --git a/src/lib/addons/slack.test.ts b/src/lib/addons/slack.test.ts index b843bd7b5c73..eba87005c73e 100644 --- a/src/lib/addons/slack.test.ts +++ b/src/lib/addons/slack.test.ts @@ -27,9 +27,7 @@ const ARGS: IAddonConfig = { unleashUrl: 'http://some-url.com', integrationEventsService: {} as IntegrationEventsService, flagResolver: { isEnabled: (expName: IFlagKey) => false } as IFlagResolver, - eventBus: { - emit: jest.fn(), - } as any, + eventBus: {} as any, }; jest.mock( diff --git a/src/lib/addons/slack.ts b/src/lib/addons/slack.ts index 25a9156345db..a9b1e18c9228 100644 --- a/src/lib/addons/slack.ts +++ b/src/lib/addons/slack.ts @@ -14,7 +14,6 @@ import { } from './feature-event-formatter-md'; import type { IEvent } from '../types/events'; import type { IntegrationEventState } from '../features/integration-events/integration-events-store'; -import { ADDON_EVENTS_HANDLED } from '../metric-events'; interface ISlackAddonParameters { url: string; @@ -134,11 +133,6 @@ export default class SlackAddon extends Addon { this.logger.warn(successWithErrorsMessage); } - this.eventBus.emit(ADDON_EVENTS_HANDLED, { - result: state, - destination: 'slack', - }); - this.registerEvent({ integrationId, state, diff --git a/src/lib/addons/teams.test.ts b/src/lib/addons/teams.test.ts index ccab21c7b8cb..8c1b14c0bb46 100644 --- a/src/lib/addons/teams.test.ts +++ b/src/lib/addons/teams.test.ts @@ -28,9 +28,7 @@ const ARGS: IAddonConfig = { unleashUrl: 'http://some-url.com', integrationEventsService: {} as IntegrationEventsService, flagResolver: { isEnabled: (expName: IFlagKey) => false } as IFlagResolver, - eventBus: { - emit: jest.fn(), - } as any, + eventBus: {} as any, }; jest.mock( diff --git a/src/lib/addons/teams.ts b/src/lib/addons/teams.ts index 54cfc7b7d565..ce184d25fc86 100644 --- a/src/lib/addons/teams.ts +++ b/src/lib/addons/teams.ts @@ -12,7 +12,6 @@ import { } from './feature-event-formatter-md'; import type { IEvent } from '../types/events'; import type { IntegrationEventState } from '../features/integration-events/integration-events-store'; -import { ADDON_EVENTS_HANDLED } from '../metric-events'; interface ITeamsParameters { url: string; @@ -110,11 +109,6 @@ export default class TeamsAddon extends Addon { this.logger.warn(failedMessage); } - this.eventBus.emit(ADDON_EVENTS_HANDLED, { - result: state, - destination: 'teams', - }); - this.registerEvent({ integrationId, state, diff --git a/src/lib/addons/webhook.test.ts b/src/lib/addons/webhook.test.ts index 6e8452471317..eb059e5ddfa0 100644 --- a/src/lib/addons/webhook.test.ts +++ b/src/lib/addons/webhook.test.ts @@ -23,9 +23,7 @@ const ARGS: IAddonConfig = { unleashUrl: 'http://some-url.com', integrationEventsService: {} as IntegrationEventsService, flagResolver: { isEnabled: (expName: IFlagKey) => false } as IFlagResolver, - eventBus: { - emit: jest.fn(), - } as any, + eventBus: {} as any, }; jest.mock( diff --git a/src/lib/addons/webhook.ts b/src/lib/addons/webhook.ts index b388b30b4aaa..22e43d02614e 100644 --- a/src/lib/addons/webhook.ts +++ b/src/lib/addons/webhook.ts @@ -12,7 +12,6 @@ import { type FeatureEventFormatter, FeatureEventFormatterMd, } from './feature-event-formatter-md'; -import { ADDON_EVENTS_HANDLED } from '../metric-events'; interface IParameters { url: string; @@ -104,11 +103,6 @@ export default class Webhook extends Addon { this.logger.warn(failedMessage); } - this.eventBus.emit(ADDON_EVENTS_HANDLED, { - result: state, - destination: 'webhook', - }); - const domain = new URL(url).hostname; this.logger.info(`Webhook invoked`, { domain, diff --git a/src/lib/services/addon-service.test.ts b/src/lib/services/addon-service.test.ts index b73fb24c3215..a01dcaaec263 100644 --- a/src/lib/services/addon-service.test.ts +++ b/src/lib/services/addon-service.test.ts @@ -55,6 +55,7 @@ function getSetup() { getLogger, // @ts-ignore server: { unleashUrl: 'http://test' }, + eventBus: { emit: jest.fn() } as any, }, tagTypeService, eventService, diff --git a/src/lib/services/addon-service.ts b/src/lib/services/addon-service.ts index 3bf4542e2c6d..a75da1c7c268 100644 --- a/src/lib/services/addon-service.ts +++ b/src/lib/services/addon-service.ts @@ -27,6 +27,7 @@ import type { IAddonDefinition } from '../types/model'; import { minutesToMilliseconds } from 'date-fns'; import type EventService from '../features/events/event-service'; import { omitKeys } from '../util'; +import type EventEmitter from 'events'; const SUPPORTED_EVENTS = Object.keys(events).map((k) => events[k]); @@ -52,6 +53,8 @@ export default class AddonService { sensitiveParams: ISensitiveParams; + eventBus: EventEmitter; + fetchAddonConfigs: (() => Promise) & memoizee.Memoized<() => Promise>; @@ -79,6 +82,7 @@ export default class AddonService { this.logger = getLogger('services/addon-service.js'); this.tagTypeService = tagTypeService; this.eventService = eventService; + this.eventBus = eventBus; this.addonProviders = addons || From a23675742021caa165c5865b1cf2fd8cd87ff4cf Mon Sep 17 00:00:00 2001 From: David Leek Date: Thu, 10 Oct 2024 08:57:19 +0200 Subject: [PATCH 04/15] chore: addons return result --- src/lib/addons/addon.ts | 2 +- src/lib/addons/datadog.ts | 4 +++- src/lib/addons/new-relic.ts | 4 +++- src/lib/addons/slack-app.ts | 8 +++++--- src/lib/addons/slack.ts | 4 +++- src/lib/addons/teams.ts | 4 +++- src/lib/addons/webhook.ts | 4 +++- src/lib/services/addon-service-test-simple-addon.ts | 4 +++- 8 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/lib/addons/addon.ts b/src/lib/addons/addon.ts index 9cec97f189a4..3d1244d6adb1 100644 --- a/src/lib/addons/addon.ts +++ b/src/lib/addons/addon.ts @@ -87,7 +87,7 @@ export default abstract class Addon { event: IEvent, parameters: any, integrationId: number, - ): Promise; + ): Promise; async registerEvent( integrationEvent: IntegrationEventWriteModel, diff --git a/src/lib/addons/datadog.ts b/src/lib/addons/datadog.ts index 57b2666b2dc0..81acf0de202c 100644 --- a/src/lib/addons/datadog.ts +++ b/src/lib/addons/datadog.ts @@ -46,7 +46,7 @@ export default class DatadogAddon extends Addon { event: IEvent, parameters: IDatadogParameters, integrationId: number, - ): Promise { + ): Promise { let state: IntegrationEventState = 'success'; const stateDetails: string[] = []; @@ -125,5 +125,7 @@ export default class DatadogAddon extends Addon { body, }, }); + + return state; } } diff --git a/src/lib/addons/new-relic.ts b/src/lib/addons/new-relic.ts index 458a0de039f6..ac2eb824ab8b 100644 --- a/src/lib/addons/new-relic.ts +++ b/src/lib/addons/new-relic.ts @@ -53,7 +53,7 @@ export default class NewRelicAddon extends Addon { event: IEvent, parameters: INewRelicParameters, integrationId: number, - ): Promise { + ): Promise { let state: IntegrationEventState = 'success'; const stateDetails: string[] = []; @@ -129,5 +129,7 @@ export default class NewRelicAddon extends Addon { body, }, }); + + return state; } } diff --git a/src/lib/addons/slack-app.ts b/src/lib/addons/slack-app.ts index a3f3cccdec31..69834888b5d5 100644 --- a/src/lib/addons/slack-app.ts +++ b/src/lib/addons/slack-app.ts @@ -53,7 +53,7 @@ export default class SlackAppAddon extends Addon { event: IEvent, parameters: ISlackAppAddonParameters, integrationId: number, - ): Promise { + ): Promise { let state: IntegrationEventState = 'success'; const stateDetails: string[] = []; let channels: string[] = []; @@ -69,7 +69,7 @@ export default class SlackAppAddon extends Addon { event, noAccessTokenMessage, ); - return; + return noAccessTokenMessage; } const taggedChannels = this.findTaggedChannels(event); @@ -85,7 +85,7 @@ export default class SlackAppAddon extends Addon { event, noSlackChannelsMessage, ); - return; + return noSlackChannelsMessage; } this.logger.debug( @@ -192,6 +192,8 @@ export default class SlackAppAddon extends Addon { }, }); } + + return state; } getUniqueArray(arr: T[]): T[] { diff --git a/src/lib/addons/slack.ts b/src/lib/addons/slack.ts index a9b1e18c9228..87658aacd58e 100644 --- a/src/lib/addons/slack.ts +++ b/src/lib/addons/slack.ts @@ -41,7 +41,7 @@ export default class SlackAddon extends Addon { event: IEvent, parameters: ISlackAddonParameters, integrationId: number, - ): Promise { + ): Promise { let state: IntegrationEventState = 'success'; const stateDetails: string[] = []; @@ -145,6 +145,8 @@ export default class SlackAddon extends Addon { message: `${formattedMessage}${text.length < formattedMessage.length ? ` (trimmed to ${maxLength} characters)` : ''}`, }, }); + + return state; } getUniqueArray(arr: T[]): T[] { diff --git a/src/lib/addons/teams.ts b/src/lib/addons/teams.ts index ce184d25fc86..cc5bc701ec4d 100644 --- a/src/lib/addons/teams.ts +++ b/src/lib/addons/teams.ts @@ -35,7 +35,7 @@ export default class TeamsAddon extends Addon { event: IEvent, parameters: ITeamsParameters, integrationId: number, - ): Promise { + ): Promise { let state: IntegrationEventState = 'success'; const stateDetails: string[] = []; @@ -119,5 +119,7 @@ export default class TeamsAddon extends Addon { body, }, }); + + return state; } } diff --git a/src/lib/addons/webhook.ts b/src/lib/addons/webhook.ts index 22e43d02614e..7b01de1a1be1 100644 --- a/src/lib/addons/webhook.ts +++ b/src/lib/addons/webhook.ts @@ -39,7 +39,7 @@ export default class Webhook extends Addon { event: IEvent, parameters: IParameters, integrationId: number, - ): Promise { + ): Promise { let state: IntegrationEventState = 'success'; const stateDetails: string[] = []; @@ -119,5 +119,7 @@ export default class Webhook extends Addon { body: sendingEvent ? event : body, }, }); + + return state; } } diff --git a/src/lib/services/addon-service-test-simple-addon.ts b/src/lib/services/addon-service-test-simple-addon.ts index 396843617554..dec6136ed649 100644 --- a/src/lib/services/addon-service-test-simple-addon.ts +++ b/src/lib/services/addon-service-test-simple-addon.ts @@ -75,10 +75,12 @@ export default class SimpleAddon extends Addon { } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - async handleEvent(event: IEvent, parameters: any): Promise { + async handleEvent(event: IEvent, parameters: any): Promise { this.events.push({ event, parameters, }); + + return 'success'; } } From 18a3dabcf094fadf880b5fbd199e8dc1362cddaf Mon Sep 17 00:00:00 2001 From: David Leek Date: Thu, 10 Oct 2024 08:57:51 +0200 Subject: [PATCH 05/15] chore: addon-service trigger event with handleEvent result --- src/lib/services/addon-service.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/lib/services/addon-service.ts b/src/lib/services/addon-service.ts index a75da1c7c268..86fc2ef716d4 100644 --- a/src/lib/services/addon-service.ts +++ b/src/lib/services/addon-service.ts @@ -27,6 +27,7 @@ import type { IAddonDefinition } from '../types/model'; import { minutesToMilliseconds } from 'date-fns'; import type EventService from '../features/events/event-service'; import { omitKeys } from '../util'; +import { ADDON_EVENTS_HANDLED } from '../metric-events'; import type EventEmitter from 'events'; const SUPPORTED_EVENTS = Object.keys(events).map((k) => events[k]); @@ -152,13 +153,16 @@ export default class AddonService { addon.environments.includes(event.environment), ) .filter((addon) => addonProviders[addon.provider]) - .forEach((addon) => - addonProviders[addon.provider].handleEvent( - event, - addon.parameters, - addon.id, - ), - ); + .forEach((addon) => { + const result = addonProviders[ + addon.provider + ].handleEvent(event, addon.parameters, addon.id); + + this.eventBus.emit(ADDON_EVENTS_HANDLED, { + result: result, + destination: addon.provider, + }); + }); }); }; } From c93d5d4216d757437ae12b289d35e890dec8d418 Mon Sep 17 00:00:00 2001 From: David Leek Date: Fri, 11 Oct 2024 08:25:36 +0200 Subject: [PATCH 06/15] chore: undo addon return changes and move metric emit to addon base class --- src/lib/addons/addon.ts | 7 ++++++- src/lib/addons/datadog.ts | 4 +--- src/lib/addons/new-relic.ts | 4 +--- src/lib/addons/slack-app.ts | 6 +----- src/lib/addons/teams.ts | 4 +--- src/lib/addons/webhook.ts | 4 +--- src/lib/services/addon-service.ts | 18 +++++++----------- 7 files changed, 18 insertions(+), 29 deletions(-) diff --git a/src/lib/addons/addon.ts b/src/lib/addons/addon.ts index 3d1244d6adb1..3cbfbf93e5ef 100644 --- a/src/lib/addons/addon.ts +++ b/src/lib/addons/addon.ts @@ -7,6 +7,7 @@ import type { IntegrationEventsService } from '../features/integration-events/in import type { IntegrationEventWriteModel } from '../features/integration-events/integration-events-store'; import type EventEmitter from 'events'; import type { IFlagResolver } from '../types'; +import { ADDON_EVENTS_HANDLED } from '../metric-events'; export default abstract class Addon { logger: Logger; @@ -87,12 +88,16 @@ export default abstract class Addon { event: IEvent, parameters: any, integrationId: number, - ): Promise; + ): Promise; async registerEvent( integrationEvent: IntegrationEventWriteModel, ): Promise { await this.integrationEventsService.registerEvent(integrationEvent); + this.eventBus.emit(ADDON_EVENTS_HANDLED, { + result: integrationEvent.state, + destination: this.name, + }); } destroy?(): void; diff --git a/src/lib/addons/datadog.ts b/src/lib/addons/datadog.ts index 81acf0de202c..57b2666b2dc0 100644 --- a/src/lib/addons/datadog.ts +++ b/src/lib/addons/datadog.ts @@ -46,7 +46,7 @@ export default class DatadogAddon extends Addon { event: IEvent, parameters: IDatadogParameters, integrationId: number, - ): Promise { + ): Promise { let state: IntegrationEventState = 'success'; const stateDetails: string[] = []; @@ -125,7 +125,5 @@ export default class DatadogAddon extends Addon { body, }, }); - - return state; } } diff --git a/src/lib/addons/new-relic.ts b/src/lib/addons/new-relic.ts index ac2eb824ab8b..458a0de039f6 100644 --- a/src/lib/addons/new-relic.ts +++ b/src/lib/addons/new-relic.ts @@ -53,7 +53,7 @@ export default class NewRelicAddon extends Addon { event: IEvent, parameters: INewRelicParameters, integrationId: number, - ): Promise { + ): Promise { let state: IntegrationEventState = 'success'; const stateDetails: string[] = []; @@ -129,7 +129,5 @@ export default class NewRelicAddon extends Addon { body, }, }); - - return state; } } diff --git a/src/lib/addons/slack-app.ts b/src/lib/addons/slack-app.ts index 69834888b5d5..b132e9c97845 100644 --- a/src/lib/addons/slack-app.ts +++ b/src/lib/addons/slack-app.ts @@ -53,7 +53,7 @@ export default class SlackAppAddon extends Addon { event: IEvent, parameters: ISlackAppAddonParameters, integrationId: number, - ): Promise { + ): Promise { let state: IntegrationEventState = 'success'; const stateDetails: string[] = []; let channels: string[] = []; @@ -69,7 +69,6 @@ export default class SlackAppAddon extends Addon { event, noAccessTokenMessage, ); - return noAccessTokenMessage; } const taggedChannels = this.findTaggedChannels(event); @@ -85,7 +84,6 @@ export default class SlackAppAddon extends Addon { event, noSlackChannelsMessage, ); - return noSlackChannelsMessage; } this.logger.debug( @@ -192,8 +190,6 @@ export default class SlackAppAddon extends Addon { }, }); } - - return state; } getUniqueArray(arr: T[]): T[] { diff --git a/src/lib/addons/teams.ts b/src/lib/addons/teams.ts index cc5bc701ec4d..ce184d25fc86 100644 --- a/src/lib/addons/teams.ts +++ b/src/lib/addons/teams.ts @@ -35,7 +35,7 @@ export default class TeamsAddon extends Addon { event: IEvent, parameters: ITeamsParameters, integrationId: number, - ): Promise { + ): Promise { let state: IntegrationEventState = 'success'; const stateDetails: string[] = []; @@ -119,7 +119,5 @@ export default class TeamsAddon extends Addon { body, }, }); - - return state; } } diff --git a/src/lib/addons/webhook.ts b/src/lib/addons/webhook.ts index 3e820d39cc37..99d226d2625f 100644 --- a/src/lib/addons/webhook.ts +++ b/src/lib/addons/webhook.ts @@ -39,7 +39,7 @@ export default class Webhook extends Addon { event: IEvent, parameters: IParameters, integrationId: number, - ): Promise { + ): Promise { let state: IntegrationEventState = 'success'; const stateDetails: string[] = []; @@ -121,7 +121,5 @@ export default class Webhook extends Addon { body: sendingEvent ? event : body, }, }); - - return state; } } diff --git a/src/lib/services/addon-service.ts b/src/lib/services/addon-service.ts index 86fc2ef716d4..a75da1c7c268 100644 --- a/src/lib/services/addon-service.ts +++ b/src/lib/services/addon-service.ts @@ -27,7 +27,6 @@ import type { IAddonDefinition } from '../types/model'; import { minutesToMilliseconds } from 'date-fns'; import type EventService from '../features/events/event-service'; import { omitKeys } from '../util'; -import { ADDON_EVENTS_HANDLED } from '../metric-events'; import type EventEmitter from 'events'; const SUPPORTED_EVENTS = Object.keys(events).map((k) => events[k]); @@ -153,16 +152,13 @@ export default class AddonService { addon.environments.includes(event.environment), ) .filter((addon) => addonProviders[addon.provider]) - .forEach((addon) => { - const result = addonProviders[ - addon.provider - ].handleEvent(event, addon.parameters, addon.id); - - this.eventBus.emit(ADDON_EVENTS_HANDLED, { - result: result, - destination: addon.provider, - }); - }); + .forEach((addon) => + addonProviders[addon.provider].handleEvent( + event, + addon.parameters, + addon.id, + ), + ); }); }; } From 47e6c3b0bb35f8ca6a59873178d3c0a7e76e8e53 Mon Sep 17 00:00:00 2001 From: David Leek Date: Fri, 11 Oct 2024 08:43:32 +0200 Subject: [PATCH 07/15] chore: fix simple addon test class --- src/lib/services/addon-service-test-simple-addon.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib/services/addon-service-test-simple-addon.ts b/src/lib/services/addon-service-test-simple-addon.ts index dec6136ed649..396843617554 100644 --- a/src/lib/services/addon-service-test-simple-addon.ts +++ b/src/lib/services/addon-service-test-simple-addon.ts @@ -75,12 +75,10 @@ export default class SimpleAddon extends Addon { } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - async handleEvent(event: IEvent, parameters: any): Promise { + async handleEvent(event: IEvent, parameters: any): Promise { this.events.push({ event, parameters, }); - - return 'success'; } } From 62b1fa0dc2bf8a456d8c96dcb881b5c9737c2f62 Mon Sep 17 00:00:00 2001 From: David Leek Date: Fri, 11 Oct 2024 08:46:20 +0200 Subject: [PATCH 08/15] chore: fix slack addon return type --- src/lib/addons/slack.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/addons/slack.ts b/src/lib/addons/slack.ts index 87658aacd58e..4d95ca2347a1 100644 --- a/src/lib/addons/slack.ts +++ b/src/lib/addons/slack.ts @@ -41,7 +41,7 @@ export default class SlackAddon extends Addon { event: IEvent, parameters: ISlackAddonParameters, integrationId: number, - ): Promise { + ): Promise { let state: IntegrationEventState = 'success'; const stateDetails: string[] = []; From 39ea2dad8f1d22c5b715d1a4606367d63c46fc53 Mon Sep 17 00:00:00 2001 From: David Leek Date: Fri, 11 Oct 2024 08:50:10 +0200 Subject: [PATCH 09/15] chore: remove slack addon return --- src/lib/addons/slack.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/lib/addons/slack.ts b/src/lib/addons/slack.ts index 4d95ca2347a1..a9b1e18c9228 100644 --- a/src/lib/addons/slack.ts +++ b/src/lib/addons/slack.ts @@ -145,8 +145,6 @@ export default class SlackAddon extends Addon { message: `${formattedMessage}${text.length < formattedMessage.length ? ` (trimmed to ${maxLength} characters)` : ''}`, }, }); - - return state; } getUniqueArray(arr: T[]): T[] { From 8c8c1f20644cdde17ce5f87ff1b48bc5fbe03a49 Mon Sep 17 00:00:00 2001 From: David Leek Date: Fri, 11 Oct 2024 10:16:27 +0200 Subject: [PATCH 10/15] chore: add back returns in slack-app addon --- src/lib/addons/slack-app.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/addons/slack-app.ts b/src/lib/addons/slack-app.ts index b132e9c97845..a3f3cccdec31 100644 --- a/src/lib/addons/slack-app.ts +++ b/src/lib/addons/slack-app.ts @@ -69,6 +69,7 @@ export default class SlackAppAddon extends Addon { event, noAccessTokenMessage, ); + return; } const taggedChannels = this.findTaggedChannels(event); @@ -84,6 +85,7 @@ export default class SlackAppAddon extends Addon { event, noSlackChannelsMessage, ); + return; } this.logger.debug( From aabdcda3497c30ebe3b032b4533270f753af9331 Mon Sep 17 00:00:00 2001 From: David Leek Date: Fri, 11 Oct 2024 10:18:05 +0200 Subject: [PATCH 11/15] chore: clean up addon-service.test --- src/lib/services/addon-service.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/services/addon-service.test.ts b/src/lib/services/addon-service.test.ts index a01dcaaec263..ff911c1d6e51 100644 --- a/src/lib/services/addon-service.test.ts +++ b/src/lib/services/addon-service.test.ts @@ -55,7 +55,7 @@ function getSetup() { getLogger, // @ts-ignore server: { unleashUrl: 'http://test' }, - eventBus: { emit: jest.fn() } as any, + eventBus: {} as any, }, tagTypeService, eventService, From 6995013f250c4df0d13ba052fa50a5d8b9a8a062 Mon Sep 17 00:00:00 2001 From: David Leek Date: Fri, 11 Oct 2024 10:19:03 +0200 Subject: [PATCH 12/15] chore: remove eventbus prop from addon-service.test config --- src/lib/services/addon-service.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/services/addon-service.test.ts b/src/lib/services/addon-service.test.ts index ff911c1d6e51..b73fb24c3215 100644 --- a/src/lib/services/addon-service.test.ts +++ b/src/lib/services/addon-service.test.ts @@ -55,7 +55,6 @@ function getSetup() { getLogger, // @ts-ignore server: { unleashUrl: 'http://test' }, - eventBus: {} as any, }, tagTypeService, eventService, From 674828fa91b9bda7e9b70929996f0df3a5113c26 Mon Sep 17 00:00:00 2001 From: David Leek Date: Fri, 11 Oct 2024 10:20:25 +0200 Subject: [PATCH 13/15] chore: remove unneccessary event emitter from addon-service --- src/lib/services/addon-service.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/lib/services/addon-service.ts b/src/lib/services/addon-service.ts index a75da1c7c268..3bf4542e2c6d 100644 --- a/src/lib/services/addon-service.ts +++ b/src/lib/services/addon-service.ts @@ -27,7 +27,6 @@ import type { IAddonDefinition } from '../types/model'; import { minutesToMilliseconds } from 'date-fns'; import type EventService from '../features/events/event-service'; import { omitKeys } from '../util'; -import type EventEmitter from 'events'; const SUPPORTED_EVENTS = Object.keys(events).map((k) => events[k]); @@ -53,8 +52,6 @@ export default class AddonService { sensitiveParams: ISensitiveParams; - eventBus: EventEmitter; - fetchAddonConfigs: (() => Promise) & memoizee.Memoized<() => Promise>; @@ -82,7 +79,6 @@ export default class AddonService { this.logger = getLogger('services/addon-service.js'); this.tagTypeService = tagTypeService; this.eventService = eventService; - this.eventBus = eventBus; this.addonProviders = addons || From 34be06a4ffe4189c3146228973b63943b0924dac Mon Sep 17 00:00:00 2001 From: David Leek Date: Fri, 11 Oct 2024 23:37:57 +0200 Subject: [PATCH 14/15] chore: re-add addonUsageMetrics as we moved the metrics code --- src/lib/types/experimental.ts | 7 ++++++- src/server-dev.ts | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/lib/types/experimental.ts b/src/lib/types/experimental.ts index e97f34b61041..4c2b8e17e211 100644 --- a/src/lib/types/experimental.ts +++ b/src/lib/types/experimental.ts @@ -62,7 +62,8 @@ export type IFlagKey = | 'purchaseAdditionalEnvironments' | 'originMiddlewareRequestLogging' | 'unleashAI' - | 'webhookDomainLogging'; + | 'webhookDomainLogging' + | 'addonUsageMetrics'; export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>; @@ -307,6 +308,10 @@ const flags: IFlags = { process.env.UNLEASH_EXPERIMENT_WEBHOOK_DOMAIN_LOGGING, false, ), + addonUsageMetrics: parseEnvVarBoolean( + process.env.UNLEASH_EXPERIMENTAL_ADDON_USAGE_METRICS, + false, + ), }; export const defaultExperimentalOptions: IExperimentalOptions = { diff --git a/src/server-dev.ts b/src/server-dev.ts index 665b3cabcf46..1da3845e862e 100644 --- a/src/server-dev.ts +++ b/src/server-dev.ts @@ -50,12 +50,14 @@ process.nextTick(async () => { manyStrategiesPagination: true, enableLegacyVariants: false, extendedMetrics: true, + onboardingMetrics: true, onboardingUI: true, personalDashboardUI: true, purchaseAdditionalEnvironments: true, originMiddlewareRequestLogging: true, unleashAI: true, webhookDomainLogging: true, + addonUsageMetrics: true, }, }, authentication: { From 53829f91bf4814a064c00f7cf42add04aad566d4 Mon Sep 17 00:00:00 2001 From: David Leek Date: Fri, 11 Oct 2024 23:39:20 +0200 Subject: [PATCH 15/15] chore: wrap metrics event emitting in addonUsageMetrics flag --- src/lib/addons/addon.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/lib/addons/addon.ts b/src/lib/addons/addon.ts index 3cbfbf93e5ef..173e84b75060 100644 --- a/src/lib/addons/addon.ts +++ b/src/lib/addons/addon.ts @@ -94,10 +94,12 @@ export default abstract class Addon { integrationEvent: IntegrationEventWriteModel, ): Promise { await this.integrationEventsService.registerEvent(integrationEvent); - this.eventBus.emit(ADDON_EVENTS_HANDLED, { - result: integrationEvent.state, - destination: this.name, - }); + if (this.flagResolver.isEnabled('addonUsageMetrics')) { + this.eventBus.emit(ADDON_EVENTS_HANDLED, { + result: integrationEvent.state, + destination: this.name, + }); + } } destroy?(): void;