From 4d180d61bce28e96d4e77253f3b78081dfbb16ef Mon Sep 17 00:00:00 2001 From: Ersin Erdal Date: Sun, 7 Jul 2024 23:52:18 +0200 Subject: [PATCH] Collect request body bytes of the outgoing requests from the connectors --- .../server/lib/action_executor.test.ts | 45 +++++++- .../actions/server/lib/action_executor.ts | 15 ++- .../actions/server/lib/axios_utils.test.ts | 22 ++-- .../plugins/actions/server/lib/axios_utils.ts | 20 ++-- ...ts => connector_metrics_collector.test.ts} | 24 ++-- ...vice.ts => connector_metrics_collector.ts} | 2 +- .../create_action_event_log_record_object.ts | 3 + x-pack/plugins/actions/server/lib/index.ts | 2 +- .../server/sub_action_framework/case.test.ts | 16 +-- .../server/sub_action_framework/case.ts | 28 ++--- .../sub_action_framework/executor.test.ts | 35 +++--- .../server/sub_action_framework/executor.ts | 4 +- .../server/sub_action_framework/mocks.ts | 14 +-- .../sub_action_connector.test.ts | 48 ++++---- .../sub_action_connector.ts | 6 +- x-pack/plugins/actions/server/types.ts | 6 +- .../plugins/event_log/generated/mappings.json | 11 ++ x-pack/plugins/event_log/generated/schemas.ts | 6 + x-pack/plugins/event_log/scripts/mappings.js | 11 ++ .../connector_types/bedrock/bedrock.test.ts | 73 ++++++------ .../server/connector_types/bedrock/bedrock.ts | 28 ++--- .../connector_types/cases_webhook/index.ts | 5 +- .../cases_webhook/service.test.ts | 54 ++++----- .../connector_types/cases_webhook/service.ts | 12 +- .../crowdstrike/crowdstrike.test.ts | 42 +++---- .../crowdstrike/crowdstrike.ts | 26 ++--- .../d3security/d3security.test.ts | 16 +-- .../connector_types/d3security/d3security.ts | 6 +- .../connector_types/email/index.test.ts | 6 +- .../server/connector_types/email/index.ts | 4 +- .../connector_types/email/send_email.test.ts | 69 ++++-------- .../connector_types/email/send_email.ts | 21 ++-- .../email/send_email_graph_api.test.ts | 18 +-- .../email/send_email_graph_api.ts | 6 +- .../connector_types/es_index/index.test.ts | 16 ++- .../connector_types/gemini/gemini.test.ts | 29 ++--- .../server/connector_types/gemini/gemini.ts | 18 +-- .../server/connector_types/jira/index.ts | 4 +- .../connector_types/jira/service.test.ts | 48 ++++---- .../server/connector_types/jira/service.ts | 24 ++-- .../servicenow/create_service_wrapper.test.ts | 7 ++ .../lib/servicenow/create_service_wrapper.ts | 8 +- .../lib/servicenow/service.test.ts | 55 +++++++++ .../connector_types/lib/servicenow/service.ts | 18 +-- .../connector_types/lib/servicenow/types.ts | 6 +- .../connector_types/openai/openai.test.ts | 106 +++++++++--------- .../server/connector_types/openai/openai.ts | 22 ++-- .../opsgenie/connector.test.ts | 30 ++--- .../connector_types/opsgenie/connector.ts | 10 +- .../connector_types/pagerduty/index.test.ts | 30 ++--- .../server/connector_types/pagerduty/index.ts | 4 +- .../pagerduty/post_pagerduty.ts | 6 +- .../resilient/resilient.test.ts | 76 +++++++------ .../connector_types/resilient/resilient.ts | 34 +++--- .../sentinelone/sentinelone.test.ts | 14 +-- .../sentinelone/sentinelone.ts | 50 ++++----- .../connector_types/server_log/index.test.ts | 3 +- .../connector_types/servicenow_itom/index.ts | 4 +- .../servicenow_itom/service.test.ts | 12 +- .../servicenow_itom/service.ts | 6 +- .../connector_types/servicenow_itsm/index.ts | 4 +- .../servicenow_itsm/service.test.ts | 72 ++++++------ .../connector_types/servicenow_sir/index.ts | 4 +- .../servicenow_sir/service.test.ts | 12 +- .../connector_types/servicenow_sir/service.ts | 6 +- .../connector_types/slack/index.test.ts | 20 ++-- .../server/connector_types/slack/index.ts | 4 +- .../connector_types/slack_api/index.test.ts | 13 ++- .../server/connector_types/slack_api/index.ts | 4 +- .../connector_types/slack_api/service.test.ts | 24 ++-- .../connector_types/slack_api/service.ts | 10 +- .../server/connector_types/swimlane/index.ts | 4 +- .../connector_types/swimlane/service.test.ts | 22 ++-- .../connector_types/swimlane/service.ts | 10 +- .../connector_types/teams/index.test.ts | 14 +-- .../server/connector_types/teams/index.ts | 4 +- .../connector_types/tines/tines.test.ts | 40 ++++--- .../server/connector_types/tines/tines.ts | 18 +-- .../server/connector_types/torq/index.test.ts | 10 +- .../server/connector_types/torq/index.ts | 4 +- .../connector_types/webhook/index.test.ts | 20 ++-- .../server/connector_types/webhook/index.ts | 4 +- .../connector_types/xmatters/index.test.ts | 12 +- .../server/connector_types/xmatters/index.ts | 4 +- .../connector_types/xmatters/post_xmatters.ts | 6 +- .../alerts/server/sub_action_connector.ts | 7 +- .../tests/actions/connector_types/bedrock.ts | 25 ++++- .../actions/connector_types/cases_webhook.ts | 20 ++++ .../actions/connector_types/d3security.ts | 21 ++++ .../tests/actions/connector_types/email.ts | 22 +++- .../tests/actions/connector_types/es_index.ts | 20 ++++ .../tests/actions/connector_types/jira.ts | 20 ++++ .../tests/actions/connector_types/openai.ts | 21 +++- .../tests/actions/connector_types/opsgenie.ts | 20 ++++ .../actions/connector_types/pagerduty.ts | 20 ++++ .../actions/connector_types/resilient.ts | 20 ++++ .../actions/connector_types/server_log.ts | 20 ++++ .../connector_types/servicenow_itom.ts | 37 ++++++ .../connector_types/servicenow_itsm.ts | 70 ++++++++++++ .../actions/connector_types/servicenow_sir.ts | 53 +++++++++ .../actions/connector_types/slack_webhook.ts | 21 ++++ .../tests/actions/connector_types/swimlane.ts | 37 ++++++ .../tests/actions/connector_types/tines.ts | 84 ++++++++++++++ .../tests/actions/connector_types/torq.ts | 19 ++++ .../tests/actions/connector_types/webhook.ts | 21 ++++ .../tests/actions/connector_types/xmatters.ts | 20 ++++ .../group2/tests/actions/execute.ts | 2 + .../actions/sub_action_framework/index.ts | 30 ++++- 108 files changed, 1548 insertions(+), 771 deletions(-) rename x-pack/plugins/actions/server/lib/{connector_metrics_service.test.ts => connector_metrics_collector.test.ts} (56%) rename x-pack/plugins/actions/server/lib/{connector_metrics_service.ts => connector_metrics_collector.ts} (95%) diff --git a/x-pack/plugins/actions/server/lib/action_executor.test.ts b/x-pack/plugins/actions/server/lib/action_executor.test.ts index bfcedc821368f..15e0234404a8a 100644 --- a/x-pack/plugins/actions/server/lib/action_executor.test.ts +++ b/x-pack/plugins/actions/server/lib/action_executor.test.ts @@ -18,7 +18,7 @@ import { } from '@kbn/core/server/mocks'; import { eventLoggerMock } from '@kbn/event-log-plugin/server/mocks'; import { spacesServiceMock } from '@kbn/spaces-plugin/server/spaces_service/spaces_service.mock'; -import { ActionType as ConnectorType } from '../types'; +import { ActionType as ConnectorType, ConnectorMetricsCollector } from '../types'; import { actionsAuthorizationMock, actionsMock } from '../mocks'; import { asBackgroundTaskExecutionSource, @@ -31,6 +31,8 @@ import { SecurityConnectorFeatureId } from '../../common'; import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { createTaskRunError, getErrorSource } from '@kbn/task-manager-plugin/server/task_running'; import { GEN_AI_TOKEN_COUNT_EVENT } from './event_based_telemetry'; +import { Event } from './create_action_event_log_record_object'; +import { set } from '@kbn/safer-lodash-set'; const actionExecutor = new ActionExecutor({ isESOCanEncrypt: true }); const services = actionsMock.createServices(); @@ -163,6 +165,7 @@ const getBaseExecuteStartEventLogDoc = (unsecured: boolean) => { }, id: CONNECTOR_ID, name: '1', + type_id: 'test', }, ...(unsecured ? {} @@ -211,6 +214,10 @@ const getBaseExecuteEventLogDoc = (unsecured: boolean) => { }; }; +const addConnectorMetrics = (event: Event, value: number) => { + set(event, 'kibana.action.execution.metrics.request_body_bytes', value); +}; + beforeEach(() => { jest.resetAllMocks(); jest.clearAllMocks(); @@ -280,6 +287,7 @@ describe('Action Executor', () => { }, params: { foo: true }, logger: loggerMock, + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); expect(loggerMock.debug).toBeCalledWith('executing action test:1: 1'); @@ -287,6 +295,7 @@ describe('Action Executor', () => { const execStartDoc = getBaseExecuteStartEventLogDoc(executeUnsecure); const execDoc = getBaseExecuteEventLogDoc(executeUnsecure); + addConnectorMetrics(execDoc, 0); expect(eventLogger.logEvent).toHaveBeenNthCalledWith(1, execStartDoc); expect(eventLogger.logEvent).toHaveBeenNthCalledWith(2, execDoc); }); @@ -353,6 +362,7 @@ describe('Action Executor', () => { params: { foo: true }, logger: loggerMock, source: executionSource.source, + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); expect(loggerMock.debug).toBeCalledWith('executing action test:1: 1'); @@ -360,6 +370,7 @@ describe('Action Executor', () => { const execStartDoc = getBaseExecuteStartEventLogDoc(executeUnsecure); const execDoc = getBaseExecuteEventLogDoc(executeUnsecure); + addConnectorMetrics(execDoc, 0); expect(eventLogger.logEvent).toHaveBeenNthCalledWith(1, { ...execStartDoc, kibana: { @@ -431,6 +442,7 @@ describe('Action Executor', () => { }, params: { foo: true }, logger: loggerMock, + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); expect(loggerMock.debug).toBeCalledWith('executing action test:preconfigured: Preconfigured'); @@ -438,6 +450,7 @@ describe('Action Executor', () => { const execStartDoc = getBaseExecuteStartEventLogDoc(executeUnsecure); const execDoc = getBaseExecuteEventLogDoc(executeUnsecure); + addConnectorMetrics(execDoc, 0); expect(eventLogger.logEvent).toHaveBeenNthCalledWith(1, { ...execStartDoc, kibana: { @@ -513,6 +526,7 @@ describe('Action Executor', () => { params: { foo: true }, logger: loggerMock, request: {}, + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); } @@ -532,6 +546,7 @@ describe('Action Executor', () => { const execStartDoc = getBaseExecuteStartEventLogDoc(executeUnsecure); const execDoc = getBaseExecuteEventLogDoc(executeUnsecure); + addConnectorMetrics(execDoc, 0); expect(eventLogger.logEvent).toHaveBeenNthCalledWith(1, { ...execStartDoc, kibana: { @@ -540,6 +555,7 @@ describe('Action Executor', () => { ...execStartDoc.kibana.action, id: 'system-connector-.cases', name: 'System action: .cases', + type_id: '.cases', }, saved_objects: [ { @@ -569,6 +585,7 @@ describe('Action Executor', () => { ...execDoc.kibana.action, id: 'system-connector-.cases', name: 'System action: .cases', + type_id: '.cases', }, saved_objects: [ { @@ -890,6 +907,7 @@ describe('Action Executor', () => { }, params: { foo: true }, logger: loggerMock, + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); }); @@ -921,6 +939,7 @@ describe('Action Executor', () => { params: { foo: true }, logger: loggerMock, request: {}, + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); }); @@ -989,6 +1008,7 @@ describe('Action Executor', () => { }, params: { foo: true }, logger: loggerMock, + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); expect(loggerMock.debug).toBeCalledWith('executing action test:preconfigured: Preconfigured'); @@ -996,6 +1016,7 @@ describe('Action Executor', () => { const execStartDoc = getBaseExecuteStartEventLogDoc(executeUnsecure); const execDoc = getBaseExecuteEventLogDoc(executeUnsecure); + addConnectorMetrics(execDoc, 0); expect(eventLogger.logEvent).toHaveBeenNthCalledWith(1, { ...execStartDoc, kibana: { @@ -1026,6 +1047,12 @@ describe('Action Executor', () => { ...execDoc.kibana.action, id: 'preconfigured', name: 'Preconfigured', + execution: { + ...execStartDoc.kibana.action.execution, + metrics: { + request_body_bytes: 0, + }, + }, }, saved_objects: [ { @@ -1074,6 +1101,7 @@ describe('Action Executor', () => { params: { foo: true }, logger: loggerMock, request: {}, + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); expect(loggerMock.debug).toBeCalledWith( @@ -1083,6 +1111,7 @@ describe('Action Executor', () => { const execStartDoc = getBaseExecuteStartEventLogDoc(executeUnsecure); const execDoc = getBaseExecuteEventLogDoc(executeUnsecure); + addConnectorMetrics(execDoc, 0); expect(eventLogger.logEvent).toHaveBeenNthCalledWith(1, { ...execStartDoc, kibana: { @@ -1091,6 +1120,7 @@ describe('Action Executor', () => { ...execStartDoc.kibana.action, id: 'system-connector-.cases', name: 'System action: .cases', + type_id: '.cases', }, saved_objects: [ { @@ -1120,6 +1150,7 @@ describe('Action Executor', () => { ...execDoc.kibana.action, id: 'system-connector-.cases', name: 'System action: .cases', + type_id: '.cases', }, saved_objects: [ { @@ -1290,6 +1321,7 @@ describe('Action Executor', () => { }, params: { foo: true }, logger: loggerMock, + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); } }); @@ -1385,6 +1417,7 @@ describe('Event log', () => { }, name: undefined, id: 'action1', + type_id: 'test', }, alert: { rule: { @@ -1430,6 +1463,7 @@ describe('Event log', () => { }, name: 'action-1', id: '1', + type_id: 'test', }, alert: { rule: { @@ -1483,6 +1517,7 @@ describe('Event log', () => { }, name: 'action-1', id: '1', + type_id: 'test', }, alert: { rule: { @@ -1559,9 +1594,13 @@ describe('Event log', () => { gen_ai: { usage: mockGenAi.usage, }, + metrics: { + request_body_bytes: 0, + }, }, name: 'action-1', id: '1', + type_id: '.gen-ai', }, alert: { rule: { @@ -1655,9 +1694,13 @@ describe('Event log', () => { total_tokens: 35, }, }, + metrics: { + request_body_bytes: 0, + }, }, name: 'action-1', id: '1', + type_id: '.gen-ai', }, alert: { rule: { diff --git a/x-pack/plugins/actions/server/lib/action_executor.ts b/x-pack/plugins/actions/server/lib/action_executor.ts index ec7375949fff0..271cf96d1ab17 100644 --- a/x-pack/plugins/actions/server/lib/action_executor.ts +++ b/x-pack/plugins/actions/server/lib/action_executor.ts @@ -23,7 +23,7 @@ import { IEventLogger, SAVED_OBJECT_REL_PRIMARY } from '@kbn/event-log-plugin/se import { createTaskRunError, TaskErrorSource } from '@kbn/task-manager-plugin/server'; import { getErrorSource } from '@kbn/task-manager-plugin/server/task_running'; import { GEN_AI_TOKEN_COUNT_EVENT } from './event_based_telemetry'; -import { ConnectorMetricsService } from './connector_metrics_service'; +import { ConnectorMetricsCollector } from './connector_metrics_collector'; import { getGenAiTokenTracking, shouldTrackGenAiToken } from './gen_ai_token_tracking'; import { validateConfig, @@ -294,6 +294,7 @@ export class ActionExecutor { actionExecutionId, isInMemory: this.actionInfo.isInMemory, ...(source ? { source } : {}), + actionTypeId: this.actionInfo.actionTypeId, }); eventLogger.logEvent(event); @@ -390,7 +391,7 @@ export class ActionExecutor { }, async (span) => { const { actionTypeRegistry, analyticsService, eventLogger } = this.actionExecutorContext!; - const connectorMetricsService = new ConnectorMetricsService(); + const connectorMetricsCollector = new ConnectorMetricsCollector(); const actionInfo = await this.getActionInfoInternal(actionId, namespace.namespace); @@ -479,6 +480,7 @@ export class ActionExecutor { actionExecutionId, isInMemory: this.actionInfo.isInMemory, ...(source ? { source } : {}), + actionTypeId, }); eventLogger.startTiming(event); @@ -512,7 +514,7 @@ export class ActionExecutor { logger, source, ...(actionType.isSystemActionType ? { request } : {}), - connectorMetricsService, + connectorMetricsCollector, }); if (rawResult && rawResult.status === 'error') { @@ -541,8 +543,6 @@ export class ActionExecutor { status: 'ok', }; - // console.log('body bytes ==> ', connectorMetricsService.getRequestBodyByte()); - event.event = event.event || {}; const { error, ...resultWithoutError } = result; @@ -553,6 +553,11 @@ export class ActionExecutor { event.user = event.user || {}; event.user.name = currentUser?.username; event.user.id = currentUser?.profile_uid; + set( + event, + 'kibana.action.execution.metrics.request_body_bytes', + connectorMetricsCollector.getRequestBodyByte() + ); if (result.status === 'ok') { span?.setOutcome('success'); diff --git a/x-pack/plugins/actions/server/lib/axios_utils.test.ts b/x-pack/plugins/actions/server/lib/axios_utils.test.ts index 4b9105450154f..a78a1b2537401 100644 --- a/x-pack/plugins/actions/server/lib/axios_utils.test.ts +++ b/x-pack/plugins/actions/server/lib/axios_utils.test.ts @@ -21,7 +21,7 @@ import { import { loggingSystemMock } from '@kbn/core/server/mocks'; import { actionsConfigMock } from '../actions_config.mock'; import { getCustomAgents } from './get_custom_agents'; -import { ConnectorMetricsService } from './connector_metrics_service'; +import { ConnectorMetricsCollector } from './connector_metrics_collector'; const TestUrl = 'https://elastic.co/foo/bar/baz'; @@ -80,7 +80,7 @@ describe('request', () => { }); }); - test('adds request body bytes from request header on a successful request when connectorMetricsService is provided', async () => { + test('adds request body bytes from request header on a successful request when connectorMetricsCollector is provided', async () => { const contentLength = 12; axiosMock.mockImplementation(() => ({ status: 200, @@ -90,17 +90,17 @@ describe('request', () => { headers: { 'Content-Length': contentLength }, }, })); - const connectorMetricsService = new ConnectorMetricsService(); + const connectorMetricsCollector = new ConnectorMetricsCollector(); await request({ axios, url: '/test', logger, data: { test: 12345 }, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); - expect(connectorMetricsService.getRequestBodyByte()).toBe(contentLength); + expect(connectorMetricsCollector.getRequestBodyByte()).toBe(contentLength); }); test('adds request body bytes from request header on a failed', async () => { @@ -111,7 +111,7 @@ describe('request', () => { headers: { 'Content-Length': contentLength }, }) ); - const connectorMetricsService = new ConnectorMetricsService(); + const connectorMetricsCollector = new ConnectorMetricsCollector(); try { await request({ @@ -119,15 +119,15 @@ describe('request', () => { url: '/test', logger, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); } catch (e) { - expect(connectorMetricsService.getRequestBodyByte()).toBe(contentLength); + expect(connectorMetricsCollector.getRequestBodyByte()).toBe(contentLength); } }); test('adds request body bytes from data when request header does not exist', async () => { - const connectorMetricsService = new ConnectorMetricsService(); + const connectorMetricsCollector = new ConnectorMetricsCollector(); const data = { test: 12345 }; await request({ @@ -136,10 +136,10 @@ describe('request', () => { logger, data, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); - expect(connectorMetricsService.getRequestBodyByte()).toBe( + expect(connectorMetricsCollector.getRequestBodyByte()).toBe( Buffer.byteLength(JSON.stringify(data), 'utf8') ); }); diff --git a/x-pack/plugins/actions/server/lib/axios_utils.ts b/x-pack/plugins/actions/server/lib/axios_utils.ts index df160bd2970b0..f1a361ad18b2b 100644 --- a/x-pack/plugins/actions/server/lib/axios_utils.ts +++ b/x-pack/plugins/actions/server/lib/axios_utils.ts @@ -17,7 +17,7 @@ import { import { Logger } from '@kbn/core/server'; import { getCustomAgents } from './get_custom_agents'; import { ActionsConfigurationUtilities } from '../actions_config'; -import { ConnectorMetricsService, SSLSettings } from '../types'; +import { ConnectorMetricsCollector, SSLSettings } from '../types'; import { combineHeadersWithBasicAuthHeader } from './get_basic_auth_header'; export const request = async ({ @@ -30,7 +30,7 @@ export const request = async ({ headers, sslOverrides, timeout, - connectorMetricsService, + connectorMetricsCollector, ...config }: { axios: AxiosInstance; @@ -42,7 +42,7 @@ export const request = async ({ headers?: Record; timeout?: number; sslOverrides?: SSLSettings; - connectorMetricsService?: ConnectorMetricsService; // TODO make optional + connectorMetricsCollector?: ConnectorMetricsCollector; // TODO make optional } & AxiosRequestConfig): Promise => { if (!isEmpty(axios?.defaults?.baseURL ?? '')) { throw new Error( @@ -80,14 +80,14 @@ export const request = async ({ timeout: Math.max(settingsTimeout, timeout ?? 0), }); - if (connectorMetricsService) { - connectorMetricsService.addRequestBodyBytes(result, data); + if (connectorMetricsCollector) { + connectorMetricsCollector.addRequestBodyBytes(result, data); } return result; } catch (error) { - if (connectorMetricsService) { - connectorMetricsService.addRequestBodyBytes(error, data); + if (connectorMetricsCollector) { + connectorMetricsCollector.addRequestBodyBytes(error, data); } throw error; } @@ -99,14 +99,14 @@ export const patch = async ({ data, logger, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }: { axios: AxiosInstance; url: string; data: T; logger: Logger; configurationUtilities: ActionsConfigurationUtilities; - connectorMetricsService?: ConnectorMetricsService; + connectorMetricsCollector?: ConnectorMetricsCollector; }): Promise => { return request({ axios, @@ -115,7 +115,7 @@ export const patch = async ({ method: 'patch', data, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); }; diff --git a/x-pack/plugins/actions/server/lib/connector_metrics_service.test.ts b/x-pack/plugins/actions/server/lib/connector_metrics_collector.test.ts similarity index 56% rename from x-pack/plugins/actions/server/lib/connector_metrics_service.test.ts rename to x-pack/plugins/actions/server/lib/connector_metrics_collector.test.ts index a75a5d9c0c2cc..09137fc1c6c87 100644 --- a/x-pack/plugins/actions/server/lib/connector_metrics_service.test.ts +++ b/x-pack/plugins/actions/server/lib/connector_metrics_collector.test.ts @@ -5,12 +5,12 @@ * 2.0. */ -import { ConnectorMetricsService } from '../types'; +import { ConnectorMetricsCollector } from '../types'; import { AxiosHeaders, AxiosResponse } from 'axios'; -describe('ConnectorMetricsService', () => { +describe('ConnectorMetricsCollector', () => { test('it collects requestBodyBytes from response.request.headers', async () => { - const connectorMetricsService = new ConnectorMetricsService(); + const connectorMetricsCollector = new ConnectorMetricsCollector(); const data = { test: 'foo' }; const contentLength = Buffer.byteLength(JSON.stringify(data), 'utf8'); @@ -25,16 +25,16 @@ describe('ConnectorMetricsService', () => { }, }; - connectorMetricsService.addRequestBodyBytes(axiosResponse, data); + connectorMetricsCollector.addRequestBodyBytes(axiosResponse, data); - expect(connectorMetricsService.getRequestBodyByte()).toBe(contentLength); + expect(connectorMetricsCollector.getRequestBodyByte()).toBe(contentLength); - connectorMetricsService.addRequestBodyBytes(axiosResponse, data); + connectorMetricsCollector.addRequestBodyBytes(axiosResponse, data); - expect(connectorMetricsService.getRequestBodyByte()).toBe(contentLength + contentLength); + expect(connectorMetricsCollector.getRequestBodyByte()).toBe(contentLength + contentLength); }); test('it collects requestBodyBytes from data when response.request.headers is missing', async () => { - const connectorMetricsService = new ConnectorMetricsService(); + const connectorMetricsCollector = new ConnectorMetricsCollector(); const data = { test: 'foo' }; const contentLength = Buffer.byteLength(JSON.stringify(data), 'utf8'); @@ -46,12 +46,12 @@ describe('ConnectorMetricsService', () => { config: { headers: new AxiosHeaders() }, }; - connectorMetricsService.addRequestBodyBytes(axiosResponse, data); + connectorMetricsCollector.addRequestBodyBytes(axiosResponse, data); - expect(connectorMetricsService.getRequestBodyByte()).toBe(contentLength); + expect(connectorMetricsCollector.getRequestBodyByte()).toBe(contentLength); - connectorMetricsService.addRequestBodyBytes(axiosResponse, data); + connectorMetricsCollector.addRequestBodyBytes(axiosResponse, data); - expect(connectorMetricsService.getRequestBodyByte()).toBe(contentLength + contentLength); + expect(connectorMetricsCollector.getRequestBodyByte()).toBe(contentLength + contentLength); }); }); diff --git a/x-pack/plugins/actions/server/lib/connector_metrics_service.ts b/x-pack/plugins/actions/server/lib/connector_metrics_collector.ts similarity index 95% rename from x-pack/plugins/actions/server/lib/connector_metrics_service.ts rename to x-pack/plugins/actions/server/lib/connector_metrics_collector.ts index 7e62c3f941d18..580ab70752f1b 100644 --- a/x-pack/plugins/actions/server/lib/connector_metrics_service.ts +++ b/x-pack/plugins/actions/server/lib/connector_metrics_collector.ts @@ -11,7 +11,7 @@ interface ConnectorMetrics { requestBodyBytes: number; } -export class ConnectorMetricsService { +export class ConnectorMetricsCollector { private metrics: ConnectorMetrics = { requestBodyBytes: 0, }; diff --git a/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.ts b/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.ts index 4f8bf08966c59..c3b7a3b35f512 100644 --- a/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.ts +++ b/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.ts @@ -37,6 +37,7 @@ interface CreateActionEventLogRecordParams { relatedSavedObjects?: RelatedSavedObjects; isInMemory?: boolean; source?: ActionExecutionSource; + actionTypeId: string; } export function createActionEventLogRecordObject(params: CreateActionEventLogRecordParams): Event { @@ -54,6 +55,7 @@ export function createActionEventLogRecordObject(params: CreateActionEventLogRec isInMemory, actionId, source, + actionTypeId, } = params; const kibanaAlertRule = { @@ -89,6 +91,7 @@ export function createActionEventLogRecordObject(params: CreateActionEventLogRec action: { ...(name ? { name } : {}), id: actionId, + type_id: actionTypeId, execution: { uuid: actionExecutionId, }, diff --git a/x-pack/plugins/actions/server/lib/index.ts b/x-pack/plugins/actions/server/lib/index.ts index ada48f8beefd0..07939fc920590 100644 --- a/x-pack/plugins/actions/server/lib/index.ts +++ b/x-pack/plugins/actions/server/lib/index.ts @@ -39,4 +39,4 @@ export { validateEmptyStrings } from './validate_empty_strings'; export { parseDate } from './parse_date'; export type { RelatedSavedObjects } from './related_saved_objects'; export { getBasicAuthHeader, combineHeadersWithBasicAuthHeader } from './get_basic_auth_header'; -export { ConnectorMetricsService } from './connector_metrics_service'; +export { ConnectorMetricsCollector } from './connector_metrics_collector'; diff --git a/x-pack/plugins/actions/server/sub_action_framework/case.test.ts b/x-pack/plugins/actions/server/sub_action_framework/case.test.ts index 387cc77af3380..c74adabca30e8 100644 --- a/x-pack/plugins/actions/server/sub_action_framework/case.test.ts +++ b/x-pack/plugins/actions/server/sub_action_framework/case.test.ts @@ -12,13 +12,14 @@ import { actionsConfigMock } from '../actions_config.mock'; import { actionsMock } from '../mocks'; import { TestCaseConnector } from './mocks'; import { ActionsConfigurationUtilities } from '../actions_config'; -import { ConnectorMetricsService } from '../lib'; +import { ConnectorMetricsCollector } from '../lib'; describe('CaseConnector', () => { let logger: MockedLogger; let services: ReturnType; let mockedActionsConfig: jest.Mocked; let service: TestCaseConnector; + let connectorMetricsCollector: ConnectorMetricsCollector; const pushToServiceIncidentParamsSchema = { name: schema.string(), category: schema.nullable(schema.string()), @@ -27,7 +28,6 @@ describe('CaseConnector', () => { check: schema.nullable(schema.number()), }), }; - const getConnectorMetricsService = () => new ConnectorMetricsService(); const incidentSchemaMock = { name: 'Test', category: null, foo: [false], bar: { check: 1 } }; const pushToServiceParams = { @@ -59,6 +59,8 @@ describe('CaseConnector', () => { }, pushToServiceIncidentParamsSchema ); + + connectorMetricsCollector = new ConnectorMetricsCollector(); }); describe('Sub actions', () => { @@ -193,7 +195,7 @@ describe('CaseConnector', () => { describe('pushToService', () => { it('should create an incident if externalId is null', async () => { - const res = await service.pushToService(pushToServiceParams, getConnectorMetricsService()); + const res = await service.pushToService(pushToServiceParams, connectorMetricsCollector); expect(res).toEqual({ id: 'create-incident', title: 'Test incident', @@ -208,7 +210,7 @@ describe('CaseConnector', () => { incident: { ...pushToServiceParams.incident, externalId: 'test-id' }, comments: [], }, - getConnectorMetricsService() + connectorMetricsCollector ); expect(res).toEqual({ @@ -228,7 +230,7 @@ describe('CaseConnector', () => { { comment: 'comment-2', commentId: 'comment-id-2' }, ], }, - getConnectorMetricsService() + connectorMetricsCollector ); expect(res).toEqual({ @@ -256,7 +258,7 @@ describe('CaseConnector', () => { // @ts-expect-error comments, }, - getConnectorMetricsService() + connectorMetricsCollector ); expect(res).toEqual({ @@ -273,7 +275,7 @@ describe('CaseConnector', () => { ...pushToServiceParams, comments: [], }, - getConnectorMetricsService() + connectorMetricsCollector ); expect(res).toEqual({ diff --git a/x-pack/plugins/actions/server/sub_action_framework/case.ts b/x-pack/plugins/actions/server/sub_action_framework/case.ts index 73ddbd582ea7f..b03d6e3001205 100644 --- a/x-pack/plugins/actions/server/sub_action_framework/case.ts +++ b/x-pack/plugins/actions/server/sub_action_framework/case.ts @@ -9,16 +9,16 @@ import { schema, Type } from '@kbn/config-schema'; import { ExternalServiceIncidentResponse, PushToServiceResponse } from './types'; import { SubActionConnector } from './sub_action_connector'; import { ServiceParams } from './types'; -import { ConnectorMetricsService } from '../lib'; +import { ConnectorMetricsCollector } from '../lib'; export interface CaseConnectorInterface { addComment: ( { incidentId, comment }: { incidentId: string; comment: string }, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) => Promise; createIncident: ( incident: Incident, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) => Promise; updateIncident: ( { @@ -28,18 +28,18 @@ export interface CaseConnectorInterface { incidentId: string; incident: Incident; }, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) => Promise; getIncident: ( { id }: { id: string }, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) => Promise; pushToService: ( params: { incident: { externalId: string | null } & Incident; comments: Array<{ commentId: string; comment: string }>; }, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) => Promise; } @@ -80,12 +80,12 @@ export abstract class CaseConnector; public abstract createIncident( incident: Incident, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise; public abstract updateIncident( { @@ -95,11 +95,11 @@ export abstract class CaseConnector; public abstract getIncident( { id }: { id: string }, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise; public async pushToService( @@ -107,7 +107,7 @@ export abstract class CaseConnector; }, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) { const { incident, comments } = params; const { externalId, ...rest } = incident; @@ -120,10 +120,10 @@ export abstract class CaseConnector 0) { @@ -135,7 +135,7 @@ export abstract class CaseConnector { const actionId = 'test-action-id'; @@ -31,7 +31,7 @@ describe('Executor', () => { let logger: MockedLogger; let services: ReturnType; let mockedActionsConfig: jest.Mocked; - const getConnectorMetricsService = () => new ConnectorMetricsService(); + let connectorMetricsCollector: ConnectorMetricsCollector; const createExecutor = (Service: IService) => { const connector = { @@ -57,6 +57,7 @@ describe('Executor', () => { logger = loggingSystemMock.createLogger(); services = actionsMock.createServices(); mockedActionsConfig = actionsConfigMock.create(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); it('should execute correctly', async () => { @@ -70,7 +71,7 @@ describe('Executor', () => { services, configurationUtilities: mockedActionsConfig, logger, - connectorMetricsService: getConnectorMetricsService(), + connectorMetricsCollector, }); expect(res).toEqual({ @@ -93,7 +94,7 @@ describe('Executor', () => { services, configurationUtilities: mockedActionsConfig, logger, - connectorMetricsService: getConnectorMetricsService(), + connectorMetricsCollector, }); expect(res).toEqual({ @@ -116,7 +117,7 @@ describe('Executor', () => { services, configurationUtilities: mockedActionsConfig, logger, - connectorMetricsService: getConnectorMetricsService(), + connectorMetricsCollector, }); expect(res).toEqual({ @@ -137,7 +138,7 @@ describe('Executor', () => { services, configurationUtilities: mockedActionsConfig, logger, - connectorMetricsService: getConnectorMetricsService(), + connectorMetricsCollector, }); expect(res).toEqual({ @@ -159,7 +160,7 @@ describe('Executor', () => { services, configurationUtilities: mockedActionsConfig, logger, - connectorMetricsService: getConnectorMetricsService(), + connectorMetricsCollector, }) ).rejects.toThrowError('You should register at least one subAction for your connector type'); }); @@ -176,7 +177,7 @@ describe('Executor', () => { services, configurationUtilities: mockedActionsConfig, logger, - connectorMetricsService: getConnectorMetricsService(), + connectorMetricsCollector, }) ).rejects.toThrowError( 'Sub action "not-exist" is not registered. Connector id: test-action-id. Connector name: Test. Connector type: .test' @@ -195,7 +196,7 @@ describe('Executor', () => { services, configurationUtilities: mockedActionsConfig, logger, - connectorMetricsService: getConnectorMetricsService(), + connectorMetricsCollector, }); } catch (e) { expect(getErrorSource(e)).toBe(TaskErrorSource.USER); @@ -217,7 +218,7 @@ describe('Executor', () => { services, configurationUtilities: mockedActionsConfig, logger, - connectorMetricsService: getConnectorMetricsService(), + connectorMetricsCollector, }) ).rejects.toThrowError( 'Method "not-exist" does not exists in service. Sub action: "testUrl". Connector id: test-action-id. Connector name: Test. Connector type: .test' @@ -236,7 +237,7 @@ describe('Executor', () => { services, configurationUtilities: mockedActionsConfig, logger, - connectorMetricsService: getConnectorMetricsService(), + connectorMetricsCollector, }) ).rejects.toThrowError( 'Method "notAFunction" must be a function. Connector id: test-action-id. Connector name: Test. Connector type: .test' @@ -255,14 +256,14 @@ describe('Executor', () => { services, configurationUtilities: mockedActionsConfig, logger, - connectorMetricsService: getConnectorMetricsService(), + connectorMetricsCollector, }) ).rejects.toThrowError( 'Request validation failed (Error: [id]: expected value of type [string] but got [undefined])' ); }); - it('Passes connectorMetricsService to the subAction method as a second param', async () => { + it('Passes connectorMetricsCollector to the subAction method as a second param', async () => { let echoSpy; const subActionParams = { id: 'test-id' }; @@ -282,15 +283,13 @@ describe('Executor', () => { }, }; - const connectorMetricsService = new ConnectorMetricsService(); - const executor = buildExecutor({ configurationUtilities: mockedActionsConfig, logger, connector, }); - executor({ + await executor({ actionId, params: { subAction: 'echo', subActionParams }, config, @@ -298,9 +297,9 @@ describe('Executor', () => { services, configurationUtilities: mockedActionsConfig, logger, - connectorMetricsService, + connectorMetricsCollector, }); - expect(echoSpy).toHaveBeenCalledWith(subActionParams, connectorMetricsService); + expect(echoSpy).toHaveBeenCalledWith(subActionParams, connectorMetricsCollector); }); }); diff --git a/x-pack/plugins/actions/server/sub_action_framework/executor.ts b/x-pack/plugins/actions/server/sub_action_framework/executor.ts index 5e8d79264b3e6..50c6b0d760e2a 100644 --- a/x-pack/plugins/actions/server/sub_action_framework/executor.ts +++ b/x-pack/plugins/actions/server/sub_action_framework/executor.ts @@ -37,7 +37,7 @@ export const buildExecutor = < secrets, services, request, - connectorMetricsService, + connectorMetricsCollector, }) => { const subAction = params.subAction; const subActionParams = params.subActionParams; @@ -96,7 +96,7 @@ export const buildExecutor = < } } - const data = await func.call(service, subActionParams, connectorMetricsService); + const data = await func.call(service, subActionParams, connectorMetricsCollector); return { status: 'ok', data: data ?? {}, actionId }; }; }; diff --git a/x-pack/plugins/actions/server/sub_action_framework/mocks.ts b/x-pack/plugins/actions/server/sub_action_framework/mocks.ts index adc026cf7f777..2ed6afe191501 100644 --- a/x-pack/plugins/actions/server/sub_action_framework/mocks.ts +++ b/x-pack/plugins/actions/server/sub_action_framework/mocks.ts @@ -8,7 +8,7 @@ import { schema, Type, TypeOf } from '@kbn/config-schema'; import { AxiosError } from 'axios'; -import { ConnectorMetricsService } from '../lib'; +import { ConnectorMetricsCollector } from '../lib'; import { SubActionConnector } from './sub_action_connector'; import { CaseConnector } from './case'; import { ExternalServiceIncidentResponse, ServiceParams } from './types'; @@ -60,7 +60,7 @@ export class TestSubActionConnector extends SubActionConnector | null }, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) { const res = await this.request( { @@ -69,7 +69,7 @@ export class TestSubActionConnector extends SubActionConnector }, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) { const res = await this.request( { @@ -86,7 +86,7 @@ export class TestSubActionConnector extends SubActionConnector } = {}, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) { const res = await this.request( { @@ -104,7 +104,7 @@ export class TestSubActionConnector extends SubActionConnector { return error; }; -const getConnectorMetricsService = () => new ConnectorMetricsService(); describe('SubActionConnector', () => { const axiosInstanceMock = jest.fn(); @@ -45,6 +44,7 @@ describe('SubActionConnector', () => { let services: ReturnType; let mockedActionsConfig: jest.Mocked; let service: TestSubActionConnector; + let connectorMetricsCollector: ConnectorMetricsCollector; beforeEach(() => { jest.resetAllMocks(); @@ -72,6 +72,8 @@ describe('SubActionConnector', () => { secrets: { username: 'elastic', password: 'changeme' }, services, }); + + connectorMetricsCollector = new ConnectorMetricsCollector(); }); describe('Sub actions', () => { @@ -89,34 +91,34 @@ describe('SubActionConnector', () => { it('removes double slashes correctly', async () => { await service.testUrl( { url: 'https://example.com//api///test-endpoint' }, - getConnectorMetricsService() + connectorMetricsCollector ); expect(requestMock.mock.calls[0][0].url).toBe('https://example.com/api/test-endpoint'); }); it('removes the ending slash correctly', async () => { - await service.testUrl({ url: 'https://example.com/' }, getConnectorMetricsService()); + await service.testUrl({ url: 'https://example.com/' }, connectorMetricsCollector); expect(requestMock.mock.calls[0][0].url).toBe('https://example.com'); }); it('throws an error if the url is invalid', async () => { expect.assertions(1); await expect(async () => - service.testUrl({ url: 'invalid-url' }, getConnectorMetricsService()) + service.testUrl({ url: 'invalid-url' }, connectorMetricsCollector) ).rejects.toThrow('URL Error: Invalid URL: invalid-url'); }); it('throws an error if the url starts with backslashes', async () => { expect.assertions(1); await expect(async () => - service.testUrl({ url: '//example.com/foo' }, getConnectorMetricsService()) + service.testUrl({ url: '//example.com/foo' }, connectorMetricsCollector) ).rejects.toThrow('URL Error: Invalid URL: //example.com/foo'); }); it('throws an error if the protocol is not supported', async () => { expect.assertions(1); await expect(async () => - service.testUrl({ url: 'ftp://example.com' }, getConnectorMetricsService()) + service.testUrl({ url: 'ftp://example.com' }, connectorMetricsCollector) ).rejects.toThrow('URL Error: Invalid protocol'); }); @@ -128,17 +130,14 @@ describe('SubActionConnector', () => { }); await expect(async () => - service.testUrl({ url: 'https://example.com' }, getConnectorMetricsService()) + service.testUrl({ url: 'https://example.com' }, connectorMetricsCollector) ).rejects.toThrow('error configuring connector action: URI is not allowed'); }); }); describe('Data', () => { it('sets data to an empty object if the data are null', async () => { - await service.testUrl( - { url: 'https://example.com', data: null }, - getConnectorMetricsService() - ); + await service.testUrl({ url: 'https://example.com', data: null }, connectorMetricsCollector); expect(requestMock).toHaveBeenCalledTimes(1); const { data } = requestMock.mock.calls[0][0]; @@ -148,7 +147,7 @@ describe('SubActionConnector', () => { it('pass data to axios correctly if not null', async () => { await service.testUrl( { url: 'https://example.com', data: { foo: 'foo' } }, - getConnectorMetricsService() + connectorMetricsCollector ); expect(requestMock).toHaveBeenCalledTimes(1); @@ -159,7 +158,7 @@ describe('SubActionConnector', () => { it('removeNullOrUndefinedFields: removes null values and undefined values correctly', async () => { await service.testData( { data: { foo: 'foo', bar: null, baz: undefined } }, - getConnectorMetricsService() + connectorMetricsCollector ); expect(requestMock).toHaveBeenCalledTimes(1); @@ -181,8 +180,7 @@ describe('SubActionConnector', () => { describe('Fetching', () => { it('fetch correctly', async () => { - const connectorMetricsService = getConnectorMetricsService(); - const res = await service.testUrl({ url: 'https://example.com' }, connectorMetricsService); + const res = await service.testUrl({ url: 'https://example.com' }, connectorMetricsCollector); expect(requestMock).toHaveBeenCalledTimes(1); expect(requestMock).toBeCalledWith({ @@ -196,7 +194,7 @@ describe('SubActionConnector', () => { 'X-Test-Header': 'test', }, url: 'https://example.com', - connectorMetricsService, + connectorMetricsCollector, }); expect(logger.debug).toBeCalledWith( @@ -209,7 +207,7 @@ describe('SubActionConnector', () => { it('validates the response correctly', async () => { requestMock.mockReturnValue({ data: { invalidField: 'test' } }); await expect(async () => - service.testUrl({ url: 'https://example.com' }, getConnectorMetricsService()) + service.testUrl({ url: 'https://example.com' }, connectorMetricsCollector) ).rejects.toThrow( 'Response validation failed (Error: [status]: expected value of type [string] but got [undefined])' ); @@ -221,7 +219,7 @@ describe('SubActionConnector', () => { }); await expect(async () => - service.testUrl({ url: 'https://example.com' }, getConnectorMetricsService()) + service.testUrl({ url: 'https://example.com' }, connectorMetricsCollector) ).rejects.toThrow('Message: An error occurred. Code: 500'); expect(logger.debug).toHaveBeenLastCalledWith( @@ -230,9 +228,7 @@ describe('SubActionConnector', () => { }); it('converts auth axios property to a basic auth header if provided', async () => { - const connectorMetricsService = getConnectorMetricsService(); - - await service.testAuth(undefined, connectorMetricsService); + await service.testAuth(undefined, connectorMetricsCollector); expect(requestMock).toHaveBeenCalledTimes(1); expect(requestMock).toBeCalledWith({ @@ -247,16 +243,14 @@ describe('SubActionConnector', () => { Authorization: `Basic ${Buffer.from('username:password').toString('base64')}`, }, url: 'https://example.com', - connectorMetricsService, + connectorMetricsCollector, }); }); it('does not override an authorization header if provided', async () => { - const connectorMetricsService = getConnectorMetricsService(); - await service.testAuth( { headers: { Authorization: 'Bearer my_token' } }, - connectorMetricsService + connectorMetricsCollector ); expect(requestMock).toHaveBeenCalledTimes(1); @@ -272,7 +266,7 @@ describe('SubActionConnector', () => { Authorization: 'Bearer my_token', }, url: 'https://example.com', - connectorMetricsService, + connectorMetricsCollector, }); }); }); diff --git a/x-pack/plugins/actions/server/sub_action_framework/sub_action_connector.ts b/x-pack/plugins/actions/server/sub_action_framework/sub_action_connector.ts index d0d00b9d9be23..5c43683f1e58e 100644 --- a/x-pack/plugins/actions/server/sub_action_framework/sub_action_connector.ts +++ b/x-pack/plugins/actions/server/sub_action_framework/sub_action_connector.ts @@ -24,7 +24,7 @@ import { IncomingMessage } from 'http'; import { PassThrough } from 'stream'; import { KibanaRequest } from '@kbn/core-http-server'; import { inspect } from 'util'; -import { ConnectorMetricsService } from '../lib'; +import { ConnectorMetricsCollector } from '../lib'; import { assertURL } from './helpers/validators'; import { ActionsConfigurationUtilities } from '../actions_config'; import { SubAction, SubActionRequestParams } from './types'; @@ -141,7 +141,7 @@ export abstract class SubActionConnector { timeout, ...config }: SubActionRequestParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise> { try { this.assertURL(url); @@ -164,7 +164,7 @@ export abstract class SubActionConnector { configurationUtilities: this.configurationUtilities, headers: this.getHeaders(auth, headers as AxiosHeaders), timeout, - connectorMetricsService, + connectorMetricsCollector, }); this.validateResponse(responseSchema, res.data); diff --git a/x-pack/plugins/actions/server/types.ts b/x-pack/plugins/actions/server/types.ts index d4bb89618e0e5..ffac1a9151c42 100644 --- a/x-pack/plugins/actions/server/types.ts +++ b/x-pack/plugins/actions/server/types.ts @@ -40,8 +40,8 @@ export type ActionTypeParams = Record; export type ConnectorTokenClientContract = PublicMethodsOf; import { Connector, ConnectorWithExtraFindData } from './application/connector/types'; -import type { ActionExecutionSource, ConnectorMetricsService } from './lib'; -export { ActionExecutionSourceType, ConnectorMetricsService } from './lib'; +import type { ActionExecutionSource, ConnectorMetricsCollector } from './lib'; +export { ActionExecutionSourceType, ConnectorMetricsCollector } from './lib'; export interface Services { savedObjectsClient: SavedObjectsClientContract; @@ -86,7 +86,7 @@ export interface ActionTypeExecutorOptions< configurationUtilities: ActionsConfigurationUtilities; source?: ActionExecutionSource; request?: KibanaRequest; - connectorMetricsService: ConnectorMetricsService; + connectorMetricsCollector: ConnectorMetricsCollector; } export type ActionResult = Connector; diff --git a/x-pack/plugins/event_log/generated/mappings.json b/x-pack/plugins/event_log/generated/mappings.json index 98908f516fc96..9626958958ff7 100644 --- a/x-pack/plugins/event_log/generated/mappings.json +++ b/x-pack/plugins/event_log/generated/mappings.json @@ -482,6 +482,10 @@ "type": "keyword", "ignore_above": 1024 }, + "type_id": { + "type": "keyword", + "ignore_above": 1024 + }, "execution": { "properties": { "source": { @@ -508,6 +512,13 @@ } } } + }, + "metrics": { + "properties": { + "request_body_bytes": { + "type": "long" + } + } } } } diff --git a/x-pack/plugins/event_log/generated/schemas.ts b/x-pack/plugins/event_log/generated/schemas.ts index f8db21105539e..eac5fe08ee0be 100644 --- a/x-pack/plugins/event_log/generated/schemas.ts +++ b/x-pack/plugins/event_log/generated/schemas.ts @@ -212,6 +212,7 @@ export const EventSchema = schema.maybe( schema.object({ name: ecsString(), id: ecsString(), + type_id: ecsString(), execution: schema.maybe( schema.object({ source: ecsString(), @@ -227,6 +228,11 @@ export const EventSchema = schema.maybe( ), }) ), + metrics: schema.maybe( + schema.object({ + request_body_bytes: ecsStringOrNumber(), + }) + ), }) ), }) diff --git a/x-pack/plugins/event_log/scripts/mappings.js b/x-pack/plugins/event_log/scripts/mappings.js index aa91f7fc5c2d6..360faaf488b9b 100644 --- a/x-pack/plugins/event_log/scripts/mappings.js +++ b/x-pack/plugins/event_log/scripts/mappings.js @@ -257,6 +257,10 @@ exports.EcsCustomPropertyMappings = { type: 'keyword', ignore_above: 1024, }, + type_id: { + type: 'keyword', + ignore_above: 1024, + }, execution: { properties: { source: { @@ -284,6 +288,13 @@ exports.EcsCustomPropertyMappings = { }, }, }, + metrics: { + properties: { + request_body_bytes: { + type: 'long', + }, + }, + }, }, }, }, diff --git a/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.test.ts index 7090bf8092e45..96a51d47f0988 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.test.ts @@ -25,7 +25,7 @@ import { import { DEFAULT_BODY } from '../../../public/connector_types/bedrock/constants'; import { initDashboard } from '../lib/gen_ai/create_gen_ai_dashboard'; import { AxiosError } from 'axios'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; jest.mock('../lib/gen_ai/create_gen_ai_dashboard'); // @ts-ignore @@ -58,7 +58,7 @@ describe('BedrockConnector', () => { headers: {}, data: claude3Response, }; - let connectorMetricsService: ConnectorMetricsService; + let connectorMetricsCollector: ConnectorMetricsCollector; beforeEach(() => { jest.clearAllMocks(); @@ -66,7 +66,7 @@ describe('BedrockConnector', () => { mockError = jest.fn().mockImplementation(() => { throw new Error('API Error'); }); - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); const connector = new BedrockConnector({ @@ -89,7 +89,7 @@ describe('BedrockConnector', () => { describe('runApi', () => { it('the aws signature has non-streaming headers', async () => { - await connector.runApi({ body: DEFAULT_BODY }, new ConnectorMetricsService()); + await connector.runApi({ body: DEFAULT_BODY }, new ConnectorMetricsCollector()); expect(mockSigner).toHaveBeenCalledWith( { body: DEFAULT_BODY, @@ -105,7 +105,7 @@ describe('BedrockConnector', () => { ); }); it('the Bedrock API call is successful with Claude 3 parameters; returns the response formatted for Claude 2 along with usage object', async () => { - const response = await connector.runApi({ body: DEFAULT_BODY }, connectorMetricsService); + const response = await connector.runApi({ body: DEFAULT_BODY }, connectorMetricsCollector); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( { @@ -116,7 +116,7 @@ describe('BedrockConnector', () => { responseSchema: RunApiLatestResponseSchema, data: DEFAULT_BODY, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual({ ...claude2Response, @@ -135,7 +135,7 @@ describe('BedrockConnector', () => { }); // @ts-ignore connector.request = mockRequest; - const response = await connector.runApi({ body: v2Body }, connectorMetricsService); + const response = await connector.runApi({ body: v2Body }, connectorMetricsCollector); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( { @@ -146,7 +146,7 @@ describe('BedrockConnector', () => { responseSchema: RunActionResponseSchema, data: v2Body, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual(claude2Response); }); @@ -156,7 +156,7 @@ describe('BedrockConnector', () => { connector.request = mockError; await expect( - connector.runApi({ body: DEFAULT_BODY }, new ConnectorMetricsService()) + connector.runApi({ body: DEFAULT_BODY }, new ConnectorMetricsCollector()) ).rejects.toThrow('API Error'); }); }); @@ -182,7 +182,7 @@ describe('BedrockConnector', () => { }; it('the aws signature has streaming headers', async () => { - await connector.invokeStream(aiAssistantBody, connectorMetricsService); + await connector.invokeStream(aiAssistantBody, connectorMetricsCollector); expect(mockSigner).toHaveBeenCalledWith( { @@ -201,7 +201,7 @@ describe('BedrockConnector', () => { }); it('the API call is successful with correct request parameters', async () => { - await connector.invokeStream(aiAssistantBody, connectorMetricsService); + await connector.invokeStream(aiAssistantBody, connectorMetricsCollector); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( { @@ -212,7 +212,7 @@ describe('BedrockConnector', () => { responseType: 'stream', data: JSON.stringify({ ...JSON.parse(DEFAULT_BODY), temperature: 0 }), }, - connectorMetricsService + connectorMetricsCollector ); }); @@ -221,7 +221,7 @@ describe('BedrockConnector', () => { const timeout = 180000; await connector.invokeStream( { ...aiAssistantBody, timeout, signal }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toHaveBeenCalledWith( @@ -235,7 +235,7 @@ describe('BedrockConnector', () => { timeout, signal, }, - connectorMetricsService + connectorMetricsCollector ); }); @@ -261,7 +261,7 @@ describe('BedrockConnector', () => { }, ], }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toHaveBeenCalledWith( { @@ -282,7 +282,7 @@ describe('BedrockConnector', () => { temperature: 0, }), }, - connectorMetricsService + connectorMetricsCollector ); }); @@ -316,7 +316,7 @@ describe('BedrockConnector', () => { }, ], }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toHaveBeenCalledWith( { @@ -336,7 +336,7 @@ describe('BedrockConnector', () => { temperature: 0, }), }, - connectorMetricsService + connectorMetricsCollector ); }); @@ -365,7 +365,7 @@ describe('BedrockConnector', () => { ], model: modelOverride, }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toHaveBeenCalledWith( { @@ -386,12 +386,12 @@ describe('BedrockConnector', () => { temperature: 0, }), }, - connectorMetricsService + connectorMetricsCollector ); }); it('responds with a readable stream', async () => { - const response = await connector.invokeStream(aiAssistantBody, connectorMetricsService); + const response = await connector.invokeStream(aiAssistantBody, connectorMetricsCollector); expect(response instanceof PassThrough).toEqual(true); }); @@ -400,7 +400,7 @@ describe('BedrockConnector', () => { connector.request = mockError; await expect( - connector.invokeStream(aiAssistantBody, connectorMetricsService) + connector.invokeStream(aiAssistantBody, connectorMetricsCollector) ).rejects.toThrow('API Error'); }); }); @@ -417,7 +417,7 @@ describe('BedrockConnector', () => { }; it('the API call is successful with correct parameters', async () => { - const response = await connector.invokeAI(aiAssistantBody, connectorMetricsService); + const response = await connector.invokeAI(aiAssistantBody, connectorMetricsCollector); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( { @@ -433,7 +433,7 @@ describe('BedrockConnector', () => { temperature: 0, }), }, - connectorMetricsService + connectorMetricsCollector ); expect(response.message).toEqual(mockResponseString); }); @@ -460,7 +460,7 @@ describe('BedrockConnector', () => { }, ], }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -482,7 +482,7 @@ describe('BedrockConnector', () => { temperature: 0, }), }, - connectorMetricsService + connectorMetricsCollector ); expect(response.message).toEqual(mockResponseString); }); @@ -506,7 +506,7 @@ describe('BedrockConnector', () => { ], system: 'This is a system message', }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -528,7 +528,7 @@ describe('BedrockConnector', () => { temperature: 0, }), }, - connectorMetricsService + connectorMetricsCollector ); expect(response.message).toEqual(mockResponseString); }); @@ -556,7 +556,7 @@ describe('BedrockConnector', () => { ], system: 'This is a system message', }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -578,14 +578,17 @@ describe('BedrockConnector', () => { temperature: 0, }), }, - connectorMetricsService + connectorMetricsCollector ); expect(response.message).toEqual(mockResponseString); }); it('signal and timeout is properly passed to runApi', async () => { const signal = jest.fn(); const timeout = 180000; - await connector.invokeAI({ ...aiAssistantBody, timeout, signal }, connectorMetricsService); + await connector.invokeAI( + { ...aiAssistantBody, timeout, signal }, + connectorMetricsCollector + ); expect(mockRequest).toHaveBeenCalledWith( { @@ -602,16 +605,16 @@ describe('BedrockConnector', () => { timeout, signal, }, - connectorMetricsService + connectorMetricsCollector ); }); it('errors during API calls are properly handled', async () => { // @ts-ignore connector.request = mockError; - await expect(connector.invokeAI(aiAssistantBody, connectorMetricsService)).rejects.toThrow( - 'API Error' - ); + await expect( + connector.invokeAI(aiAssistantBody, connectorMetricsCollector) + ).rejects.toThrow('API Error'); }); }); describe('getResponseErrorMessage', () => { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.ts b/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.ts index c9c4a3404d6ae..c79827df550bc 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.ts @@ -11,7 +11,7 @@ import { AxiosError, Method } from 'axios'; import { IncomingMessage } from 'http'; import { PassThrough } from 'stream'; import { SubActionRequestParams } from '@kbn/actions-plugin/server/sub_action_framework/types'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; import { initDashboard } from '../lib/gen_ai/create_gen_ai_dashboard'; import { RunActionParamsSchema, @@ -186,17 +186,17 @@ The Kibana Connector in use may need to be reconfigured with an updated Amazon B private async runApiDeprecated( params: SubActionRequestParams, // : SubActionRequestParams - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { - const response = await this.request(params, connectorMetricsService); + const response = await this.request(params, connectorMetricsCollector); return response.data; } private async runApiLatest( params: SubActionRequestParams, // : SubActionRequestParams - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { - const response = await this.request(params, connectorMetricsService); + const response = await this.request(params, connectorMetricsCollector); // keeping the response the same as claude 2 for our APIs // adding the usage object for better token tracking return { @@ -213,7 +213,7 @@ The Kibana Connector in use may need to be reconfigured with an updated Amazon B */ public async runApi( { body, model: reqModel, signal, timeout }: RunActionParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { // set model on per request basis const currentModel = reqModel ?? this.model; @@ -232,12 +232,12 @@ The Kibana Connector in use may need to be reconfigured with an updated Amazon B if (usesDeprecatedArguments(body)) { return this.runApiDeprecated( { ...requestArgs, responseSchema: RunActionResponseSchema }, - connectorMetricsService + connectorMetricsCollector ); } return this.runApiLatest( { ...requestArgs, responseSchema: RunApiLatestResponseSchema }, - connectorMetricsService + connectorMetricsCollector ); } @@ -251,7 +251,7 @@ The Kibana Connector in use may need to be reconfigured with an updated Amazon B */ private async streamApi( { body, model: reqModel, signal, timeout }: RunActionParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { // set model on per request basis const path = `/model/${reqModel ?? this.model}/invoke-with-response-stream`; @@ -268,7 +268,7 @@ The Kibana Connector in use may need to be reconfigured with an updated Amazon B signal, timeout, }, - connectorMetricsService + connectorMetricsCollector ); return response.data.pipe(new PassThrough()); @@ -284,7 +284,7 @@ The Kibana Connector in use may need to be reconfigured with an updated Amazon B */ public async invokeStream( { messages, model, stopSequences, system, temperature, signal, timeout }: InvokeAIActionParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const res = (await this.streamApi( { @@ -293,7 +293,7 @@ The Kibana Connector in use may need to be reconfigured with an updated Amazon B signal, timeout, }, - connectorMetricsService + connectorMetricsCollector )) as unknown as IncomingMessage; return res; } @@ -317,7 +317,7 @@ The Kibana Connector in use may need to be reconfigured with an updated Amazon B signal, timeout, }: InvokeAIActionParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const res = await this.runApi( { @@ -328,7 +328,7 @@ The Kibana Connector in use may need to be reconfigured with an updated Amazon B signal, timeout, }, - connectorMetricsService + connectorMetricsCollector ); return { message: res.completion.trim() }; } diff --git a/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/index.ts index a9964b4106eca..431fb3ed7984b 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/index.ts @@ -70,7 +70,8 @@ export async function executor( CasesWebhookActionParamsType > ): Promise> { - const { actionId, configurationUtilities, params, logger, connectorMetricsService } = execOptions; + const { actionId, configurationUtilities, params, logger, connectorMetricsCollector } = + execOptions; const { subAction, subActionParams } = params; let data: CasesWebhookExecutorResultData | undefined; @@ -82,7 +83,7 @@ export async function executor( }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); if (!api[subAction]) { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/service.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/service.test.ts index ff06844c34952..7d1ea93b662db 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/service.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/service.test.ts @@ -13,7 +13,7 @@ import { CasesWebhookPublicConfigurationType, ExternalService } from './types'; import { Logger } from '@kbn/core/server'; import { loggingSystemMock } from '@kbn/core/server/mocks'; import { actionsConfigMock } from '@kbn/actions-plugin/server/actions_config.mock'; -import { ConnectorMetricsService, getBasicAuthHeader } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector, getBasicAuthHeader } from '@kbn/actions-plugin/server/lib'; import { AuthType, WebhookMethods, SSLCertType } from '../../../common/auth/constants'; import { CRT_FILE, KEY_FILE } from '../../../common/auth/mocks'; @@ -69,14 +69,14 @@ const sslConfig: CasesWebhookPublicConfigurationType = { hasAuth: true, }; const sslSecrets = { crt: CRT_FILE, key: KEY_FILE, password: 'foobar', user: null, pfx: null }; -let connectorMetricsService: ConnectorMetricsService; +let connectorMetricsCollector: ConnectorMetricsCollector; describe('Cases webhook service', () => { let service: ExternalService; let sslService: ExternalService; beforeAll(() => { - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); service = createExternalService( actionId, { @@ -85,7 +85,7 @@ describe('Cases webhook service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); sslService = createExternalService( @@ -96,7 +96,7 @@ describe('Cases webhook service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); jest.useFakeTimers(); jest.setSystemTime(mockTime); @@ -126,7 +126,7 @@ describe('Cases webhook service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ) ).toThrow(); }); @@ -141,7 +141,7 @@ describe('Cases webhook service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ) ).toThrow(); }); @@ -156,7 +156,7 @@ describe('Cases webhook service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ) ).not.toThrow(); }); @@ -170,7 +170,7 @@ describe('Cases webhook service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); expect(axios.create).toHaveBeenCalledWith({ @@ -191,7 +191,7 @@ describe('Cases webhook service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); expect(axios.create).toHaveBeenCalledWith({ @@ -234,7 +234,7 @@ describe('Cases webhook service', () => { logger, configurationUtilities, sslOverrides: defaultSSLOverrides, - connectorMetricsService: expect.any(ConnectorMetricsService), + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); }); @@ -248,7 +248,7 @@ describe('Cases webhook service', () => { expect(requestMock.mock.calls[0][0]).toMatchInlineSnapshot(` Object { "axios": [Function], - "connectorMetricsService": ConnectorMetricsService { + "connectorMetricsCollector": ConnectorMetricsCollector { "metrics": Object { "requestBodyBytes": 0, }, @@ -496,7 +496,7 @@ describe('Cases webhook service', () => { configurationUtilities, sslOverrides: defaultSSLOverrides, data: `{"fields":{"title":"title","description":"desc","tags":["hello","world"],"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}`, - connectorMetricsService: expect.any(ConnectorMetricsService), + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); }); @@ -526,7 +526,7 @@ describe('Cases webhook service', () => { expect(requestMock.mock.calls[0][0]).toMatchInlineSnapshot(` Object { "axios": [Function], - "connectorMetricsService": ConnectorMetricsService { + "connectorMetricsCollector": ConnectorMetricsCollector { "metrics": Object { "requestBodyBytes": 0, }, @@ -777,7 +777,7 @@ describe('Cases webhook service', () => { issuetype: { id: '10024' }, }, }), - connectorMetricsService: expect.any(ConnectorMetricsService), + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); }); @@ -798,7 +798,7 @@ describe('Cases webhook service', () => { expect(requestMock.mock.calls[0][0]).toMatchInlineSnapshot(` Object { "axios": [Function], - "connectorMetricsService": ConnectorMetricsService { + "connectorMetricsCollector": ConnectorMetricsCollector { "metrics": Object { "requestBodyBytes": 0, }, @@ -1011,7 +1011,7 @@ describe('Cases webhook service', () => { sslOverrides: defaultSSLOverrides, url: 'https://coolsite.net/issue/1/comment', data: `{"body":"comment"}`, - connectorMetricsService: expect.any(ConnectorMetricsService), + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); }); @@ -1032,7 +1032,7 @@ describe('Cases webhook service', () => { expect(requestMock.mock.calls[0][0]).toMatchInlineSnapshot(` Object { "axios": [Function], - "connectorMetricsService": ConnectorMetricsService { + "connectorMetricsCollector": ConnectorMetricsCollector { "metrics": Object { "requestBodyBytes": 0, }, @@ -1210,7 +1210,7 @@ describe('Cases webhook service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); const res = await service.createComment(commentReq); expect(requestMock).not.toHaveBeenCalled(); @@ -1226,7 +1226,7 @@ describe('Cases webhook service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); const res = await service.createComment(commentReq); expect(requestMock).not.toHaveBeenCalled(); @@ -1253,7 +1253,7 @@ describe('Cases webhook service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); await service.createComment(commentReq); expect(requestMock).toHaveBeenCalledWith({ @@ -1264,7 +1264,7 @@ describe('Cases webhook service', () => { url: 'https://coolsite.net/issue/1/comment', data: `{"body":"comment","id":"1"}`, sslOverrides: defaultSSLOverrides, - connectorMetricsService: expect.any(ConnectorMetricsService), + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); }); @@ -1295,7 +1295,7 @@ describe('Cases webhook service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); await service.createComment(commentReq2); expect(requestMock).toHaveBeenCalledWith({ @@ -1306,7 +1306,7 @@ describe('Cases webhook service', () => { url: 'https://coolsite.net/issue/1/comment', data: `{"body":"comment","id":1}`, sslOverrides: defaultSSLOverrides, - connectorMetricsService: expect.any(ConnectorMetricsService), + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); }); }); @@ -1326,7 +1326,7 @@ describe('Cases webhook service', () => { throw new Error('Uri not allowed'); }), }, - connectorMetricsService + connectorMetricsCollector ); }); @@ -1401,7 +1401,7 @@ describe('Cases webhook service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); }); @@ -1472,7 +1472,7 @@ describe('Cases webhook service', () => { { ...configurationUtilities, }, - connectorMetricsService + connectorMetricsCollector ); requestMock.mockImplementation(() => createAxiosResponse({ diff --git a/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/service.ts b/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/service.ts index ac5b132c100cb..c5fdb53e5e7e0 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/service.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/service.ts @@ -13,7 +13,7 @@ import { request } from '@kbn/actions-plugin/server/lib/axios_utils'; import { ActionsConfigurationUtilities } from '@kbn/actions-plugin/server/actions_config'; import { combineHeadersWithBasicAuthHeader, - ConnectorMetricsService, + ConnectorMetricsCollector, } from '@kbn/actions-plugin/server/lib'; import { buildConnectorAuth, validateConnectorAuthConfiguration } from '../../../common/auth/utils'; import { validateAndNormalizeUrl, validateJson } from './validators'; @@ -42,7 +42,7 @@ export const createExternalService = ( { config, secrets }: ExternalServiceCredentials, logger: Logger, configurationUtilities: ActionsConfigurationUtilities, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): ExternalService => { const { createCommentJson, @@ -121,7 +121,7 @@ export const createExternalService = ( logger, configurationUtilities, sslOverrides, - connectorMetricsService, + connectorMetricsCollector, }); throwDescriptiveErrorIfResponseIsNotValid({ @@ -167,7 +167,7 @@ export const createExternalService = ( data: json, configurationUtilities, sslOverrides, - connectorMetricsService, + connectorMetricsCollector, }); const { status, statusText, data } = res; @@ -252,7 +252,7 @@ export const createExternalService = ( data: json, configurationUtilities, sslOverrides, - connectorMetricsService, + connectorMetricsCollector, }); throwDescriptiveErrorIfResponseIsNotValid({ @@ -326,7 +326,7 @@ export const createExternalService = ( data: json, configurationUtilities, sslOverrides, - connectorMetricsService, + connectorMetricsCollector, }); throwDescriptiveErrorIfResponseIsNotValid({ diff --git a/x-pack/plugins/stack_connectors/server/connector_types/crowdstrike/crowdstrike.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/crowdstrike/crowdstrike.test.ts index 64a98b43bc5e8..1eb1d89d09c6a 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/crowdstrike/crowdstrike.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/crowdstrike/crowdstrike.test.ts @@ -10,7 +10,7 @@ import { actionsConfigMock } from '@kbn/actions-plugin/server/actions_config.moc import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { actionsMock } from '@kbn/actions-plugin/server/mocks'; import { CROWDSTRIKE_CONNECTOR_ID } from '../../../public/common'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; const tokenPath = 'https://api.crowdstrike.com/oauth2/token'; const hostPath = 'https://api.crowdstrike.com/devices/entities/devices/v2'; @@ -26,14 +26,14 @@ describe('CrowdstrikeConnector', () => { services: actionsMock.createServices(), }); let mockedRequest: jest.Mock; - let connectorMetricsService: ConnectorMetricsService; + let connectorMetricsCollector: ConnectorMetricsCollector; beforeEach(() => { // @ts-expect-error private static - but I still want to reset it CrowdstrikeConnector.token = null; // @ts-expect-error mockedRequest = connector.request = jest.fn() as jest.Mock; - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); afterEach(() => { jest.clearAllMocks(); @@ -51,7 +51,7 @@ describe('CrowdstrikeConnector', () => { command: 'contain', ids: ['id1', 'id2'], }, - connectorMetricsService + connectorMetricsCollector ); expect(mockedRequest).toHaveBeenNthCalledWith( 1, @@ -65,7 +65,7 @@ describe('CrowdstrikeConnector', () => { responseSchema: expect.any(Object), url: tokenPath, }), - connectorMetricsService + connectorMetricsCollector ); expect(mockedRequest).toHaveBeenNthCalledWith( 2, @@ -77,7 +77,7 @@ describe('CrowdstrikeConnector', () => { paramsSerializer: expect.any(Function), responseSchema: expect.any(Object), }), - connectorMetricsService + connectorMetricsCollector ); expect(result).toEqual({ id: 'testid', path: 'testpath' }); }); @@ -92,7 +92,7 @@ describe('CrowdstrikeConnector', () => { const result = await connector.getAgentDetails( { ids: ['id1', 'id2'] }, - connectorMetricsService + connectorMetricsCollector ); expect(mockedRequest).toHaveBeenNthCalledWith( @@ -107,7 +107,7 @@ describe('CrowdstrikeConnector', () => { responseSchema: expect.any(Object), url: tokenPath, }), - connectorMetricsService + connectorMetricsCollector ); expect(mockedRequest).toHaveBeenNthCalledWith( 2, @@ -121,7 +121,7 @@ describe('CrowdstrikeConnector', () => { responseSchema: expect.any(Object), url: hostPath, }), - connectorMetricsService + connectorMetricsCollector ); expect(result).toEqual({ resources: [{}] }); }); @@ -136,7 +136,7 @@ describe('CrowdstrikeConnector', () => { const result = await connector.getAgentOnlineStatus( { ids: ['id1', 'id2'] }, - connectorMetricsService + connectorMetricsCollector ); expect(mockedRequest).toHaveBeenNthCalledWith( @@ -151,7 +151,7 @@ describe('CrowdstrikeConnector', () => { responseSchema: expect.any(Object), url: tokenPath, }), - connectorMetricsService + connectorMetricsCollector ); expect(mockedRequest).toHaveBeenNthCalledWith( 2, @@ -165,7 +165,7 @@ describe('CrowdstrikeConnector', () => { responseSchema: expect.any(Object), url: onlineStatusPath, }), - connectorMetricsService + connectorMetricsCollector ); expect(result).toEqual({ resources: [{}] }); }); @@ -244,7 +244,7 @@ describe('CrowdstrikeConnector', () => { mockedRequest.mockResolvedValueOnce(mockResponse); // @ts-expect-error private method - but I still want to - const result = await connector.getTokenRequest(connectorMetricsService); + const result = await connector.getTokenRequest(connectorMetricsCollector); expect(mockedRequest).toHaveBeenCalledWith( expect.objectContaining({ @@ -256,7 +256,7 @@ describe('CrowdstrikeConnector', () => { authorization: expect.stringContaining('Basic'), }, }), - connectorMetricsService + connectorMetricsCollector ); expect(result).toEqual('testToken'); }); @@ -266,7 +266,7 @@ describe('CrowdstrikeConnector', () => { mockedRequest.mockResolvedValueOnce({ data: { access_token: 'testToken' } }); mockedRequest.mockResolvedValue(mockResponse); - await connector.getAgentDetails({ ids: ['id1', 'id2'] }, connectorMetricsService); + await connector.getAgentDetails({ ids: ['id1', 'id2'] }, connectorMetricsCollector); expect(mockedRequest).toHaveBeenNthCalledWith( 1, @@ -280,7 +280,7 @@ describe('CrowdstrikeConnector', () => { responseSchema: expect.any(Object), url: tokenPath, }), - connectorMetricsService + connectorMetricsCollector ); expect(mockedRequest).toHaveBeenNthCalledWith( 2, @@ -294,10 +294,10 @@ describe('CrowdstrikeConnector', () => { responseSchema: expect.any(Object), url: hostPath, }), - connectorMetricsService + connectorMetricsCollector ); expect(mockedRequest).toHaveBeenCalledTimes(2); - await connector.getAgentDetails({ ids: ['id1', 'id2'] }, connectorMetricsService); + await connector.getAgentDetails({ ids: ['id1', 'id2'] }, connectorMetricsCollector); expect(mockedRequest).toHaveBeenNthCalledWith( 3, expect.objectContaining({ @@ -310,7 +310,7 @@ describe('CrowdstrikeConnector', () => { responseSchema: expect.any(Object), url: hostPath, }), - connectorMetricsService + connectorMetricsCollector ); expect(mockedRequest).toHaveBeenCalledTimes(3); }); @@ -321,7 +321,7 @@ describe('CrowdstrikeConnector', () => { mockedRequest.mockRejectedValueOnce(mockResponse); await expect(() => - connector.getAgentDetails({ ids: ['id1', 'id2'] }, connectorMetricsService) + connector.getAgentDetails({ ids: ['id1', 'id2'] }, connectorMetricsCollector) ).rejects.toThrowError('something goes wrong'); expect(mockedRequest).toHaveBeenCalledTimes(2); }); @@ -332,7 +332,7 @@ describe('CrowdstrikeConnector', () => { mockedRequest.mockRejectedValueOnce(mockResponse); await expect(() => - connector.getAgentDetails({ ids: ['id1', 'id2'] }, connectorMetricsService) + connector.getAgentDetails({ ids: ['id1', 'id2'] }, connectorMetricsCollector) ).rejects.toThrowError(); expect(mockedRequest).toHaveBeenCalledTimes(3); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/crowdstrike/crowdstrike.ts b/x-pack/plugins/stack_connectors/server/connector_types/crowdstrike/crowdstrike.ts index 0ffaf72d06db0..15299c2e159b9 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/crowdstrike/crowdstrike.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/crowdstrike/crowdstrike.ts @@ -9,7 +9,7 @@ import { ServiceParams, SubActionConnector } from '@kbn/actions-plugin/server'; import type { AxiosError } from 'axios'; import { SubActionRequestParams } from '@kbn/actions-plugin/server/sub_action_framework/types'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; import { isAggregateError, NodeSystemError } from './types'; import type { CrowdstrikeConfig, @@ -99,7 +99,7 @@ export class CrowdstrikeConnector extends SubActionConnector< public async executeHostActions( { alertIds, ...payload }: CrowdstrikeHostActionsParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) { return this.crowdstrikeApiRequest( { @@ -124,13 +124,13 @@ export class CrowdstrikeConnector extends SubActionConnector< paramsSerializer, responseSchema: CrowdstrikeHostActionsResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ); } public async getAgentDetails( payload: CrowdstrikeGetAgentsParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { return this.crowdstrikeApiRequest( { @@ -142,13 +142,13 @@ export class CrowdstrikeConnector extends SubActionConnector< paramsSerializer, responseSchema: RelaxedCrowdstrikeBaseApiResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ) as Promise; } public async getAgentOnlineStatus( payload: CrowdstrikeGetAgentsParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { return this.crowdstrikeApiRequest( { @@ -160,11 +160,11 @@ export class CrowdstrikeConnector extends SubActionConnector< paramsSerializer, responseSchema: RelaxedCrowdstrikeBaseApiResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ) as Promise; } - private async getTokenRequest(connectorMetricsService: ConnectorMetricsService) { + private async getTokenRequest(connectorMetricsCollector: ConnectorMetricsCollector) { const response = await this.request( { url: this.urls.getToken, @@ -176,7 +176,7 @@ export class CrowdstrikeConnector extends SubActionConnector< }, responseSchema: CrowdstrikeGetTokenResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ); const token = response.data?.access_token; if (token) { @@ -193,13 +193,13 @@ export class CrowdstrikeConnector extends SubActionConnector< private async crowdstrikeApiRequest( req: SubActionRequestParams, - connectorMetricsService: ConnectorMetricsService, + connectorMetricsCollector: ConnectorMetricsCollector, retried?: boolean ): Promise { try { if (!CrowdstrikeConnector.token) { CrowdstrikeConnector.token = (await this.getTokenRequest( - connectorMetricsService + connectorMetricsCollector )) as string; } @@ -211,14 +211,14 @@ export class CrowdstrikeConnector extends SubActionConnector< Authorization: `Bearer ${CrowdstrikeConnector.token}`, }, }, - connectorMetricsService + connectorMetricsCollector ); return response.data; } catch (error) { if (error.code === 401 && !retried) { CrowdstrikeConnector.token = null; - return this.crowdstrikeApiRequest(req, connectorMetricsService, true); + return this.crowdstrikeApiRequest(req, connectorMetricsCollector, true); } throw new CrowdstrikeError(error.message); } diff --git a/x-pack/plugins/stack_connectors/server/connector_types/d3security/d3security.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/d3security/d3security.test.ts index 1999efb922d26..4dd4fdcf7abcf 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/d3security/d3security.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/d3security/d3security.test.ts @@ -11,7 +11,7 @@ import { D3_SECURITY_CONNECTOR_ID } from '../../../common/d3security/constants'; import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { actionsMock } from '@kbn/actions-plugin/server/mocks'; import { D3SecurityRunActionResponseSchema } from '../../../common/d3security/schema'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; describe('D3SecurityConnector', () => { const sampleBody = JSON.stringify({ @@ -39,16 +39,16 @@ describe('D3SecurityConnector', () => { logger: loggingSystemMock.createLogger(), services: actionsMock.createServices(), }); - let connectorMetricsService: ConnectorMetricsService; + let connectorMetricsCollector: ConnectorMetricsCollector; beforeEach(() => { // @ts-ignore connector.request = mockRequest; jest.clearAllMocks(); - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); it('the D3 Security API call is successful with correct parameters', async () => { - const response = await connector.runApi({ body: sampleBody }, connectorMetricsService); + const response = await connector.runApi({ body: sampleBody }, connectorMetricsCollector); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( { @@ -60,7 +60,7 @@ describe('D3SecurityConnector', () => { d3key: '123', }, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual({ result: 'success' }); }); @@ -69,9 +69,9 @@ describe('D3SecurityConnector', () => { // @ts-ignore connector.request = mockError; - await expect(connector.runApi({ body: sampleBody }, connectorMetricsService)).rejects.toThrow( - 'API Error' - ); + await expect( + connector.runApi({ body: sampleBody }, connectorMetricsCollector) + ).rejects.toThrow('API Error'); }); }); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/d3security/d3security.ts b/x-pack/plugins/stack_connectors/server/connector_types/d3security/d3security.ts index c2c08ccbe6830..d92ed428440d9 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/d3security/d3security.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/d3security/d3security.ts @@ -7,7 +7,7 @@ import { ServiceParams, SubActionConnector } from '@kbn/actions-plugin/server'; import type { AxiosError } from 'axios'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; import { addSeverityAndEventTypeInBody } from './helpers'; import { D3SecurityRunActionParamsSchema, @@ -60,7 +60,7 @@ export class D3SecurityConnector extends SubActionConnector { const response = await this.request( { @@ -74,7 +74,7 @@ export class D3SecurityConnector extends SubActionConnector { text: 'Go to Elastic', }, }; - const connectorMetricsService = new ConnectorMetricsService(); + const connectorMetricsCollector = new ConnectorMetricsCollector(); const actionId = 'some-id'; const executorOptions: EmailConnectorTypeExecutorOptions = { @@ -526,7 +526,7 @@ describe('execute()', () => { services, configurationUtilities: actionsConfigMock.create(), logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }; beforeEach(() => { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/email/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/email/index.ts index c173da89eb9c4..da22352b7af36 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/email/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/email/index.ts @@ -282,7 +282,7 @@ async function executor( configurationUtilities, services, logger, - connectorMetricsService, + connectorMetricsCollector, } = execOptions; const connectorTokenClient = services.connectorTokenClient; @@ -378,7 +378,7 @@ async function executor( logger, sendEmailOptions, connectorTokenClient, - connectorMetricsService + connectorMetricsCollector ); } catch (err) { const message = i18n.translate('xpack.stackConnectors.email.errorSendingErrorMessage', { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.test.ts index e44bb0189b48d..573cd732bd01d 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.test.ts @@ -10,7 +10,7 @@ import { Logger } from '@kbn/core/server'; import { sendEmail } from './send_email'; import { loggingSystemMock } from '@kbn/core/server/mocks'; import nodemailer from 'nodemailer'; -import { ConnectorMetricsService, ProxySettings } from '@kbn/actions-plugin/server/types'; +import { ConnectorMetricsCollector, ProxySettings } from '@kbn/actions-plugin/server/types'; import { actionsConfigMock } from '@kbn/actions-plugin/server/actions_config.mock'; import { CustomHostSettings } from '@kbn/actions-plugin/server/config'; import { sendEmailGraphApi } from './send_email_graph_api'; @@ -39,7 +39,7 @@ const sendMailMock = jest.fn(); const mockLogger = loggingSystemMock.create().get() as jest.Mocked; const connectorTokenClient = connectorTokenClientMock.create(); -const getConnectorMetricsService = () => new ConnectorMetricsService(); +let connectorMetricsCollector: ConnectorMetricsCollector; describe('send_email module', () => { beforeEach(() => { @@ -54,6 +54,8 @@ describe('send_email module', () => { interceptors: mockAxiosInstanceInterceptor, }; }); + + connectorMetricsCollector = new ConnectorMetricsCollector(); }); test('handles authenticated email using service', async () => { @@ -62,7 +64,7 @@ describe('send_email module', () => { mockLogger, sendEmailOptions, connectorTokenClient, - getConnectorMetricsService() + connectorMetricsCollector ); expect(result).toBe(sendMailMockResult); expect(createTransportMock.mock.calls[0]).toMatchInlineSnapshot(` @@ -111,7 +113,7 @@ describe('send_email module', () => { mockLogger, sendEmailOptions, connectorTokenClient, - getConnectorMetricsService() + connectorMetricsCollector ); expect(result).toBe(sendMailMockResult); expect(createTransportMock.mock.calls[0]).toMatchInlineSnapshot(` @@ -170,12 +172,7 @@ describe('send_email module', () => { status: 202, }); - await sendEmail( - mockLogger, - sendEmailOptions, - connectorTokenClient, - getConnectorMetricsService() - ); + await sendEmail(mockLogger, sendEmailOptions, connectorTokenClient, connectorMetricsCollector); expect(getOAuthClientCredentialsAccessTokenMock).toHaveBeenCalledWith({ configurationUtilities: sendEmailOptions.configurationUtilities, connectorId: '1', @@ -271,12 +268,7 @@ describe('send_email module', () => { status: 202, }); - await sendEmail( - mockLogger, - sendEmailOptions, - connectorTokenClient, - getConnectorMetricsService() - ); + await sendEmail(mockLogger, sendEmailOptions, connectorTokenClient, connectorMetricsCollector); expect(getOAuthClientCredentialsAccessTokenMock).toHaveBeenCalledWith({ configurationUtilities: sendEmailOptions.configurationUtilities, connectorId: '1', @@ -314,12 +306,7 @@ describe('send_email module', () => { status: 202, }); - await sendEmail( - mockLogger, - sendEmailOptions, - connectorTokenClient, - getConnectorMetricsService() - ); + await sendEmail(mockLogger, sendEmailOptions, connectorTokenClient, connectorMetricsCollector); expect(getOAuthClientCredentialsAccessTokenMock).toHaveBeenCalledWith({ configurationUtilities: sendEmailOptions.configurationUtilities, connectorId: '1', @@ -349,7 +336,7 @@ describe('send_email module', () => { getOAuthClientCredentialsAccessTokenMock.mockReturnValueOnce(null); await expect(() => - sendEmail(mockLogger, sendEmailOptions, connectorTokenClient, getConnectorMetricsService()) + sendEmail(mockLogger, sendEmailOptions, connectorTokenClient, connectorMetricsCollector) ).rejects.toThrowErrorMatchingInlineSnapshot( `"Unable to retrieve access token for connectorId: 1"` ); @@ -393,7 +380,7 @@ describe('send_email module', () => { mockLogger, sendEmailOptions, connectorTokenClient, - getConnectorMetricsService() + connectorMetricsCollector ); expect(result).toBe(sendMailMockResult); expect(createTransportMock.mock.calls[0]).toMatchInlineSnapshot(` @@ -448,7 +435,7 @@ describe('send_email module', () => { mockLogger, sendEmailOptions, connectorTokenClient, - getConnectorMetricsService() + connectorMetricsCollector ); expect(result).toBe(sendMailMockResult); expect(createTransportMock.mock.calls[0]).toMatchInlineSnapshot(` @@ -503,7 +490,7 @@ describe('send_email module', () => { mockLogger, sendEmailOptions, connectorTokenClient, - getConnectorMetricsService() + connectorMetricsCollector ); expect(result).toBe(sendMailMockResult); expect(createTransportMock.mock.calls[0]).toMatchInlineSnapshot(` @@ -546,7 +533,7 @@ describe('send_email module', () => { sendMailMock.mockRejectedValue(new Error('wops')); await expect( - sendEmail(mockLogger, sendEmailOptions, connectorTokenClient, getConnectorMetricsService()) + sendEmail(mockLogger, sendEmailOptions, connectorTokenClient, connectorMetricsCollector) ).rejects.toThrow('wops'); }); @@ -572,7 +559,7 @@ describe('send_email module', () => { mockLogger, sendEmailOptions, connectorTokenClient, - getConnectorMetricsService() + connectorMetricsCollector ); expect(result).toBe(sendMailMockResult); expect(createTransportMock.mock.calls[0]).toMatchInlineSnapshot(` @@ -611,7 +598,7 @@ describe('send_email module', () => { mockLogger, sendEmailOptions, connectorTokenClient, - getConnectorMetricsService() + connectorMetricsCollector ); expect(result).toBe(sendMailMockResult); expect(createTransportMock.mock.calls[0]).toMatchInlineSnapshot(` @@ -652,7 +639,7 @@ describe('send_email module', () => { mockLogger, sendEmailOptions, connectorTokenClient, - getConnectorMetricsService() + connectorMetricsCollector ); expect(result).toBe(sendMailMockResult); expect(createTransportMock.mock.calls[0]).toMatchInlineSnapshot(` @@ -691,7 +678,7 @@ describe('send_email module', () => { mockLogger, sendEmailOptions, connectorTokenClient, - getConnectorMetricsService() + connectorMetricsCollector ); expect(result).toBe(sendMailMockResult); expect(createTransportMock.mock.calls[0]).toMatchInlineSnapshot(` @@ -733,7 +720,7 @@ describe('send_email module', () => { mockLogger, sendEmailOptions, connectorTokenClient, - getConnectorMetricsService() + connectorMetricsCollector ); expect(result).toBe(sendMailMockResult); @@ -781,7 +768,7 @@ describe('send_email module', () => { mockLogger, sendEmailOptions, connectorTokenClient, - getConnectorMetricsService() + connectorMetricsCollector ); expect(result).toBe(sendMailMockResult); @@ -833,7 +820,7 @@ describe('send_email module', () => { mockLogger, sendEmailOptions, connectorTokenClient, - getConnectorMetricsService() + connectorMetricsCollector ); expect(result).toBe(sendMailMockResult); expect(createTransportMock.mock.calls[0]).toMatchInlineSnapshot(` @@ -868,12 +855,7 @@ describe('send_email module', () => { 'Bearer clienttokentokentoken' ); - await sendEmail( - mockLogger, - sendEmailOptions, - connectorTokenClient, - getConnectorMetricsService() - ); + await sendEmail(mockLogger, sendEmailOptions, connectorTokenClient, connectorMetricsCollector); expect(createAxiosInstanceMock).toHaveBeenCalledTimes(1); expect(createAxiosInstanceMock).toHaveBeenCalledWith(); expect(mockAxiosInstanceInterceptor.response.use).toHaveBeenCalledTimes(1); @@ -916,12 +898,7 @@ describe('send_email module', () => { 'Bearer clienttokentokentoken' ); - await sendEmail( - mockLogger, - sendEmailOptions, - connectorTokenClient, - getConnectorMetricsService() - ); + await sendEmail(mockLogger, sendEmailOptions, connectorTokenClient, connectorMetricsCollector); expect(createAxiosInstanceMock).toHaveBeenCalledTimes(1); expect(createAxiosInstanceMock).toHaveBeenCalledWith(); expect(mockAxiosInstanceInterceptor.response.use).toHaveBeenCalledTimes(1); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.ts b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.ts index 5058d8ade2003..377a0bfe50a02 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.ts @@ -18,7 +18,7 @@ import { getSSLSettingsFromConfig, } from '@kbn/actions-plugin/server/lib/get_node_ssl_options'; import { - ConnectorMetricsService, + ConnectorMetricsCollector, ConnectorTokenClientContract, ProxySettings, } from '@kbn/actions-plugin/server/types'; @@ -71,7 +71,7 @@ export async function sendEmail( logger: Logger, options: SendEmailOptions, connectorTokenClient: ConnectorTokenClientContract, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const { transport, content } = options; const { message, messageHTML } = content; @@ -84,10 +84,15 @@ export async function sendEmail( options, renderedMessage, connectorTokenClient, - connectorMetricsService + connectorMetricsCollector ); } else { - return await sendEmailWithNodemailer(logger, options, renderedMessage, connectorMetricsService); + return await sendEmailWithNodemailer( + logger, + options, + renderedMessage, + connectorMetricsCollector + ); } } @@ -97,7 +102,7 @@ export async function sendEmailWithExchange( options: SendEmailOptions, messageHTML: string, connectorTokenClient: ConnectorTokenClientContract, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const { transport, configurationUtilities, connectorId } = options; const { clientId, clientSecret, tenantId, oauthTokenUrl } = transport; @@ -167,7 +172,7 @@ export async function sendEmailWithExchange( }, logger, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, axiosInstance ); } @@ -177,7 +182,7 @@ async function sendEmailWithNodemailer( logger: Logger, options: SendEmailOptions, messageHTML: string, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const { transport, routing, content, configurationUtilities, hasAuth } = options; const { service } = transport; @@ -200,7 +205,7 @@ async function sendEmailWithNodemailer( // some deep properties, so need to use any here. const transportConfig = getTransportConfig(configurationUtilities, logger, transport, hasAuth); const nodemailerTransport = nodemailer.createTransport(transportConfig); - connectorMetricsService.addRequestBodyBytes(undefined, email); + connectorMetricsCollector.addRequestBodyBytes(undefined, email); const result = await nodemailerTransport.sendMail(email); if (service === JSON_TRANSPORT_SERVICE) { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts index 85303119b75f3..ef4e088dd2dab 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts @@ -14,7 +14,7 @@ import { Logger } from '@kbn/core/server'; import { loggingSystemMock } from '@kbn/core/server/mocks'; import { actionsConfigMock } from '@kbn/actions-plugin/server/actions_config.mock'; import { CustomHostSettings } from '@kbn/actions-plugin/server/config'; -import { ConnectorMetricsService, ProxySettings } from '@kbn/actions-plugin/server/types'; +import { ConnectorMetricsCollector, ProxySettings } from '@kbn/actions-plugin/server/types'; import { sendEmailGraphApi } from './send_email_graph_api'; const createAxiosInstanceMock = axios.create as jest.Mock; @@ -28,7 +28,7 @@ describe('sendEmailGraphApi', () => { const configurationUtilities = actionsConfigMock.create(); test('email contains the proper message', async () => { - const connectorMetricsService = new ConnectorMetricsService(); + const connectorMetricsCollector = new ConnectorMetricsCollector(); axiosInstanceMock.mockReturnValueOnce({ status: 202, @@ -41,7 +41,7 @@ describe('sendEmailGraphApi', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); expect(axiosInstanceMock.mock.calls[0]).toMatchInlineSnapshot(` Array [ @@ -121,7 +121,7 @@ describe('sendEmailGraphApi', () => { }); test('email was sent on behalf of the user "from" mailbox', async () => { - const connectorMetricsService = new ConnectorMetricsService(); + const connectorMetricsCollector = new ConnectorMetricsCollector(); axiosInstanceMock.mockReturnValueOnce({ status: 202, }); @@ -133,7 +133,7 @@ describe('sendEmailGraphApi', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); expect(axiosInstanceMock.mock.calls[1]).toMatchInlineSnapshot(` Array [ @@ -215,7 +215,7 @@ describe('sendEmailGraphApi', () => { }); test('sendMail request was sent to the custom configured Graph API URL', async () => { - const connectorMetricsService = new ConnectorMetricsService(); + const connectorMetricsCollector = new ConnectorMetricsCollector(); axiosInstanceMock.mockReturnValueOnce({ status: 202, }); @@ -228,7 +228,7 @@ describe('sendEmailGraphApi', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); expect(axiosInstanceMock.mock.calls[2]).toMatchInlineSnapshot(` Array [ @@ -308,7 +308,7 @@ describe('sendEmailGraphApi', () => { }); test('throw the exception and log the proper error if message was not sent successfuly', async () => { - const connectorMetricsService = new ConnectorMetricsService(); + const connectorMetricsCollector = new ConnectorMetricsCollector(); axiosInstanceMock.mockReturnValueOnce({ status: 400, data: { @@ -324,7 +324,7 @@ describe('sendEmailGraphApi', () => { { options: getSendEmailOptions(), messageHTML: 'test1', headers: {} }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ) ).rejects.toThrowErrorMatchingInlineSnapshot( '"{\\"error\\":{\\"code\\":\\"ErrorMimeContentInvalidBase64String\\",\\"message\\":\\"Invalid base64 string for MIME content.\\"}}"' diff --git a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.ts b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.ts index 104fe34bfea57..f0b7f3cdddb3c 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.ts @@ -11,14 +11,14 @@ import axios, { AxiosInstance, AxiosResponse } from 'axios'; import { Logger } from '@kbn/core/server'; import { request } from '@kbn/actions-plugin/server/lib/axios_utils'; import { ActionsConfigurationUtilities } from '@kbn/actions-plugin/server/actions_config'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; import { SendEmailOptions } from './send_email'; export async function sendEmailGraphApi( sendEmailOptions: SendEmailGraphApiOptions, logger: Logger, configurationUtilities: ActionsConfigurationUtilities, - connectorMetricsService: ConnectorMetricsService, + connectorMetricsCollector: ConnectorMetricsCollector, axiosInstance?: AxiosInstance ): Promise { const { options, headers, messageHTML } = sendEmailOptions; @@ -38,7 +38,7 @@ export async function sendEmailGraphApi( headers, configurationUtilities, validateStatus: () => true, - connectorMetricsService, + connectorMetricsCollector, }); if (res.status === 202) { return res.data; diff --git a/x-pack/plugins/stack_connectors/server/connector_types/es_index/index.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/es_index/index.test.ts index 2b3fab30432fa..636cbd8596027 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/es_index/index.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/es_index/index.test.ts @@ -6,7 +6,11 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { validateConfig, validateParams } from '@kbn/actions-plugin/server/lib'; +import { + ConnectorMetricsCollector, + validateConfig, + validateParams, +} from '@kbn/actions-plugin/server/lib'; import { actionsMock } from '@kbn/actions-plugin/server/mocks'; import { ActionParamsType, @@ -27,11 +31,13 @@ const mockedLogger: jest.Mocked = loggerMock.create(); let connectorType: ESIndexConnectorType; let configurationUtilities: ActionsConfigurationUtilities; +let connectorMetricsCollector: ConnectorMetricsCollector; beforeEach(() => { jest.resetAllMocks(); configurationUtilities = actionsConfigMock.create(); connectorType = getConnectorType(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); describe('connector registration', () => { @@ -185,6 +191,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, + connectorMetricsCollector, }; const scopedClusterClient = elasticsearchClientMock .createClusterClient() @@ -230,6 +237,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, + connectorMetricsCollector, }; scopedClusterClient.bulk.mockClear(); await connectorType.executor({ @@ -280,6 +288,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, + connectorMetricsCollector, }; scopedClusterClient.bulk.mockClear(); @@ -324,6 +333,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, + connectorMetricsCollector, }; scopedClusterClient.bulk.mockClear(); await connectorType.executor({ @@ -656,6 +666,7 @@ describe('execute()', () => { services: { ...services, scopedClusterClient }, configurationUtilities, logger: mockedLogger, + connectorMetricsCollector, }) ).toMatchInlineSnapshot(` Object { @@ -695,6 +706,7 @@ describe('execute()', () => { services: { ...services, scopedClusterClient }, configurationUtilities, logger: mockedLogger, + connectorMetricsCollector, }) ).toMatchInlineSnapshot(` Object { @@ -757,6 +769,7 @@ describe('execute()', () => { services: { ...services, scopedClusterClient }, configurationUtilities, logger: mockedLogger, + connectorMetricsCollector, }) ).toMatchInlineSnapshot(` Object { @@ -824,6 +837,7 @@ describe('execute()', () => { services: { ...services, scopedClusterClient }, configurationUtilities, logger: mockedLogger, + connectorMetricsCollector, }) ).toMatchInlineSnapshot(` Object { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/gemini/gemini.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/gemini/gemini.test.ts index d88f8f13d9970..85fa03faf345b 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/gemini/gemini.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/gemini/gemini.test.ts @@ -15,7 +15,7 @@ import { RunApiResponseSchema, StreamingResponseSchema } from '../../../common/g import { DEFAULT_GEMINI_MODEL } from '../../../common/gemini/constants'; import { AxiosError } from 'axios'; import { Transform } from 'stream'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; jest.mock('../lib/gen_ai/create_gen_ai_dashboard'); jest.mock('@kbn/actions-plugin/server/sub_action_framework/helpers/validators', () => ({ @@ -88,13 +88,13 @@ describe('GeminiConnector', () => { logger: loggingSystemMock.createLogger(), services: actionsMock.createServices(), }); - let connectorMetricsService: ConnectorMetricsService; + let connectorMetricsCollector: ConnectorMetricsCollector; describe('Gemini', () => { beforeEach(() => { // @ts-ignore connector.request = mockRequest; - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); describe('runApi', () => { @@ -104,7 +104,7 @@ describe('GeminiConnector', () => { model: DEFAULT_GEMINI_MODEL, }; - const response = await connector.runApi(runActionParams, connectorMetricsService); + const response = await connector.runApi(runActionParams, connectorMetricsCollector); // Assertions expect(mockRequest).toBeCalledTimes(1); @@ -132,7 +132,7 @@ describe('GeminiConnector', () => { responseSchema: RunApiResponseSchema, signal: undefined, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual(connectorResponse); @@ -150,7 +150,7 @@ describe('GeminiConnector', () => { }; it('the API call is successful with correct parameters', async () => { - await connector.invokeAI(aiAssistantBody, connectorMetricsService); + await connector.invokeAI(aiAssistantBody, connectorMetricsCollector); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( { @@ -176,14 +176,17 @@ describe('GeminiConnector', () => { signal: undefined, timeout: 60000, }, - connectorMetricsService + connectorMetricsCollector ); }); it('signal and timeout is properly passed to runApi', async () => { const signal = jest.fn(); const timeout = 60000; - await connector.invokeAI({ ...aiAssistantBody, timeout, signal }, connectorMetricsService); + await connector.invokeAI( + { ...aiAssistantBody, timeout, signal }, + connectorMetricsCollector + ); expect(mockRequest).toHaveBeenCalledWith( { url: `https://api.gemini.com/v1/projects/my-project-12345/locations/us-central1/publishers/google/models/${DEFAULT_GEMINI_MODEL}:generateContent`, @@ -208,7 +211,7 @@ describe('GeminiConnector', () => { signal, timeout: 60000, }, - connectorMetricsService + connectorMetricsCollector ); }); }); @@ -232,7 +235,7 @@ describe('GeminiConnector', () => { }; it('the API call is successful with correct request parameters', async () => { - await connector.invokeStream(aiAssistantBody, connectorMetricsService); + await connector.invokeStream(aiAssistantBody, connectorMetricsCollector); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( { @@ -259,7 +262,7 @@ describe('GeminiConnector', () => { signal: undefined, timeout: 60000, }, - connectorMetricsService + connectorMetricsCollector ); }); @@ -268,7 +271,7 @@ describe('GeminiConnector', () => { const timeout = 60000; await connector.invokeStream( { ...aiAssistantBody, timeout, signal }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toHaveBeenCalledWith( { @@ -295,7 +298,7 @@ describe('GeminiConnector', () => { signal, timeout: 60000, }, - connectorMetricsService + connectorMetricsCollector ); }); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/gemini/gemini.ts b/x-pack/plugins/stack_connectors/server/connector_types/gemini/gemini.ts index 335559a1b0ef7..523ecef34cba0 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/gemini/gemini.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/gemini/gemini.ts @@ -13,7 +13,7 @@ import { SubActionRequestParams } from '@kbn/actions-plugin/server/sub_action_fr import { getGoogleOAuthJwtAccessToken } from '@kbn/actions-plugin/server/lib/get_gcp_oauth_access_token'; import { Logger } from '@kbn/core/server'; import { - ConnectorMetricsService, + ConnectorMetricsCollector, ConnectorTokenClientContract, } from '@kbn/actions-plugin/server/types'; import { ActionsConfigurationUtilities } from '@kbn/actions-plugin/server/actions_config'; @@ -204,7 +204,7 @@ export class GeminiConnector extends SubActionConnector { */ public async runApi( { body, model: reqModel, signal, timeout }: RunActionParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { // set model on per request basis const currentModel = reqModel ?? this.model; @@ -224,7 +224,7 @@ export class GeminiConnector extends SubActionConnector { responseSchema: RunApiResponseSchema, } as SubActionRequestParams; - const response = await this.request(requestArgs, connectorMetricsService); + const response = await this.request(requestArgs, connectorMetricsCollector); const candidate = response.data.candidates[0]; const usageMetadata = response.data.usageMetadata; const completionText = candidate.content.parts[0].text; @@ -234,7 +234,7 @@ export class GeminiConnector extends SubActionConnector { private async streamAPI( { body, model: reqModel, signal, timeout }: RunActionParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const currentModel = reqModel ?? this.model; const path = `/v1/projects/${this.gcpProjectID}/locations/${this.gcpRegion}/publishers/google/models/${currentModel}:streamGenerateContent?alt=sse`; @@ -254,7 +254,7 @@ export class GeminiConnector extends SubActionConnector { signal, timeout: timeout ?? DEFAULT_TIMEOUT_MS, }, - connectorMetricsService + connectorMetricsCollector ); return response.data.pipe(new PassThrough()); @@ -262,7 +262,7 @@ export class GeminiConnector extends SubActionConnector { public async invokeAI( { messages, model, temperature = 0, signal, timeout }: InvokeAIActionParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const res = await this.runApi( { @@ -271,7 +271,7 @@ export class GeminiConnector extends SubActionConnector { signal, timeout, }, - connectorMetricsService + connectorMetricsCollector ); return { message: res.completion, usageMetadata: res.usageMetadata }; @@ -287,7 +287,7 @@ export class GeminiConnector extends SubActionConnector { */ public async invokeStream( { messages, model, stopSequences, temperature = 0, signal, timeout }: InvokeAIActionParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const res = (await this.streamAPI( { @@ -297,7 +297,7 @@ export class GeminiConnector extends SubActionConnector { signal, timeout, }, - connectorMetricsService + connectorMetricsCollector )) as unknown as IncomingMessage; return res; } diff --git a/x-pack/plugins/stack_connectors/server/connector_types/jira/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/jira/index.ts index 16e79ecedd74c..bcb9b79660741 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/jira/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/jira/index.ts @@ -102,7 +102,7 @@ async function executor( secrets, configurationUtilities, logger, - connectorMetricsService, + connectorMetricsCollector, } = execOptions; const { subAction, subActionParams } = params as ExecutorParams; let data: JiraExecutorResultData | null = null; @@ -114,7 +114,7 @@ async function executor( }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); if (!api[subAction]) { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/jira/service.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/jira/service.test.ts index 49c6c4459e8a1..74091388eee5f 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/jira/service.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/jira/service.test.ts @@ -14,7 +14,7 @@ import { Logger } from '@kbn/core/server'; import { loggingSystemMock } from '@kbn/core/server/mocks'; import { actionsConfigMock } from '@kbn/actions-plugin/server/actions_config.mock'; import { getBasicAuthHeader } from '@kbn/actions-plugin/server'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; const logger = loggingSystemMock.create().get() as jest.Mocked; interface ResponseError extends Error { @@ -136,10 +136,10 @@ const mockOldAPI = () => describe('Jira service', () => { let service: ExternalService; - let connectorMetricsService: ConnectorMetricsService; + let connectorMetricsCollector: ConnectorMetricsCollector; beforeAll(() => { - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); service = createExternalService( { // The trailing slash at the end of the url is intended. @@ -149,7 +149,7 @@ describe('Jira service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); }); @@ -167,7 +167,7 @@ describe('Jira service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ) ).toThrow(); }); @@ -181,7 +181,7 @@ describe('Jira service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ) ).toThrow(); }); @@ -195,7 +195,7 @@ describe('Jira service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ) ).toThrow(); }); @@ -209,7 +209,7 @@ describe('Jira service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ) ).toThrow(); }); @@ -222,7 +222,7 @@ describe('Jira service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); expect(axios.create).toHaveBeenCalledWith({ @@ -267,7 +267,7 @@ describe('Jira service', () => { url: 'https://coolsite.net/rest/api/2/issue/1', logger, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -411,7 +411,7 @@ describe('Jira service', () => { priority: { name: 'High' }, }, }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -470,7 +470,7 @@ describe('Jira service', () => { priority: { name: 'High' }, }, }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -504,7 +504,7 @@ describe('Jira service', () => { parent: { key: 'RJ-107' }, }, }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -574,7 +574,7 @@ describe('Jira service', () => { ...otherFields, }, }, - connectorMetricsService, + connectorMetricsCollector, }); }); }); @@ -645,7 +645,7 @@ describe('Jira service', () => { parent: { key: 'RJ-107' }, }, }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -708,7 +708,7 @@ describe('Jira service', () => { ...otherFields, }, }, - connectorMetricsService, + connectorMetricsCollector, }); }); }); @@ -762,7 +762,7 @@ describe('Jira service', () => { configurationUtilities, url: 'https://coolsite.net/rest/api/2/issue/1/comment', data: { body: 'comment' }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -819,7 +819,7 @@ describe('Jira service', () => { method: 'get', configurationUtilities, url: 'https://coolsite.net/rest/capabilities', - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -901,7 +901,7 @@ describe('Jira service', () => { method: 'get', configurationUtilities, url: 'https://coolsite.net/rest/api/2/issue/createmeta?projectKeys=CK&expand=projects.issuetypes.fields', - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -976,7 +976,7 @@ describe('Jira service', () => { method: 'get', configurationUtilities, url: 'https://coolsite.net/rest/api/2/issue/createmeta/CK/issuetypes', - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -1052,7 +1052,7 @@ describe('Jira service', () => { method: 'get', configurationUtilities, url: 'https://coolsite.net/rest/api/2/issue/createmeta?projectKeys=CK&issuetypeIds=10006&expand=projects.issuetypes.fields', - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -1261,7 +1261,7 @@ describe('Jira service', () => { method: 'get', configurationUtilities, url: `https://coolsite.net/rest/api/2/search?jql=project%3D%22CK%22%20and%20summary%20~%22Test%20title%22`, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -1288,7 +1288,7 @@ describe('Jira service', () => { method: 'get', configurationUtilities, url: `https://coolsite.net/rest/api/2/search?jql=project%3D%22CK%22%20and%20summary%20~%22%5C%5C%5Bth%5C%5C!s%5C%5C%5Eis%5C%5C(%5C%5C)a%5C%5C-te%5C%5C%2Bst%5C%5C-%5C%5C%7B%5C%5C~is%5C%5C*s%5C%5C%26ue%5C%5C%3For%5C%5C%7Cand%5C%5Cbye%5C%5C%3A%5C%5C%7D%5C%5C%5D%5C%5C%7D%5C%5C%5D%22`, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -1367,7 +1367,7 @@ describe('Jira service', () => { method: 'get', configurationUtilities, url: `https://coolsite.net/rest/api/2/issue/RJ-107`, - connectorMetricsService, + connectorMetricsCollector, }); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/jira/service.ts b/x-pack/plugins/stack_connectors/server/connector_types/jira/service.ts index cf229f8aeaedb..aa3b862c48815 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/jira/service.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/jira/service.ts @@ -16,7 +16,7 @@ import { } from '@kbn/actions-plugin/server/lib/axios_utils'; import { ActionsConfigurationUtilities } from '@kbn/actions-plugin/server/actions_config'; import { getBasicAuthHeader } from '@kbn/actions-plugin/server'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; import { CreateCommentParams, CreateIncidentParams, @@ -49,7 +49,7 @@ export const createExternalService = ( { config, secrets }: ExternalServiceCredentials, logger: Logger, configurationUtilities: ActionsConfigurationUtilities, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): ExternalService => { const { apiUrl: url, projectKey } = config as JiraPublicConfigurationType; const { apiToken, email } = secrets as JiraSecretConfigurationType; @@ -191,7 +191,7 @@ export const createExternalService = ( url: `${incidentUrl}/${id}`, logger, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); throwIfResponseIsNotValid({ @@ -245,7 +245,7 @@ export const createExternalService = ( fields, }, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); throwIfResponseIsNotValid({ @@ -292,7 +292,7 @@ export const createExternalService = ( logger, data: { fields }, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); throwIfResponseIsNotValid({ @@ -331,7 +331,7 @@ export const createExternalService = ( logger, data: { body: comment.comment }, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); throwIfResponseIsNotValid({ @@ -364,7 +364,7 @@ export const createExternalService = ( url: capabilitiesUrl, logger, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); throwIfResponseIsNotValid({ @@ -396,7 +396,7 @@ export const createExternalService = ( url: getIssueTypesOldAPIURL, logger, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); throwIfResponseIsNotValid({ @@ -412,7 +412,7 @@ export const createExternalService = ( url: getIssueTypesUrl, logger, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); throwIfResponseIsNotValid({ @@ -445,7 +445,7 @@ export const createExternalService = ( url: createGetIssueTypeFieldsUrl(getIssueTypeFieldsOldAPIURL, issueTypeId), logger, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); throwIfResponseIsNotValid({ @@ -525,7 +525,7 @@ export const createExternalService = ( url: query, logger, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); throwIfResponseIsNotValid({ @@ -554,7 +554,7 @@ export const createExternalService = ( url: getIssueUrl, logger, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); throwIfResponseIsNotValid({ diff --git a/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/create_service_wrapper.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/create_service_wrapper.test.ts index 311de65eb4abe..9f984de648ae9 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/create_service_wrapper.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/create_service_wrapper.test.ts @@ -12,6 +12,7 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; import { actionsConfigMock } from '@kbn/actions-plugin/server/actions_config.mock'; import { connectorTokenClientMock } from '@kbn/actions-plugin/server/lib/connector_token_client.mock'; import { snExternalServiceConfig } from './config'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; const logger = loggingSystemMock.create().get() as jest.Mocked; const connectorTokenClient = connectorTokenClientMock.create(); @@ -19,10 +20,12 @@ const configurationUtilities = actionsConfigMock.create(); jest.mock('axios'); axios.create = jest.fn(() => axios); +let connectorMetricsCollector: ConnectorMetricsCollector; describe('createServiceWrapper', () => { beforeEach(() => { jest.clearAllMocks(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); test('creates axios instance with apiUrl', () => { @@ -45,6 +48,7 @@ describe('createServiceWrapper', () => { serviceConfig, connectorTokenClient, createServiceFn, + connectorMetricsCollector, }); expect(createServiceFn).toHaveBeenCalledWith({ @@ -53,6 +57,7 @@ describe('createServiceWrapper', () => { configurationUtilities, serviceConfig, axiosInstance: axios, + connectorMetricsCollector, }); }); @@ -76,6 +81,7 @@ describe('createServiceWrapper', () => { serviceConfig, connectorTokenClient, createServiceFn, + connectorMetricsCollector, }); expect(createServiceFn).toHaveBeenCalledWith({ @@ -84,6 +90,7 @@ describe('createServiceWrapper', () => { configurationUtilities, serviceConfig, axiosInstance: axios, + connectorMetricsCollector, }); }); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/create_service_wrapper.ts b/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/create_service_wrapper.ts index 01a215bc8905c..7d4e2715be9c0 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/create_service_wrapper.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/create_service_wrapper.ts @@ -7,7 +7,7 @@ import { Logger } from '@kbn/core/server'; import { - ConnectorMetricsService, + ConnectorMetricsCollector, ConnectorTokenClientContract, } from '@kbn/actions-plugin/server/types'; import { ActionsConfigurationUtilities } from '@kbn/actions-plugin/server/actions_config'; @@ -24,7 +24,7 @@ interface CreateServiceWrapperOpts { serviceConfig: SNProductsConfigValue; connectorTokenClient: ConnectorTokenClientContract; createServiceFn: ServiceFactory; - connectorMetricsService: ConnectorMetricsService; + connectorMetricsCollector: ConnectorMetricsCollector; } export function createServiceWrapper({ @@ -35,7 +35,7 @@ export function createServiceWrapper({ serviceConfig, connectorTokenClient, createServiceFn, - connectorMetricsService, + connectorMetricsCollector, }: CreateServiceWrapperOpts): T { const { config } = credentials; const { apiUrl: url } = config as ServiceNowPublicConfigurationType; @@ -55,6 +55,6 @@ export function createServiceWrapper({ configurationUtilities, serviceConfig, axiosInstance, - connectorMetricsService, + connectorMetricsCollector, }); } diff --git a/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/service.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/service.test.ts index ce6f33e1cc0d1..58ac9f19a5176 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/service.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/service.test.ts @@ -15,6 +15,7 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; import { actionsConfigMock } from '@kbn/actions-plugin/server/actions_config.mock'; import { serviceNowCommonFields, serviceNowChoices } from './mocks'; import { snExternalServiceConfig } from './config'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; const logger = loggingSystemMock.create().get() as jest.Mocked; jest.mock('axios', () => ({ @@ -178,6 +179,7 @@ const expectImportedIncident = (update: boolean) => { configurationUtilities, url: 'https://example.com/api/x_elas2_inc_int/elastic_api/health', method: 'get', + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); expect(requestMock).toHaveBeenNthCalledWith(2, { @@ -191,6 +193,7 @@ const expectImportedIncident = (update: boolean) => { u_description: 'desc', ...(update ? { elastic_incident_id: '1' } : {}), }, + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); expect(requestMock).toHaveBeenNthCalledWith(3, { @@ -199,14 +202,18 @@ const expectImportedIncident = (update: boolean) => { configurationUtilities, url: 'https://example.com/api/now/v2/table/incident/1', method: 'get', + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); }; describe('ServiceNow service', () => { let service: ExternalService; + let connectorMetricsCollector: ConnectorMetricsCollector; beforeEach(() => { jest.clearAllMocks(); + connectorMetricsCollector = new ConnectorMetricsCollector(); + service = createExternalService({ credentials: { // The trailing slash at the end of the url is intended. @@ -218,6 +225,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: snExternalServiceConfig['.servicenow'], axiosInstance: axios, + connectorMetricsCollector, }); }); @@ -233,6 +241,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: snExternalServiceConfig['.servicenow'], axiosInstance: axios, + connectorMetricsCollector, }) ).toThrow(); }); @@ -273,6 +282,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: snExternalServiceConfig['.servicenow'], axiosInstance: axios, + connectorMetricsCollector, }) ).toThrow(); }); @@ -437,6 +447,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: snExternalServiceConfig['.servicenow'], axiosInstance: axios, + connectorMetricsCollector, }) ).toThrow(); }); @@ -464,6 +475,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/incident/1', method: 'get', + connectorMetricsCollector, }); }); @@ -477,6 +489,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow'], table: 'sn_si_incident' }, axiosInstance: axios, + connectorMetricsCollector, }); requestMock.mockImplementation(() => ({ @@ -490,6 +503,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/sn_si_incident/1', method: 'get', + connectorMetricsCollector, }); }); @@ -535,6 +549,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/incident?sysparm_query=ORDERBYDESCsys_created_on^correlation_id=custom_correlation_id', method: 'get', + connectorMetricsCollector, }); }); @@ -559,6 +574,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow'], table: 'sn_si_incident' }, axiosInstance: axios, + connectorMetricsCollector, }); requestMock.mockImplementation(() => ({ @@ -572,6 +588,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/sn_si_incident?sysparm_query=ORDERBYDESCsys_created_on^correlation_id=custom_correlation_id', method: 'get', + connectorMetricsCollector, }); }); @@ -625,6 +642,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: snExternalServiceConfig['.servicenow-sir'], axiosInstance: axios, + connectorMetricsCollector, }); const res = await createIncident(service); @@ -635,6 +653,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/x_elas2_sir_int/elastic_api/health', method: 'get', + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(2, { @@ -644,6 +663,7 @@ describe('ServiceNow service', () => { url: 'https://example.com/api/now/import/x_elas2_sir_int_elastic_si_incident', method: 'post', data: { u_short_description: 'title', u_description: 'desc' }, + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(3, { @@ -652,6 +672,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/sn_si_incident/1', method: 'get', + connectorMetricsCollector, }); expect(res.url).toEqual('https://example.com/nav_to.do?uri=sn_si_incident.do?sys_id=1'); @@ -707,6 +728,7 @@ describe('ServiceNow service', () => { url: 'https://example.com/api/now/import/x_elas2_inc_int_elastic_incident', method: 'post', data: { u_short_description: 'title', u_description: 'desc', foo: 'test' }, + connectorMetricsCollector, }); }); }); @@ -723,6 +745,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow'], useImportAPI: false }, axiosInstance: axios, + connectorMetricsCollector, }); }); @@ -749,6 +772,7 @@ describe('ServiceNow service', () => { url: 'https://example.com/api/now/v2/table/incident', method: 'post', data: { short_description: 'title', description: 'desc' }, + connectorMetricsCollector, }); }); @@ -762,6 +786,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow-sir'], useImportAPI: false }, axiosInstance: axios, + connectorMetricsCollector, }); mockIncidentResponse(false); @@ -778,6 +803,7 @@ describe('ServiceNow service', () => { url: 'https://example.com/api/now/v2/table/sn_si_incident', method: 'post', data: { short_description: 'title', description: 'desc' }, + connectorMetricsCollector, }); expect(res.url).toEqual('https://example.com/nav_to.do?uri=sn_si_incident.do?sys_id=1'); @@ -826,6 +852,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: snExternalServiceConfig['.servicenow-sir'], axiosInstance: axios, + connectorMetricsCollector, }); const res = await updateIncident(service); @@ -835,6 +862,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/x_elas2_sir_int/elastic_api/health', method: 'get', + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(2, { @@ -844,6 +872,7 @@ describe('ServiceNow service', () => { url: 'https://example.com/api/now/import/x_elas2_sir_int_elastic_si_incident', method: 'post', data: { u_short_description: 'title', u_description: 'desc', elastic_incident_id: '1' }, + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(3, { @@ -852,6 +881,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/sn_si_incident/1', method: 'get', + connectorMetricsCollector, }); expect(res.url).toEqual('https://example.com/nav_to.do?uri=sn_si_incident.do?sys_id=1'); @@ -915,6 +945,7 @@ describe('ServiceNow service', () => { elastic_incident_id: '1', foo: 'test', }, + connectorMetricsCollector, }); }); }); @@ -931,6 +962,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow'], useImportAPI: false }, axiosInstance: axios, + connectorMetricsCollector, }); }); @@ -958,6 +990,7 @@ describe('ServiceNow service', () => { url: 'https://example.com/api/now/v2/table/incident/1', method: 'patch', data: { short_description: 'title', description: 'desc' }, + connectorMetricsCollector, }); }); @@ -971,6 +1004,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow-sir'], useImportAPI: false }, axiosInstance: axios, + connectorMetricsCollector, }); mockIncidentResponse(false); @@ -988,6 +1022,7 @@ describe('ServiceNow service', () => { url: 'https://example.com/api/now/v2/table/sn_si_incident/1', method: 'patch', data: { short_description: 'title', description: 'desc' }, + connectorMetricsCollector, }); expect(res.url).toEqual('https://example.com/nav_to.do?uri=sn_si_incident.do?sys_id=1'); @@ -1032,6 +1067,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/incident/1', method: 'get', + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(2, { @@ -1040,6 +1076,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/x_elas2_inc_int/elastic_api/health', method: 'get', + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(3, { @@ -1054,6 +1091,7 @@ describe('ServiceNow service', () => { u_state: '7', u_close_notes: 'Closed by Caller', }, + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(4, { @@ -1062,6 +1100,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/incident/1', method: 'get', + connectorMetricsCollector, }); expect(res?.url).toEqual('https://example.com/nav_to.do?uri=incident.do?sys_id=1'); @@ -1097,6 +1136,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/incident?sysparm_query=ORDERBYDESCsys_created_on^correlation_id=custom_correlation_id', method: 'get', + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(2, { @@ -1105,6 +1145,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/x_elas2_inc_int/elastic_api/health', method: 'get', + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(3, { @@ -1119,6 +1160,7 @@ describe('ServiceNow service', () => { u_state: '7', u_close_notes: 'Closed by Caller', }, + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(4, { @@ -1127,6 +1169,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/incident/1', method: 'get', + connectorMetricsCollector, }); expect(res?.url).toEqual('https://example.com/nav_to.do?uri=incident.do?sys_id=1'); @@ -1237,6 +1280,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow'], useImportAPI: false }, axiosInstance: axios, + connectorMetricsCollector, }); }); @@ -1268,6 +1312,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow-sir'], useImportAPI: false }, axiosInstance: axios, + connectorMetricsCollector, }); mockIncidentResponse(false); @@ -1285,6 +1330,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/sn_si_incident/1', method: 'get', + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(2, { @@ -1298,6 +1344,7 @@ describe('ServiceNow service', () => { state: '7', close_notes: 'Closed by Caller', }, + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(3, { @@ -1306,6 +1353,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/sn_si_incident/1', method: 'get', + connectorMetricsCollector, }); expect(res?.url).toEqual('https://example.com/nav_to.do?uri=sn_si_incident.do?sys_id=1'); @@ -1325,6 +1373,7 @@ describe('ServiceNow service', () => { logger, configurationUtilities, url: 'https://example.com/api/now/table/sys_dictionary?sysparm_query=name=task^ORname=incident^internal_type=string&active=true&array=false&read_only=false&sysparm_fields=max_length,element,column_label,mandatory', + connectorMetricsCollector, }); }); @@ -1346,6 +1395,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow'], table: 'sn_si_incident' }, axiosInstance: axios, + connectorMetricsCollector, }); requestMock.mockImplementation(() => ({ @@ -1358,6 +1408,7 @@ describe('ServiceNow service', () => { logger, configurationUtilities, url: 'https://example.com/api/now/table/sys_dictionary?sysparm_query=name=task^ORname=sn_si_incident^internal_type=string&active=true&array=false&read_only=false&sysparm_fields=max_length,element,column_label,mandatory', + connectorMetricsCollector, }); }); @@ -1394,6 +1445,7 @@ describe('ServiceNow service', () => { logger, configurationUtilities, url: 'https://example.com/api/now/table/sys_choice?sysparm_query=name=task^ORname=incident^element=priority^ORelement=category^language=en&sysparm_fields=label,value,dependent_value,element', + connectorMetricsCollector, }); }); @@ -1415,6 +1467,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow'], table: 'sn_si_incident' }, axiosInstance: axios, + connectorMetricsCollector, }); requestMock.mockImplementation(() => ({ @@ -1428,6 +1481,7 @@ describe('ServiceNow service', () => { logger, configurationUtilities, url: 'https://example.com/api/now/table/sys_choice?sysparm_query=name=task^ORname=sn_si_incident^element=priority^ORelement=category^language=en&sysparm_fields=label,value,dependent_value,element', + connectorMetricsCollector, }); }); @@ -1520,6 +1574,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow'], useImportAPI: false }, axiosInstance: axios, + connectorMetricsCollector, }); await service.checkIfApplicationIsInstalled(); expect(requestMock).not.toHaveBeenCalled(); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/service.ts b/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/service.ts index de2573463094e..a8e4f66263379 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/service.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/service.ts @@ -37,7 +37,7 @@ export const createExternalService: ServiceFactory = ({ configurationUtilities, serviceConfig, axiosInstance, - connectorMetricsService, + connectorMetricsCollector, }): ExternalService => { const { config, secrets } = credentials; const { table, importSetTable, useImportAPI, appScope } = serviceConfig; @@ -133,7 +133,7 @@ export const createExternalService: ServiceFactory = ({ logger, configurationUtilities, method: 'get', - connectorMetricsService, // TODO check if this is internal + connectorMetricsCollector, // TODO check if this is internal }); checkInstance(res); @@ -162,7 +162,7 @@ export const createExternalService: ServiceFactory = ({ logger, configurationUtilities, method: 'get', - connectorMetricsService, + connectorMetricsCollector, }); checkInstance(res); @@ -181,7 +181,7 @@ export const createExternalService: ServiceFactory = ({ logger, params, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); checkInstance(res); @@ -205,7 +205,7 @@ export const createExternalService: ServiceFactory = ({ method: 'post', data: prepareIncident(useTableApi, incident), configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); checkInstance(res); @@ -245,7 +245,7 @@ export const createExternalService: ServiceFactory = ({ ...(useTableApi ? {} : { elastic_incident_id: incidentId }), }, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); checkInstance(res); @@ -278,7 +278,7 @@ export const createExternalService: ServiceFactory = ({ method: 'get', logger, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); checkInstance(res); @@ -357,7 +357,7 @@ export const createExternalService: ServiceFactory = ({ url: fieldsUrl, logger, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); checkInstance(res); @@ -375,7 +375,7 @@ export const createExternalService: ServiceFactory = ({ url: getChoicesURL(fields), logger, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); checkInstance(res); return res.data.result; diff --git a/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/types.ts b/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/types.ts index adde700b93c4d..93462e2811826 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/types.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/types.ts @@ -11,7 +11,7 @@ import { AxiosError, AxiosInstance, AxiosResponse } from 'axios'; import { TypeOf } from '@kbn/config-schema'; import { Logger } from '@kbn/core/server'; import { ActionsConfigurationUtilities } from '@kbn/actions-plugin/server/actions_config'; -import { ConnectorMetricsService, ValidatorServices } from '@kbn/actions-plugin/server/types'; +import { ConnectorMetricsCollector, ValidatorServices } from '@kbn/actions-plugin/server/types'; import { ExecutorParamsSchemaITSM, ExecutorSubActionCommonFieldsParamsSchema, @@ -305,7 +305,7 @@ interface ServiceFactoryOpts { configurationUtilities: ActionsConfigurationUtilities; serviceConfig: SNProductsConfigValue; axiosInstance: AxiosInstance; - connectorMetricsService: ConnectorMetricsService; + connectorMetricsCollector: ConnectorMetricsCollector; } export type ServiceFactory = ({ @@ -314,7 +314,7 @@ export type ServiceFactory = ({ configurationUtilities, serviceConfig, axiosInstance, - connectorMetricsService, + connectorMetricsCollector, }: ServiceFactoryOpts) => T; /** diff --git a/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.test.ts index 46818b85adc52..ea0b48e116832 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.test.ts @@ -19,7 +19,7 @@ import { actionsMock } from '@kbn/actions-plugin/server/mocks'; import { RunActionResponseSchema, StreamingResponseSchema } from '../../../common/openai/schema'; import { initDashboard } from '../lib/gen_ai/create_gen_ai_dashboard'; import { PassThrough, Transform } from 'stream'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; jest.mock('../lib/gen_ai/create_gen_ai_dashboard'); const mockTee = jest.fn(); @@ -47,7 +47,7 @@ jest.mock('openai', () => ({ describe('OpenAIConnector', () => { let mockRequest: jest.Mock; let mockError: jest.Mock; - let connectorMetricsService: ConnectorMetricsService; + let connectorMetricsCollector: ConnectorMetricsCollector; const mockResponseString = 'Hello! How can I assist you today?'; const mockResponse = { @@ -75,7 +75,7 @@ describe('OpenAIConnector', () => { }, }; beforeEach(() => { - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); mockRequest = jest.fn().mockResolvedValue(mockResponse); mockError = jest.fn().mockImplementation(() => { throw new Error('API Error'); @@ -119,7 +119,7 @@ describe('OpenAIConnector', () => { it('uses the default model if none is supplied', async () => { const response = await connector.runApi( { body: JSON.stringify(sampleOpenAiBody) }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -136,7 +136,7 @@ describe('OpenAIConnector', () => { 'content-type': 'application/json', }, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual(mockResponse.data); }); @@ -145,7 +145,7 @@ describe('OpenAIConnector', () => { const requestBody = { model: 'gpt-3.5-turbo', ...sampleOpenAiBody }; const response = await connector.runApi( { body: JSON.stringify(requestBody) }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -158,7 +158,7 @@ describe('OpenAIConnector', () => { 'content-type': 'application/json', }, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual(mockResponse.data); }); @@ -166,7 +166,7 @@ describe('OpenAIConnector', () => { it('the OpenAI API call is successful with correct parameters', async () => { const response = await connector.runApi( { body: JSON.stringify(sampleOpenAiBody) }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -183,7 +183,7 @@ describe('OpenAIConnector', () => { 'content-type': 'application/json', }, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual(mockResponse.data); }); @@ -205,7 +205,7 @@ describe('OpenAIConnector', () => { stream: true, }), }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -221,7 +221,7 @@ describe('OpenAIConnector', () => { 'content-type': 'application/json', }, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual(mockResponse.data); }); @@ -231,7 +231,7 @@ describe('OpenAIConnector', () => { connector.request = mockError; await expect( - connector.runApi({ body: JSON.stringify(sampleOpenAiBody) }, connectorMetricsService) + connector.runApi({ body: JSON.stringify(sampleOpenAiBody) }, connectorMetricsCollector) ).rejects.toThrow('API Error'); }); }); @@ -243,7 +243,7 @@ describe('OpenAIConnector', () => { body: JSON.stringify(sampleOpenAiBody), stream: false, }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -262,7 +262,7 @@ describe('OpenAIConnector', () => { 'content-type': 'application/json', }, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual(mockResponse.data); }); @@ -273,7 +273,7 @@ describe('OpenAIConnector', () => { body: JSON.stringify(sampleOpenAiBody), stream: true, }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -293,7 +293,7 @@ describe('OpenAIConnector', () => { 'content-type': 'application/json', }, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual({ headers: { 'Content-Type': 'dont-compress-this' }, @@ -319,7 +319,7 @@ describe('OpenAIConnector', () => { }), stream: true, }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -338,7 +338,7 @@ describe('OpenAIConnector', () => { 'content-type': 'application/json', }, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual({ headers: { 'Content-Type': 'dont-compress-this' }, @@ -353,7 +353,7 @@ describe('OpenAIConnector', () => { await expect( connector.streamApi( { body: JSON.stringify(sampleOpenAiBody), stream: true }, - connectorMetricsService + connectorMetricsCollector ) ).rejects.toThrow('API Error'); }); @@ -379,7 +379,7 @@ describe('OpenAIConnector', () => { }); it('the API call is successful with correct request parameters', async () => { - await connector.invokeStream(sampleOpenAiBody, connectorMetricsService); + await connector.invokeStream(sampleOpenAiBody, connectorMetricsCollector); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( { @@ -398,13 +398,13 @@ describe('OpenAIConnector', () => { 'content-type': 'application/json', }, }, - connectorMetricsService + connectorMetricsCollector ); }); it('signal is properly passed to streamApi', async () => { const signal = jest.fn(); - await connector.invokeStream({ ...sampleOpenAiBody, signal }, connectorMetricsService); + await connector.invokeStream({ ...sampleOpenAiBody, signal }, connectorMetricsCollector); expect(mockRequest).toHaveBeenCalledWith( { @@ -424,13 +424,13 @@ describe('OpenAIConnector', () => { }, signal, }, - connectorMetricsService + connectorMetricsCollector ); }); it('timeout is properly passed to streamApi', async () => { const timeout = 180000; - await connector.invokeStream({ ...sampleOpenAiBody, timeout }, connectorMetricsService); + await connector.invokeStream({ ...sampleOpenAiBody, timeout }, connectorMetricsCollector); expect(mockRequest).toHaveBeenCalledWith( { @@ -450,7 +450,7 @@ describe('OpenAIConnector', () => { }, timeout, }, - connectorMetricsService + connectorMetricsCollector ); }); @@ -459,21 +459,21 @@ describe('OpenAIConnector', () => { connector.request = mockError; await expect( - connector.invokeStream(sampleOpenAiBody, connectorMetricsService) + connector.invokeStream(sampleOpenAiBody, connectorMetricsCollector) ).rejects.toThrow('API Error'); }); it('responds with a readable stream', async () => { // @ts-ignore connector.request = mockStream(); - const response = await connector.invokeStream(sampleOpenAiBody, connectorMetricsService); + const response = await connector.invokeStream(sampleOpenAiBody, connectorMetricsCollector); expect(response instanceof PassThrough).toEqual(true); }); }); describe('invokeAI', () => { it('the API call is successful with correct parameters', async () => { - const response = await connector.invokeAI(sampleOpenAiBody, connectorMetricsService); + const response = await connector.invokeAI(sampleOpenAiBody, connectorMetricsCollector); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( { @@ -489,7 +489,7 @@ describe('OpenAIConnector', () => { 'content-type': 'application/json', }, }, - connectorMetricsService + connectorMetricsCollector ); expect(response.message).toEqual(mockResponseString); expect(response.usage.total_tokens).toEqual(9); @@ -497,7 +497,7 @@ describe('OpenAIConnector', () => { it('signal is properly passed to runApi', async () => { const signal = jest.fn(); - await connector.invokeAI({ ...sampleOpenAiBody, signal }, connectorMetricsService); + await connector.invokeAI({ ...sampleOpenAiBody, signal }, connectorMetricsCollector); expect(mockRequest).toHaveBeenCalledWith( { @@ -514,13 +514,13 @@ describe('OpenAIConnector', () => { }, signal, }, - connectorMetricsService + connectorMetricsCollector ); }); it('timeout is properly passed to runApi', async () => { const timeout = 180000; - await connector.invokeAI({ ...sampleOpenAiBody, timeout }, connectorMetricsService); + await connector.invokeAI({ ...sampleOpenAiBody, timeout }, connectorMetricsCollector); expect(mockRequest).toHaveBeenCalledWith( { @@ -537,7 +537,7 @@ describe('OpenAIConnector', () => { }, timeout, }, - connectorMetricsService + connectorMetricsCollector ); }); @@ -545,15 +545,15 @@ describe('OpenAIConnector', () => { // @ts-ignore connector.request = mockError; - await expect(connector.invokeAI(sampleOpenAiBody, connectorMetricsService)).rejects.toThrow( - 'API Error' - ); + await expect( + connector.invokeAI(sampleOpenAiBody, connectorMetricsCollector) + ).rejects.toThrow('API Error'); }); }); describe('invokeAsyncIterator', () => { it('the API call is successful with correct request parameters', async () => { - await connector.invokeAsyncIterator(sampleOpenAiBody, connectorMetricsService); + await connector.invokeAsyncIterator(sampleOpenAiBody, connectorMetricsCollector); expect(mockRequest).toBeCalledTimes(0); expect(mockCreate).toHaveBeenCalledWith( { @@ -570,7 +570,7 @@ describe('OpenAIConnector', () => { const signal = jest.fn(); await connector.invokeAsyncIterator( { ...sampleOpenAiBody, signal, timeout }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(0); expect(mockCreate).toHaveBeenCalledWith( @@ -593,7 +593,7 @@ describe('OpenAIConnector', () => { }); await expect( - connector.invokeAsyncIterator(sampleOpenAiBody, connectorMetricsService) + connector.invokeAsyncIterator(sampleOpenAiBody, connectorMetricsCollector) ).rejects.toThrow('API Error'); }); }); @@ -686,7 +686,7 @@ describe('OpenAIConnector', () => { it('uses the default model if none is supplied', async () => { const response = await connector.runApi( { body: JSON.stringify(sampleOpenAiBody) }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -702,7 +702,7 @@ describe('OpenAIConnector', () => { 'content-type': 'application/json', }, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual(mockResponse.data); }); @@ -742,7 +742,7 @@ describe('OpenAIConnector', () => { it('test the AzureAI API call is successful with correct parameters', async () => { const response = await connector.runApi( { body: JSON.stringify(sampleAzureAiBody) }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -755,7 +755,7 @@ describe('OpenAIConnector', () => { 'content-type': 'application/json', }, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual(mockResponse.data); }); @@ -773,7 +773,7 @@ describe('OpenAIConnector', () => { { body: JSON.stringify({ ...body, stream: true }), }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -786,7 +786,7 @@ describe('OpenAIConnector', () => { 'content-type': 'application/json', }, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual(mockResponse.data); }); @@ -796,7 +796,7 @@ describe('OpenAIConnector', () => { connector.request = mockError; await expect( - connector.runApi({ body: JSON.stringify(sampleAzureAiBody) }, connectorMetricsService) + connector.runApi({ body: JSON.stringify(sampleAzureAiBody) }, connectorMetricsCollector) ).rejects.toThrow('API Error'); }); }); @@ -808,7 +808,7 @@ describe('OpenAIConnector', () => { body: JSON.stringify(sampleAzureAiBody), stream: false, }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -822,7 +822,7 @@ describe('OpenAIConnector', () => { 'content-type': 'application/json', }, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual(mockResponse.data); }); @@ -833,7 +833,7 @@ describe('OpenAIConnector', () => { body: JSON.stringify(sampleAzureAiBody), stream: true, }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -848,7 +848,7 @@ describe('OpenAIConnector', () => { 'content-type': 'application/json', }, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual({ headers: { 'Content-Type': 'dont-compress-this' }, @@ -870,7 +870,7 @@ describe('OpenAIConnector', () => { body: JSON.stringify({ ...body, stream: false }), stream: true, }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith( @@ -888,7 +888,7 @@ describe('OpenAIConnector', () => { 'content-type': 'application/json', }, }, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual({ headers: { 'Content-Type': 'dont-compress-this' }, @@ -903,7 +903,7 @@ describe('OpenAIConnector', () => { await expect( connector.streamApi( { body: JSON.stringify(sampleAzureAiBody), stream: true }, - connectorMetricsService + connectorMetricsCollector ) ).rejects.toThrow('API Error'); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.ts b/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.ts index 682cfa95a678a..191bfb3693538 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.ts @@ -16,7 +16,7 @@ import { ChatCompletionMessageParam, } from 'openai/resources/chat/completions'; import { Stream } from 'openai/streaming'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; import { removeEndpointFromUrl } from './lib/openai_utils'; import { RunActionParamsSchema, @@ -160,7 +160,7 @@ export class OpenAIConnector extends SubActionConnector { public async runApi( { body, signal, timeout }: RunActionParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const sanitizedBody = sanitizeRequest( this.provider, @@ -184,7 +184,7 @@ export class OpenAIConnector extends SubActionConnector { ...axiosOptions.headers, }, }, - connectorMetricsService + connectorMetricsCollector ); return response.data; } @@ -199,7 +199,7 @@ export class OpenAIConnector extends SubActionConnector { */ public async streamApi( { body, stream, signal, timeout }: StreamActionParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const executeBody = getRequestWithStreamOption( this.provider, @@ -225,7 +225,7 @@ export class OpenAIConnector extends SubActionConnector { }, timeout, }, - connectorMetricsService + connectorMetricsCollector ); return stream ? pipeStreamingResponse(response) : response.data; } @@ -275,7 +275,7 @@ export class OpenAIConnector extends SubActionConnector { */ public async invokeStream( body: InvokeAIActionParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const { signal, timeout, ...rest } = body; @@ -286,7 +286,7 @@ export class OpenAIConnector extends SubActionConnector { signal, timeout, // do not default if not provided }, - connectorMetricsService + connectorMetricsCollector )) as unknown as IncomingMessage; return res.pipe(new PassThrough()); @@ -303,7 +303,7 @@ export class OpenAIConnector extends SubActionConnector { */ public async invokeAsyncIterator( body: InvokeAIActionParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise<{ consumerStream: Stream; tokenCountStream: Stream; @@ -320,7 +320,7 @@ export class OpenAIConnector extends SubActionConnector { ('defaultModel' in this.config ? this.config.defaultModel : DEFAULT_OPENAI_MODEL), }; - connectorMetricsService.addRequestBodyBytes(undefined, requestBody); + connectorMetricsCollector.addRequestBodyBytes(undefined, requestBody); const stream = await this.openAI.chat.completions.create(requestBody, { signal, timeout, // do not default if not provided @@ -345,12 +345,12 @@ export class OpenAIConnector extends SubActionConnector { */ public async invokeAI( body: InvokeAIActionParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const { signal, timeout, ...rest } = body; const res = await this.runApi( { body: JSON.stringify(rest), signal, timeout }, - connectorMetricsService + connectorMetricsCollector ); if (res.choices && res.choices.length > 0 && res.choices[0].message?.content) { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/opsgenie/connector.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/opsgenie/connector.test.ts index 4b01301ca3d91..98f98c4c79d33 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/opsgenie/connector.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/opsgenie/connector.test.ts @@ -15,7 +15,7 @@ import { MockedLogger } from '@kbn/logging-mocks'; import { OpsgenieConnectorTypeId } from '../../../common'; import { OpsgenieConnector } from './connector'; import * as utils from '@kbn/actions-plugin/server/lib/axios_utils'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; jest.mock('axios'); @@ -37,7 +37,7 @@ describe('OpsgenieConnector', () => { let mockedActionsConfig: jest.Mocked; let logger: MockedLogger; let services: ReturnType; - let connectorMetricsService: ConnectorMetricsService; + let connectorMetricsCollector: ConnectorMetricsCollector; const defaultCreateAlertExpect = { method: 'post', @@ -77,40 +77,40 @@ describe('OpsgenieConnector', () => { logger, services, }); - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); it('calls request with the correct arguments for creating an alert', async () => { - await connector.createAlert({ message: 'hello' }, connectorMetricsService); + await connector.createAlert({ message: 'hello' }, connectorMetricsCollector); expect(requestMock.mock.calls[0][0]).toEqual({ data: { message: 'hello' }, ...ignoredRequestFields, ...defaultCreateAlertExpect, - connectorMetricsService, + connectorMetricsCollector, }); }); it('calls request without modifying the alias when it is less than 512 characters when creating an alert', async () => { - await connector.createAlert({ message: 'hello', alias: '111' }, connectorMetricsService); + await connector.createAlert({ message: 'hello', alias: '111' }, connectorMetricsCollector); expect(requestMock.mock.calls[0][0]).toEqual({ ...ignoredRequestFields, ...defaultCreateAlertExpect, data: { message: 'hello', alias: '111' }, - connectorMetricsService, + connectorMetricsCollector, }); }); it('calls request without modifying the alias when it is equal to 512 characters when creating an alert', async () => { const alias = 'a'.repeat(512); - await connector.createAlert({ message: 'hello', alias }, connectorMetricsService); + await connector.createAlert({ message: 'hello', alias }, connectorMetricsCollector); expect(requestMock.mock.calls[0][0]).toEqual({ ...ignoredRequestFields, ...defaultCreateAlertExpect, data: { message: 'hello', alias }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -120,13 +120,13 @@ describe('OpsgenieConnector', () => { const hasher = crypto.createHash('sha256'); const sha256Hash = hasher.update(alias); - await connector.createAlert({ message: 'hello', alias }, connectorMetricsService); + await connector.createAlert({ message: 'hello', alias }, connectorMetricsCollector); expect(requestMock.mock.calls[0][0]).toEqual({ ...ignoredRequestFields, ...defaultCreateAlertExpect, data: { message: 'hello', alias: `sha-${sha256Hash.digest('hex')}` }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -136,24 +136,24 @@ describe('OpsgenieConnector', () => { const hasher = crypto.createHash('sha256'); const sha256Hash = hasher.update(alias); - await connector.closeAlert({ alias }, connectorMetricsService); + await connector.closeAlert({ alias }, connectorMetricsCollector); expect(requestMock.mock.calls[0][0]).toEqual({ ...ignoredRequestFields, ...createCloseAlertExpect(`sha-${sha256Hash.digest('hex')}`), data: {}, - connectorMetricsService, + connectorMetricsCollector, }); }); it('calls request with the correct arguments for closing an alert', async () => { - await connector.closeAlert({ user: 'sam', alias: '111' }, connectorMetricsService); + await connector.closeAlert({ user: 'sam', alias: '111' }, connectorMetricsCollector); expect(requestMock.mock.calls[0][0]).toEqual({ ...ignoredRequestFields, ...createCloseAlertExpect('111'), data: { user: 'sam' }, - connectorMetricsService, + connectorMetricsCollector, }); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/opsgenie/connector.ts b/x-pack/plugins/stack_connectors/server/connector_types/opsgenie/connector.ts index 6091734c0b51c..16b91e2256284 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/opsgenie/connector.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/opsgenie/connector.ts @@ -9,7 +9,7 @@ import crypto from 'crypto'; import { ServiceParams, SubActionConnector } from '@kbn/actions-plugin/server'; import { AxiosError } from 'axios'; import { isEmpty } from 'lodash'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; import { OpsgenieSubActions } from '../../../common'; import { CreateAlertParamsSchema, CloseAlertParamsSchema, Response } from './schema'; import { CloseAlertParams, Config, CreateAlertParams, FailureResponseType, Secrets } from './types'; @@ -70,7 +70,7 @@ export class OpsgenieConnector extends SubActionConnector { public async createAlert( params: CreateAlertParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) { const res = await this.request( { @@ -80,7 +80,7 @@ export class OpsgenieConnector extends SubActionConnector { headers: this.createHeaders(), responseSchema: Response, }, - connectorMetricsService + connectorMetricsCollector ); return res.data; @@ -116,7 +116,7 @@ export class OpsgenieConnector extends SubActionConnector { public async closeAlert( params: CloseAlertParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) { const newAlias = OpsgenieConnector.createAlias(params.alias); @@ -133,7 +133,7 @@ export class OpsgenieConnector extends SubActionConnector { headers: this.createHeaders(), responseSchema: Response, }, - connectorMetricsService + connectorMetricsCollector ); return res.data; diff --git a/x-pack/plugins/stack_connectors/server/connector_types/pagerduty/index.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/pagerduty/index.test.ts index 9446221ea2f1a..770bdca23d25d 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/pagerduty/index.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/pagerduty/index.test.ts @@ -10,7 +10,7 @@ import moment from 'moment'; jest.mock('./post_pagerduty', () => ({ postPagerduty: jest.fn(), })); -import { ConnectorMetricsService, Services } from '@kbn/actions-plugin/server/types'; +import { ConnectorMetricsCollector, Services } from '@kbn/actions-plugin/server/types'; import { validateConfig, validateSecrets, validateParams } from '@kbn/actions-plugin/server/lib'; import { postPagerduty } from './post_pagerduty'; import { Logger } from '@kbn/core/server'; @@ -31,12 +31,12 @@ const mockedLogger: jest.Mocked = loggerMock.create(); let connectorType: PagerDutyConnectorType; let configurationUtilities: jest.Mocked; -let connectorMetricsService: ConnectorMetricsService; +let connectorMetricsCollector: ConnectorMetricsCollector; beforeEach(() => { configurationUtilities = actionsConfigMock.create(); connectorType = getConnectorType(); - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); describe('get()', () => { @@ -271,7 +271,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }; const actionResponse = await connectorType.executor(executorOptions); const { apiUrl, data, headers } = postPagerdutyMock.mock.calls[0][0]; @@ -353,7 +353,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }; const actionResponse = await connectorType.executor(executorOptions); const { apiUrl, data, headers } = postPagerdutyMock.mock.calls[0][0]; @@ -462,7 +462,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }; const actionResponse = await connectorType.executor(executorOptions); const { apiUrl, data, headers } = postPagerdutyMock.mock.calls[0][0]; @@ -540,7 +540,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }; const actionResponse = await connectorType.executor(executorOptions); const { apiUrl, data, headers } = postPagerdutyMock.mock.calls[0][0]; @@ -584,7 +584,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }; const actionResponse = await connectorType.executor(executorOptions); expect(actionResponse).toMatchInlineSnapshot(` @@ -615,7 +615,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }; const actionResponse = await connectorType.executor(executorOptions); expect(actionResponse).toMatchInlineSnapshot(` @@ -646,7 +646,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }; const actionResponse = await connectorType.executor(executorOptions); expect(actionResponse).toMatchInlineSnapshot(` @@ -677,7 +677,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }; const actionResponse = await connectorType.executor(executorOptions); expect(actionResponse).toMatchInlineSnapshot(` @@ -718,7 +718,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }; const actionResponse = await connectorType.executor(executorOptions); const { apiUrl, data, headers } = postPagerdutyMock.mock.calls[0][0]; @@ -782,7 +782,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }; const actionResponse = await connectorType.executor(executorOptions); const { apiUrl, data, headers } = postPagerdutyMock.mock.calls[0][0]; @@ -849,7 +849,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }; const actionResponse = await connectorType.executor(executorOptions); const { apiUrl, data, headers } = postPagerdutyMock.mock.calls[0][0]; @@ -915,7 +915,7 @@ describe('execute()', () => { services, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }; const actionResponse = await connectorType.executor(executorOptions); const { apiUrl, data, headers } = postPagerdutyMock.mock.calls[0][0]; diff --git a/x-pack/plugins/stack_connectors/server/connector_types/pagerduty/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/pagerduty/index.ts index 319f38125face..ee56b9e2d58d8 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/pagerduty/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/pagerduty/index.ts @@ -206,7 +206,7 @@ async function executor( services, configurationUtilities, logger, - connectorMetricsService, + connectorMetricsCollector, } = execOptions; const apiUrl = getPagerDutyApiUrl(config); @@ -222,7 +222,7 @@ async function executor( { apiUrl, data, headers, services }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); } catch (err) { const message = i18n.translate('xpack.stackConnectors.pagerduty.postingErrorMessage', { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/pagerduty/post_pagerduty.ts b/x-pack/plugins/stack_connectors/server/connector_types/pagerduty/post_pagerduty.ts index 7754e02f3c0a3..b93cc81f74492 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/pagerduty/post_pagerduty.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/pagerduty/post_pagerduty.ts @@ -7,7 +7,7 @@ import axios, { AxiosResponse } from 'axios'; import { Logger } from '@kbn/core/server'; -import { ConnectorMetricsService, Services } from '@kbn/actions-plugin/server/types'; +import { ConnectorMetricsCollector, Services } from '@kbn/actions-plugin/server/types'; import { ActionsConfigurationUtilities } from '@kbn/actions-plugin/server/actions_config'; import { request } from '@kbn/actions-plugin/server/lib/axios_utils'; @@ -23,7 +23,7 @@ export async function postPagerduty( options: PostPagerdutyOptions, logger: Logger, configurationUtilities: ActionsConfigurationUtilities, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const { apiUrl, data, headers } = options; const axiosInstance = axios.create(); @@ -37,6 +37,6 @@ export async function postPagerduty( headers, configurationUtilities, validateStatus: () => true, - connectorMetricsService, + connectorMetricsCollector, }); } diff --git a/x-pack/plugins/stack_connectors/server/connector_types/resilient/resilient.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/resilient/resilient.test.ts index fa1e591f82ebb..7a2cb567cdf8b 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/resilient/resilient.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/resilient/resilient.test.ts @@ -13,7 +13,7 @@ import { ResilientConnector } from './resilient'; import { actionsMock } from '@kbn/actions-plugin/server/mocks'; import { RESILIENT_CONNECTOR_ID } from './constants'; import { PushToServiceIncidentSchema } from './schema'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; jest.mock('axios'); jest.mock('@kbn/actions-plugin/server/lib/axios_utils', () => { @@ -84,7 +84,7 @@ const mockIncidentUpdate = (withUpdateError = false) => { }) ); }; -let connectorMetricsService: ConnectorMetricsService; +let connectorMetricsCollector: ConnectorMetricsCollector; describe('IBM Resilient connector', () => { const connector = new ResilientConnector( @@ -109,7 +109,7 @@ describe('IBM Resilient connector', () => { beforeEach(() => { jest.resetAllMocks(); jest.setSystemTime(TIMESTAMP); - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); describe('getIncident', () => { @@ -132,12 +132,12 @@ describe('IBM Resilient connector', () => { }); it('returns the incident correctly', async () => { - const res = await connector.getIncident({ id: '1' }, connectorMetricsService); + const res = await connector.getIncident({ id: '1' }, connectorMetricsCollector); expect(res).toEqual(incidentMock); }); it('should call request with correct arguments', async () => { - await connector.getIncident({ id: '1' }, connectorMetricsService); + await connector.getIncident({ id: '1' }, connectorMetricsCollector); expect(requestMock).toHaveBeenCalledWith({ ...ignoredRequestFields, method: 'GET', @@ -150,7 +150,7 @@ describe('IBM Resilient connector', () => { params: { text_content_output_format: 'objects_convert', }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -158,7 +158,7 @@ describe('IBM Resilient connector', () => { requestMock.mockImplementation(() => { throw new Error('An error has occurred'); }); - await expect(connector.getIncident({ id: '1' }, connectorMetricsService)).rejects.toThrow( + await expect(connector.getIncident({ id: '1' }, connectorMetricsCollector)).rejects.toThrow( 'Unable to get incident with id 1. Error: An error has occurred' ); }); @@ -187,7 +187,7 @@ describe('IBM Resilient connector', () => { }); it('creates the incident correctly', async () => { - const res = await connector.createIncident(incidentMock, connectorMetricsService); + const res = await connector.createIncident(incidentMock, connectorMetricsCollector); expect(res).toEqual({ title: '1', @@ -198,7 +198,7 @@ describe('IBM Resilient connector', () => { }); it('should call request with correct arguments', async () => { - await connector.createIncident(incidentMock, connectorMetricsService); + await connector.createIncident(incidentMock, connectorMetricsCollector); expect(requestMock).toHaveBeenCalledWith({ ...ignoredRequestFields, @@ -218,7 +218,7 @@ describe('IBM Resilient connector', () => { Authorization: `Basic ${token}`, 'Content-Type': 'application/json', }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -235,7 +235,7 @@ describe('IBM Resilient connector', () => { incidentTypes: [1001], severityCode: 6, }, - connectorMetricsService + connectorMetricsCollector ) ).rejects.toThrow( '[Action][IBM Resilient]: Unable to create incident. Error: An error has occurred' @@ -245,7 +245,9 @@ describe('IBM Resilient connector', () => { it('should throw if the required attributes are not received in response', async () => { requestMock.mockImplementation(() => createAxiosResponse({ data: { notRequired: 'test' } })); - await expect(connector.createIncident(incidentMock, connectorMetricsService)).rejects.toThrow( + await expect( + connector.createIncident(incidentMock, connectorMetricsCollector) + ).rejects.toThrow( '[Action][IBM Resilient]: Unable to create incident. Error: Response validation failed (Error: [id]: expected value of type [number] but got [undefined]).' ); }); @@ -263,7 +265,7 @@ describe('IBM Resilient connector', () => { }; it('updates the incident correctly', async () => { mockIncidentUpdate(); - const res = await connector.updateIncident(req, connectorMetricsService); + const res = await connector.updateIncident(req, connectorMetricsCollector); expect(res).toEqual({ title: '1', @@ -286,7 +288,7 @@ describe('IBM Resilient connector', () => { severityCode: 5, }, }, - connectorMetricsService + connectorMetricsCollector ); expect(requestMock.mock.calls[1][0]).toEqual({ @@ -343,14 +345,14 @@ describe('IBM Resilient connector', () => { }, ], }, - connectorMetricsService, + connectorMetricsCollector, }); }); it('it should throw an error', async () => { mockIncidentUpdate(true); - await expect(connector.updateIncident(req, connectorMetricsService)).rejects.toThrow( + await expect(connector.updateIncident(req, connectorMetricsCollector)).rejects.toThrow( '[Action][IBM Resilient]: Unable to update incident with id 1. Error: An error has occurred' ); }); @@ -373,7 +375,7 @@ describe('IBM Resilient connector', () => { ); requestMock.mockImplementation(() => createAxiosResponse({ data: { notRequired: 'test' } })); - await expect(connector.updateIncident(req, connectorMetricsService)).rejects.toThrow( + await expect(connector.updateIncident(req, connectorMetricsCollector)).rejects.toThrow( '[Action][IBM Resilient]: Unable to update incident with id 1. Error: Response validation failed (Error: [success]: expected value of type [boolean] but got [undefined]).' ); }); @@ -400,7 +402,7 @@ describe('IBM Resilient connector', () => { }); it('should call request with correct arguments', async () => { - await connector.addComment(req, connectorMetricsService); + await connector.addComment(req, connectorMetricsCollector); expect(requestMock).toHaveBeenCalledWith({ ...ignoredRequestFields, @@ -416,7 +418,7 @@ describe('IBM Resilient connector', () => { format: 'text', }, }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -425,7 +427,7 @@ describe('IBM Resilient connector', () => { throw new Error('An error has occurred'); }); - await expect(connector.addComment(req, connectorMetricsService)).rejects.toThrow( + await expect(connector.addComment(req, connectorMetricsCollector)).rejects.toThrow( '[Action][IBM Resilient]: Unable to create comment at incident with id 1. Error: An error has occurred.' ); }); @@ -441,7 +443,7 @@ describe('IBM Resilient connector', () => { }); it('should call request with correct arguments', async () => { - await connector.getIncidentTypes(undefined, connectorMetricsService); + await connector.getIncidentTypes(undefined, connectorMetricsCollector); expect(requestMock).toBeCalledTimes(1); expect(requestMock).toHaveBeenCalledWith({ ...ignoredRequestFields, @@ -452,12 +454,12 @@ describe('IBM Resilient connector', () => { Authorization: `Basic ${token}`, 'Content-Type': 'application/json', }, - connectorMetricsService, + connectorMetricsCollector, }); }); it('returns incident types correctly', async () => { - const res = await connector.getIncidentTypes(undefined, connectorMetricsService); + const res = await connector.getIncidentTypes(undefined, connectorMetricsCollector); expect(res).toEqual([ { id: '17', name: 'Communication error (fax; email)' }, @@ -470,7 +472,9 @@ describe('IBM Resilient connector', () => { throw new Error('An error has occurred'); }); - await expect(connector.getIncidentTypes(undefined, connectorMetricsService)).rejects.toThrow( + await expect( + connector.getIncidentTypes(undefined, connectorMetricsCollector) + ).rejects.toThrow( '[Action][IBM Resilient]: Unable to get incident types. Error: An error has occurred.' ); }); @@ -480,7 +484,9 @@ describe('IBM Resilient connector', () => { createAxiosResponse({ data: { id: '1001', name: 'Custom type' } }) ); - await expect(connector.getIncidentTypes(undefined, connectorMetricsService)).rejects.toThrow( + await expect( + connector.getIncidentTypes(undefined, connectorMetricsCollector) + ).rejects.toThrow( '[Action][IBM Resilient]: Unable to get incident types. Error: Response validation failed (Error: [values]: expected value of type [array] but got [undefined]).' ); }); @@ -498,7 +504,7 @@ describe('IBM Resilient connector', () => { }); it('should call request with correct arguments', async () => { - await connector.getSeverity(undefined, connectorMetricsService); + await connector.getSeverity(undefined, connectorMetricsCollector); expect(requestMock).toBeCalledTimes(1); expect(requestMock).toHaveBeenCalledWith({ ...ignoredRequestFields, @@ -509,12 +515,12 @@ describe('IBM Resilient connector', () => { Authorization: `Basic ${token}`, 'Content-Type': 'application/json', }, - connectorMetricsService, + connectorMetricsCollector, }); }); it('returns severity correctly', async () => { - const res = await connector.getSeverity(undefined, connectorMetricsService); + const res = await connector.getSeverity(undefined, connectorMetricsCollector); expect(res).toEqual([ { @@ -537,7 +543,7 @@ describe('IBM Resilient connector', () => { throw new Error('An error has occurred'); }); - await expect(connector.getSeverity(undefined, connectorMetricsService)).rejects.toThrow( + await expect(connector.getSeverity(undefined, connectorMetricsCollector)).rejects.toThrow( '[Action][IBM Resilient]: Unable to get severity. Error: An error has occurred.' ); }); @@ -547,7 +553,7 @@ describe('IBM Resilient connector', () => { createAxiosResponse({ data: { id: '10', name: 'Critical' } }) ); - await expect(connector.getSeverity(undefined, connectorMetricsService)).rejects.toThrow( + await expect(connector.getSeverity(undefined, connectorMetricsCollector)).rejects.toThrow( '[Action][IBM Resilient]: Unable to get severity. Error: Response validation failed (Error: [values]: expected value of type [array] but got [undefined]).' ); }); @@ -562,7 +568,7 @@ describe('IBM Resilient connector', () => { ); }); it('should call request with correct arguments', async () => { - await connector.getFields(undefined, connectorMetricsService); + await connector.getFields(undefined, connectorMetricsCollector); expect(requestMock).toBeCalledTimes(1); expect(requestMock).toHaveBeenCalledWith({ @@ -574,12 +580,12 @@ describe('IBM Resilient connector', () => { Authorization: `Basic ${token}`, 'Content-Type': 'application/json', }, - connectorMetricsService, + connectorMetricsCollector, }); }); it('returns common fields correctly', async () => { - const res = await connector.getFields(undefined, connectorMetricsService); + const res = await connector.getFields(undefined, connectorMetricsCollector); expect(res).toEqual(resilientFields); }); @@ -587,7 +593,7 @@ describe('IBM Resilient connector', () => { requestMock.mockImplementation(() => { throw new Error('An error has occurred'); }); - await expect(connector.getFields(undefined, connectorMetricsService)).rejects.toThrow( + await expect(connector.getFields(undefined, connectorMetricsCollector)).rejects.toThrow( 'Unable to get fields. Error: An error has occurred' ); }); @@ -595,7 +601,7 @@ describe('IBM Resilient connector', () => { it('should throw if the required attributes are not received in response', async () => { requestMock.mockImplementation(() => createAxiosResponse({ data: { someField: 'test' } })); - await expect(connector.getFields(undefined, connectorMetricsService)).rejects.toThrow( + await expect(connector.getFields(undefined, connectorMetricsCollector)).rejects.toThrow( '[Action][IBM Resilient]: Unable to get fields. Error: Response validation failed (Error: expected value of type [array] but got [Object]).' ); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/resilient/resilient.ts b/x-pack/plugins/stack_connectors/server/connector_types/resilient/resilient.ts index bd7c47619c7a4..6a5b9f36a20ea 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/resilient/resilient.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/resilient/resilient.ts @@ -10,7 +10,7 @@ import { omitBy, isNil } from 'lodash/fp'; import { CaseConnector, getBasicAuthHeader, ServiceParams } from '@kbn/actions-plugin/server'; import { schema, Type } from '@kbn/config-schema'; import { getErrorMessage } from '@kbn/actions-plugin/server/lib/axios_utils'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; import { CreateIncidentData, ExternalServiceIncidentResponse, @@ -120,7 +120,7 @@ export class ResilientConnector extends CaseConnector< public async createIncident( incident: Incident, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { try { let data: CreateIncidentData = { @@ -168,7 +168,7 @@ export class ResilientConnector extends CaseConnector< { unknowns: 'allow' } ), }, - connectorMetricsService + connectorMetricsCollector ); const { id, create_date: createDate } = res.data; @@ -188,10 +188,10 @@ export class ResilientConnector extends CaseConnector< public async updateIncident( { incidentId, incident }: UpdateIncidentParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { try { - const latestIncident = await this.getIncident({ id: incidentId }, connectorMetricsService); + const latestIncident = await this.getIncident({ id: incidentId }, connectorMetricsCollector); // Remove null or undefined values. Allowing null values sets the field in IBM Resilient to empty. const newIncident = omitBy(isNil, incident); @@ -205,14 +205,14 @@ export class ResilientConnector extends CaseConnector< headers: this.getAuthHeaders(), responseSchema: schema.object({ success: schema.boolean() }, { unknowns: 'allow' }), }, - connectorMetricsService + connectorMetricsCollector ); if (!res.data.success) { throw new Error('Error while updating incident'); } - const updatedIncident = await this.getIncident({ id: incidentId }, connectorMetricsService); + const updatedIncident = await this.getIncident({ id: incidentId }, connectorMetricsCollector); return { title: `${updatedIncident.id}`, @@ -232,7 +232,7 @@ export class ResilientConnector extends CaseConnector< public async addComment( { incidentId, comment }: { incidentId: string; comment: string }, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) { try { await this.request( @@ -243,7 +243,7 @@ export class ResilientConnector extends CaseConnector< headers: this.getAuthHeaders(), responseSchema: schema.object({}, { unknowns: 'allow' }), }, - connectorMetricsService + connectorMetricsCollector ); } catch (error) { throw new Error( @@ -257,7 +257,7 @@ export class ResilientConnector extends CaseConnector< public async getIncident( { id }: { id: string }, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { try { const res = await this.request( @@ -270,7 +270,7 @@ export class ResilientConnector extends CaseConnector< headers: this.getAuthHeaders(), responseSchema: GetIncidentResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ); return res.data; @@ -283,7 +283,7 @@ export class ResilientConnector extends CaseConnector< public async getIncidentTypes( params: unknown, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { try { const res = await this.request( @@ -293,7 +293,7 @@ export class ResilientConnector extends CaseConnector< headers: this.getAuthHeaders(), responseSchema: GetIncidentTypesResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ); const incidentTypes = res.data?.values ?? []; @@ -311,7 +311,7 @@ export class ResilientConnector extends CaseConnector< public async getSeverity( params: unknown, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { try { const res = await this.request( @@ -321,7 +321,7 @@ export class ResilientConnector extends CaseConnector< headers: this.getAuthHeaders(), responseSchema: GetSeverityResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ); const severities = res.data?.values ?? []; @@ -336,7 +336,7 @@ export class ResilientConnector extends CaseConnector< } } - public async getFields(params: unknown, connectorMetricsService: ConnectorMetricsService) { + public async getFields(params: unknown, connectorMetricsCollector: ConnectorMetricsCollector) { try { const res = await this.request( { @@ -345,7 +345,7 @@ export class ResilientConnector extends CaseConnector< headers: this.getAuthHeaders(), responseSchema: GetCommonFieldsResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ); const fields = res.data.map((field) => { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.test.ts index 1cf6104a7c008..80bd1fcb9a816 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.test.ts @@ -13,15 +13,15 @@ import { } from '../../../common/sentinelone/types'; import { API_PATH } from './sentinelone'; import { SentinelOneGetActivitiesResponseSchema } from '../../../common/sentinelone/schema'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; describe('SentinelOne Connector', () => { let connectorInstance: ReturnType; - let connectorMetricsService: ConnectorMetricsService; + let connectorMetricsCollector: ConnectorMetricsCollector; beforeEach(() => { connectorInstance = sentinelOneConnectorMocks.create(); - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); describe('#fetchAgentFiles()', () => { @@ -39,7 +39,7 @@ describe('SentinelOne Connector', () => { connectorInstance.mockResponses.getAgentsApiResponse.data.length = 0; await expect( - connectorInstance.fetchAgentFiles(fetchAgentFilesParams, connectorMetricsService) + connectorInstance.fetchAgentFiles(fetchAgentFilesParams, connectorMetricsCollector) ).rejects.toHaveProperty('message', 'No agent found in SentinelOne for UUID [uuid-1]'); }); @@ -47,7 +47,7 @@ describe('SentinelOne Connector', () => { const fetchFilesUrl = `${connectorInstance.constructorParams.config.url}${API_PATH}/agents/1913920934584665209/actions/fetch-files`; const response = await connectorInstance.fetchAgentFiles( fetchAgentFilesParams, - connectorMetricsService + connectorMetricsCollector ); expect(response).toEqual({ data: { success: true }, errors: null }); @@ -82,13 +82,13 @@ describe('SentinelOne Connector', () => { connectorInstance.mockResponses.getAgentsApiResponse.data.length = 0; await expect( - connectorInstance.downloadAgentFile(downloadAgentFileParams, connectorMetricsService) + connectorInstance.downloadAgentFile(downloadAgentFileParams, connectorMetricsCollector) ).rejects.toHaveProperty('message', 'No agent found in SentinelOne for UUID [uuid-1]'); }); it('should call SentinelOne api with expected url', async () => { await expect( - connectorInstance.downloadAgentFile(downloadAgentFileParams, connectorMetricsService) + connectorInstance.downloadAgentFile(downloadAgentFileParams, connectorMetricsCollector) ).resolves.toEqual(connectorInstance.mockResponses.downloadAgentFileApiResponse); }); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.ts b/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.ts index 68f2527889163..ad04ca7930eb7 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.ts @@ -8,7 +8,7 @@ import { ServiceParams, SubActionConnector } from '@kbn/actions-plugin/server'; import type { AxiosError } from 'axios'; import { SubActionRequestParams } from '@kbn/actions-plugin/server/sub_action_framework/types'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; import type { SentinelOneConfig, SentinelOneSecrets, @@ -137,9 +137,9 @@ export class SentinelOneConnector extends SubActionConnector< public async fetchAgentFiles( { files, agentUUID, zipPassCode }: SentinelOneFetchAgentFilesParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) { - const agent = await this.getAgents({ uuid: agentUUID }, connectorMetricsService); + const agent = await this.getAgents({ uuid: agentUUID }, connectorMetricsCollector); const agentId = agent.data[0]?.id; if (!agentId) { @@ -158,15 +158,15 @@ export class SentinelOneConnector extends SubActionConnector< }, responseSchema: SentinelOneFetchAgentFilesResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ); } public async downloadAgentFile( { agentUUID, activityId }: SentinelOneDownloadAgentFileParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) { - const agent = await this.getAgents({ uuid: agentUUID }, connectorMetricsService); + const agent = await this.getAgents({ uuid: agentUUID }, connectorMetricsCollector); const agentId = agent.data[0]?.id; if (!agentId) { @@ -180,13 +180,13 @@ export class SentinelOneConnector extends SubActionConnector< responseType: 'stream', responseSchema: SentinelOneDownloadAgentFileResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ); } public async getActivities( queryParams?: SentinelOneGetActivitiesParams, - connectorMetricsService?: ConnectorMetricsService + connectorMetricsCollector?: ConnectorMetricsCollector ) { return this.sentinelOneApiRequest( { @@ -195,13 +195,13 @@ export class SentinelOneConnector extends SubActionConnector< params: queryParams, responseSchema: SentinelOneGetActivitiesResponseSchema, }, - connectorMetricsService! + connectorMetricsCollector! ); } public async executeScript( { filter, script }: SentinelOneExecuteScriptParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) { if (!filter.ids && !filter.uuids) { throw new Error(`A filter must be defined; either 'ids' or 'uuids'`); @@ -220,15 +220,15 @@ export class SentinelOneConnector extends SubActionConnector< }, responseSchema: SentinelOneExecuteScriptResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ); } public async isolateHost( { alertIds, ...payload }: SentinelOneIsolateHostParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) { - const response = await this.getAgents(payload, connectorMetricsService); + const response = await this.getAgents(payload, connectorMetricsCollector); if (response.data.length === 0) { const errorMessage = 'No agents found'; @@ -255,15 +255,15 @@ export class SentinelOneConnector extends SubActionConnector< }, responseSchema: SentinelOneIsolateHostResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ); } public async releaseHost( { alertIds, ...payload }: SentinelOneIsolateHostParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) { - const response = await this.getAgents(payload, connectorMetricsService); + const response = await this.getAgents(payload, connectorMetricsCollector); if (response.data.length === 0) { throw new Error('No agents found'); @@ -286,13 +286,13 @@ export class SentinelOneConnector extends SubActionConnector< }, responseSchema: SentinelOneIsolateHostResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ); } public async getAgents( payload: SentinelOneGetAgentsParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { return this.sentinelOneApiRequest( { @@ -302,13 +302,13 @@ export class SentinelOneConnector extends SubActionConnector< }, responseSchema: SentinelOneGetAgentsResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ); } public async getRemoteScriptStatus( payload: SentinelOneGetRemoteScriptStatusParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ) { return this.sentinelOneApiRequest( { @@ -318,13 +318,13 @@ export class SentinelOneConnector extends SubActionConnector< }, responseSchema: SentinelOneGetRemoteScriptStatusResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ); } private async sentinelOneApiRequest( req: SubActionRequestParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const response = await this.request( { @@ -334,7 +334,7 @@ export class SentinelOneConnector extends SubActionConnector< APIToken: this.secrets.token, }, }, - connectorMetricsService + connectorMetricsCollector ); return response.data; @@ -364,7 +364,7 @@ export class SentinelOneConnector extends SubActionConnector< public async getRemoteScripts( payload: SentinelOneGetRemoteScriptsParams, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { return this.sentinelOneApiRequest( { @@ -375,7 +375,7 @@ export class SentinelOneConnector extends SubActionConnector< }, responseSchema: SentinelOneGetRemoteScriptsResponseSchema, }, - connectorMetricsService + connectorMetricsCollector ); } } diff --git a/x-pack/plugins/stack_connectors/server/connector_types/server_log/index.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/server_log/index.test.ts index 082098023fc3f..fd819854b1ccb 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/server_log/index.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/server_log/index.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { validateParams } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector, validateParams } from '@kbn/actions-plugin/server/lib'; import { Logger } from '@kbn/core/server'; import { actionsMock } from '@kbn/actions-plugin/server/mocks'; import { getConnectorType, ServerLogConnectorType, ServerLogConnectorTypeExecutorOptions } from '.'; @@ -107,6 +107,7 @@ describe('execute()', () => { secrets: {}, configurationUtilities, logger: mockedLogger, + connectorMetricsCollector: new ConnectorMetricsCollector(), }; await connectorType.executor(executorOptions); expect(mockedLogger.info).toHaveBeenCalledWith('Server log: message text here'); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/index.ts index c456f4f6b5a1b..236589545dd36 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/index.ts @@ -109,7 +109,7 @@ async function executorITOM( secrets, configurationUtilities, logger, - connectorMetricsService, + connectorMetricsCollector, } = execOptions; const { subAction, subActionParams } = params; const connectorTokenClient = execOptions.services.connectorTokenClient; @@ -127,7 +127,7 @@ async function executorITOM( serviceConfig: externalServiceConfig, connectorTokenClient, createServiceFn: createService, - connectorMetricsService, + connectorMetricsCollector, }); const apiAsRecord = api as unknown as Record; diff --git a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/service.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/service.test.ts index b77206888ee62..2dafe4f83be60 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/service.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/service.test.ts @@ -15,7 +15,7 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; import { actionsConfigMock } from '@kbn/actions-plugin/server/actions_config.mock'; import { snExternalServiceConfig } from '../lib/servicenow/config'; import { itomEventParams, serviceNowChoices } from '../lib/servicenow/mocks'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; const logger = loggingSystemMock.create().get() as jest.Mocked; @@ -34,10 +34,10 @@ const configurationUtilities = actionsConfigMock.create(); describe('ServiceNow SIR service', () => { let service: ExternalServiceITOM; - let connectorMetricsService: ConnectorMetricsService; + let connectorMetricsCollector: ConnectorMetricsCollector; beforeEach(() => { - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); service = createExternalService({ credentials: { config: { apiUrl: 'https://example.com/', isOAuth: false }, @@ -47,7 +47,7 @@ describe('ServiceNow SIR service', () => { configurationUtilities, serviceConfig: snExternalServiceConfig['.servicenow-itom'], axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }) as ExternalServiceITOM; }); @@ -73,7 +73,7 @@ describe('ServiceNow SIR service', () => { url: 'https://example.com/api/global/em/jsonv2', method: 'post', data: { records: [itomEventParams] }, - connectorMetricsService, + connectorMetricsCollector, }); }); }); @@ -90,7 +90,7 @@ describe('ServiceNow SIR service', () => { logger, configurationUtilities, url: 'https://example.com/api/now/table/sys_choice?sysparm_query=name=task^ORname=em_event^element=severity^language=en&sysparm_fields=label,value,dependent_value,element', - connectorMetricsService, + connectorMetricsCollector, }); }); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/service.ts b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/service.ts index 7215e1cf638ca..ba99737c4f75d 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/service.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/service.ts @@ -23,7 +23,7 @@ export const createExternalService: ServiceFactory = ({ configurationUtilities, serviceConfig, axiosInstance, - connectorMetricsService, + connectorMetricsCollector, }): ExternalServiceITOM => { const snService = createExternalServiceCommon({ credentials, @@ -31,7 +31,7 @@ export const createExternalService: ServiceFactory = ({ configurationUtilities, serviceConfig, axiosInstance, - connectorMetricsService, + connectorMetricsCollector, }); const addEvent = async (params: ExecutorSubActionAddEventParams) => { @@ -43,7 +43,7 @@ export const createExternalService: ServiceFactory = ({ method: 'post', data: { records: [params] }, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); snService.checkInstance(res); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itsm/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itsm/index.ts index d58dff262d0a1..4e20e027a2481 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itsm/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itsm/index.ts @@ -133,7 +133,7 @@ async function executor( services, configurationUtilities, logger, - connectorMetricsService, + connectorMetricsCollector, } = execOptions; const { subAction, subActionParams } = params; const connectorTokenClient = services.connectorTokenClient; @@ -151,7 +151,7 @@ async function executor( serviceConfig: externalServiceConfig, connectorTokenClient, createServiceFn: createService, - connectorMetricsService, + connectorMetricsCollector, }); const apiAsRecord = api as unknown as Record; diff --git a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itsm/service.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itsm/service.test.ts index 9fb52bab57a7d..8bc567dde9bc5 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itsm/service.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itsm/service.test.ts @@ -15,7 +15,7 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; import { actionsConfigMock } from '@kbn/actions-plugin/server/actions_config.mock'; import { serviceNowCommonFields, serviceNowChoices } from '../lib/servicenow/mocks'; import { snExternalServiceConfig } from '../lib/servicenow/config'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; const logger = loggingSystemMock.create().get() as jest.Mocked; jest.mock('axios', () => ({ @@ -123,7 +123,7 @@ const expectImportedIncident = (update: boolean) => { configurationUtilities, url: 'https://example.com/api/x_elas2_inc_int/elastic_api/health', method: 'get', - connectorMetricsService: expect.any(ConnectorMetricsService), + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); expect(requestMock).toHaveBeenNthCalledWith(2, { @@ -137,7 +137,7 @@ const expectImportedIncident = (update: boolean) => { u_description: 'desc', ...(update ? { elastic_incident_id: '1' } : {}), }, - connectorMetricsService: expect.any(ConnectorMetricsService), + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); expect(requestMock).toHaveBeenNthCalledWith(3, { @@ -146,17 +146,17 @@ const expectImportedIncident = (update: boolean) => { configurationUtilities, url: 'https://example.com/api/now/v2/table/incident/1', method: 'get', - connectorMetricsService: expect.any(ConnectorMetricsService), + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); }; describe('ServiceNow service', () => { let service: ExternalService; - let connectorMetricsService: ConnectorMetricsService; + let connectorMetricsCollector: ConnectorMetricsCollector; beforeEach(() => { jest.clearAllMocks(); - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); service = createExternalService({ credentials: { // The trailing slash at the end of the url is intended. @@ -168,7 +168,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: snExternalServiceConfig['.servicenow'], axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -184,7 +184,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: snExternalServiceConfig['.servicenow'], axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }) ).toThrow(); }); @@ -225,7 +225,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: snExternalServiceConfig['.servicenow'], axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }) ).toThrow(); }); @@ -390,7 +390,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: snExternalServiceConfig['.servicenow'], axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }) ).toThrow(); }); @@ -418,7 +418,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/incident/1', method: 'get', - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -432,7 +432,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow'], table: 'sn_si_incident' }, axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }); requestMock.mockImplementation(() => ({ @@ -446,7 +446,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/sn_si_incident/1', method: 'get', - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -500,7 +500,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: snExternalServiceConfig['.servicenow-sir'], axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }); const res = await createIncident(service); @@ -511,7 +511,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/x_elas2_sir_int/elastic_api/health', method: 'get', - connectorMetricsService, + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(2, { @@ -521,7 +521,7 @@ describe('ServiceNow service', () => { url: 'https://example.com/api/now/import/x_elas2_sir_int_elastic_si_incident', method: 'post', data: { u_short_description: 'title', u_description: 'desc' }, - connectorMetricsService, + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(3, { @@ -530,7 +530,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/sn_si_incident/1', method: 'get', - connectorMetricsService, + connectorMetricsCollector, }); expect(res.url).toEqual('https://example.com/nav_to.do?uri=sn_si_incident.do?sys_id=1'); @@ -589,7 +589,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow'], useImportAPI: false }, axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -614,7 +614,7 @@ describe('ServiceNow service', () => { url: 'https://example.com/api/now/v2/table/incident', method: 'post', data: { short_description: 'title', description: 'desc' }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -628,7 +628,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow-sir'], useImportAPI: false }, axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }); mockIncidentResponse(false); @@ -644,7 +644,7 @@ describe('ServiceNow service', () => { url: 'https://example.com/api/now/v2/table/sn_si_incident', method: 'post', data: { short_description: 'title', description: 'desc' }, - connectorMetricsService, + connectorMetricsCollector, }); expect(res.url).toEqual('https://example.com/nav_to.do?uri=sn_si_incident.do?sys_id=1'); @@ -681,7 +681,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: snExternalServiceConfig['.servicenow-sir'], axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }); const res = await updateIncident(service); @@ -691,7 +691,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/x_elas2_sir_int/elastic_api/health', method: 'get', - connectorMetricsService, + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(2, { @@ -701,7 +701,7 @@ describe('ServiceNow service', () => { url: 'https://example.com/api/now/import/x_elas2_sir_int_elastic_si_incident', method: 'post', data: { u_short_description: 'title', u_description: 'desc', elastic_incident_id: '1' }, - connectorMetricsService, + connectorMetricsCollector, }); expect(requestMock).toHaveBeenNthCalledWith(3, { @@ -710,7 +710,7 @@ describe('ServiceNow service', () => { configurationUtilities, url: 'https://example.com/api/now/v2/table/sn_si_incident/1', method: 'get', - connectorMetricsService, + connectorMetricsCollector, }); expect(res.url).toEqual('https://example.com/nav_to.do?uri=sn_si_incident.do?sys_id=1'); @@ -772,7 +772,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow'], useImportAPI: false }, axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -798,7 +798,7 @@ describe('ServiceNow service', () => { url: 'https://example.com/api/now/v2/table/incident/1', method: 'patch', data: { short_description: 'title', description: 'desc' }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -812,7 +812,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow-sir'], useImportAPI: false }, axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }); mockIncidentResponse(false); @@ -829,7 +829,7 @@ describe('ServiceNow service', () => { url: 'https://example.com/api/now/v2/table/sn_si_incident/1', method: 'patch', data: { short_description: 'title', description: 'desc' }, - connectorMetricsService, + connectorMetricsCollector, }); expect(res.url).toEqual('https://example.com/nav_to.do?uri=sn_si_incident.do?sys_id=1'); @@ -849,7 +849,7 @@ describe('ServiceNow service', () => { logger, configurationUtilities, url: 'https://example.com/api/now/table/sys_dictionary?sysparm_query=name=task^ORname=incident^internal_type=string&active=true&array=false&read_only=false&sysparm_fields=max_length,element,column_label,mandatory', - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -871,7 +871,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow'], table: 'sn_si_incident' }, axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }); requestMock.mockImplementation(() => ({ @@ -884,7 +884,7 @@ describe('ServiceNow service', () => { logger, configurationUtilities, url: 'https://example.com/api/now/table/sys_dictionary?sysparm_query=name=task^ORname=sn_si_incident^internal_type=string&active=true&array=false&read_only=false&sysparm_fields=max_length,element,column_label,mandatory', - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -921,7 +921,7 @@ describe('ServiceNow service', () => { logger, configurationUtilities, url: 'https://example.com/api/now/table/sys_choice?sysparm_query=name=task^ORname=incident^element=priority^ORelement=category^language=en&sysparm_fields=label,value,dependent_value,element', - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -943,7 +943,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow'], table: 'sn_si_incident' }, axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }); requestMock.mockImplementation(() => ({ @@ -957,7 +957,7 @@ describe('ServiceNow service', () => { logger, configurationUtilities, url: 'https://example.com/api/now/table/sys_choice?sysparm_query=name=task^ORname=sn_si_incident^element=priority^ORelement=category^language=en&sysparm_fields=label,value,dependent_value,element', - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -1050,7 +1050,7 @@ describe('ServiceNow service', () => { configurationUtilities, serviceConfig: { ...snExternalServiceConfig['.servicenow'], useImportAPI: false }, axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }); await service.checkIfApplicationIsInstalled(); expect(requestMock).not.toHaveBeenCalled(); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/index.ts index f48e87280f2d3..c880848d0667c 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/index.ts @@ -124,7 +124,7 @@ async function executor( services, configurationUtilities, logger, - connectorMetricsService, + connectorMetricsCollector, } = execOptions; const { subAction, subActionParams } = params; const connectorTokenClient = services.connectorTokenClient; @@ -142,7 +142,7 @@ async function executor( serviceConfig: externalServiceConfig, connectorTokenClient, createServiceFn: createService, - connectorMetricsService, + connectorMetricsCollector, }); const apiAsRecord = api as unknown as Record; diff --git a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/service.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/service.test.ts index eaf0a91f02a03..cb590d85f6298 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/service.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/service.test.ts @@ -15,7 +15,7 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; import { actionsConfigMock } from '@kbn/actions-plugin/server/actions_config.mock'; import { observables } from '../lib/servicenow/mocks'; import { snExternalServiceConfig } from '../lib/servicenow/config'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; const logger = loggingSystemMock.create().get() as jest.Mocked; @@ -32,7 +32,7 @@ jest.mock('@kbn/actions-plugin/server/lib/axios_utils', () => { axios.create = jest.fn(() => axios); const requestMock = utils.request as jest.Mock; const configurationUtilities = actionsConfigMock.create(); -let connectorMetricsService: ConnectorMetricsService; +let connectorMetricsCollector: ConnectorMetricsCollector; const mockApplicationVersion = () => requestMock.mockImplementationOnce(() => ({ @@ -72,7 +72,7 @@ const expectAddObservables = (single: boolean) => { configurationUtilities, url: 'https://example.com/api/x_elas2_sir_int/elastic_api/health', method: 'get', - connectorMetricsService: expect.any(ConnectorMetricsService), + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); const url = single @@ -88,7 +88,7 @@ const expectAddObservables = (single: boolean) => { url, method: 'post', data, - connectorMetricsService: expect.any(ConnectorMetricsService), + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }); }; @@ -96,7 +96,7 @@ describe('ServiceNow SIR service', () => { let service: ExternalServiceSIR; beforeEach(() => { - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); service = createExternalService({ credentials: { config: { apiUrl: 'https://example.com/', isOAuth: false }, @@ -106,7 +106,7 @@ describe('ServiceNow SIR service', () => { configurationUtilities, serviceConfig: snExternalServiceConfig['.servicenow-sir'], axiosInstance: axios, - connectorMetricsService, + connectorMetricsCollector, }) as ExternalServiceSIR; }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/service.ts b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/service.ts index 80c37c6ab9a81..b8ba4826d6838 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/service.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/service.ts @@ -28,7 +28,7 @@ export const createExternalService: ServiceFactory = ({ configurationUtilities, serviceConfig, axiosInstance, - connectorMetricsService, + connectorMetricsCollector, }): ExternalServiceSIR => { const snService = createExternalServiceCommon({ credentials, @@ -36,7 +36,7 @@ export const createExternalService: ServiceFactory = ({ configurationUtilities, serviceConfig, axiosInstance, - connectorMetricsService, + connectorMetricsCollector, }); const _addObservable = async (data: Observable | Observable[], url: string) => { @@ -49,7 +49,7 @@ export const createExternalService: ServiceFactory = ({ method: 'post', data, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); snService.checkInstance(res); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/slack/index.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/slack/index.test.ts index 154603acfb45c..aa08139915739 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/slack/index.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/slack/index.test.ts @@ -9,7 +9,7 @@ import { Logger } from '@kbn/core/server'; import { Services, ActionTypeExecutorResult as ConnectorTypeExecutorResult, - ConnectorMetricsService, + ConnectorMetricsCollector, } from '@kbn/actions-plugin/server/types'; import { validateParams, validateSecrets } from '@kbn/actions-plugin/server/lib'; import { @@ -36,7 +36,7 @@ const mockedLogger: jest.Mocked = loggerMock.create(); let connectorType: SlackConnectorType; let configurationUtilities: jest.Mocked; -let connectorMetricsService: ConnectorMetricsService; +let connectorMetricsCollector: ConnectorMetricsCollector; beforeEach(() => { configurationUtilities = actionsConfigMock.create(); @@ -45,7 +45,7 @@ beforeEach(() => { return { status: 'ok', actionId: options.actionId }; }, }); - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); describe('connector registration', () => { @@ -184,7 +184,7 @@ describe('execute()', () => { params: { message: 'this invocation should succeed' }, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); expect(response).toMatchInlineSnapshot(` Object { @@ -205,7 +205,7 @@ describe('execute()', () => { params: { message: 'failure: this invocation should fail' }, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }) ).rejects.toThrowErrorMatchingInlineSnapshot( `"slack mockExecutor failure: this invocation should fail"` @@ -231,7 +231,7 @@ describe('execute()', () => { params: { message: 'this invocation should succeed' }, configurationUtilities: configUtils, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); expect(mockedLogger.debug).toHaveBeenCalledWith( 'IncomingWebhook was called with proxyUrl https://someproxyhost' @@ -258,7 +258,7 @@ describe('execute()', () => { params: { message: 'this invocation should succeed' }, configurationUtilities: configUtils, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); expect(mockedLogger.debug).not.toHaveBeenCalledWith( 'IncomingWebhook was called with proxyUrl https://someproxyhost' @@ -285,7 +285,7 @@ describe('execute()', () => { params: { message: 'this invocation should succeed' }, configurationUtilities: configUtils, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); expect(mockedLogger.debug).toHaveBeenCalledWith( 'IncomingWebhook was called with proxyUrl https://someproxyhost' @@ -312,7 +312,7 @@ describe('execute()', () => { params: { message: 'this invocation should succeed' }, configurationUtilities: configUtils, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); expect(mockedLogger.debug).toHaveBeenCalledWith( 'IncomingWebhook was called with proxyUrl https://someproxyhost' @@ -339,7 +339,7 @@ describe('execute()', () => { params: { message: 'this invocation should succeed' }, configurationUtilities: configUtils, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); expect(mockedLogger.debug).not.toHaveBeenCalledWith( 'IncomingWebhook was called with proxyUrl https://someproxyhost' diff --git a/x-pack/plugins/stack_connectors/server/connector_types/slack/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/slack/index.ts index fd76e736e4ef3..173f309072bb5 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/slack/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/slack/index.ts @@ -139,7 +139,7 @@ function validateConnectorTypeConfig( async function slackExecutor( execOptions: SlackConnectorTypeExecutorOptions ): Promise> { - const { actionId, secrets, params, configurationUtilities, logger, connectorMetricsService } = + const { actionId, secrets, params, configurationUtilities, logger, connectorMetricsCollector } = execOptions; let result: IncomingWebhookResult; @@ -164,7 +164,7 @@ async function slackExecutor( const webhook = new IncomingWebhook(webhookUrl, { agent, }); - connectorMetricsService.addRequestBodyBytes(undefined, { text: message }); + connectorMetricsCollector.addRequestBodyBytes(undefined, { text: message }); result = await webhook.send(message); } catch (err) { if (err.original == null || err.original.response == null) { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.test.ts index 59030a71aaa05..6f183f9988516 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.test.ts @@ -7,7 +7,7 @@ import axios from 'axios'; import { Logger } from '@kbn/core/server'; -import { Services } from '@kbn/actions-plugin/server/types'; +import { ConnectorMetricsCollector, Services } from '@kbn/actions-plugin/server/types'; import { validateConfig, validateParams, validateSecrets } from '@kbn/actions-plugin/server/lib'; import { getConnectorType } from '.'; import { actionsConfigMock } from '@kbn/actions-plugin/server/actions_config.mock'; @@ -39,10 +39,12 @@ const headers = { let connectorType: SlackApiConnectorType; let configurationUtilities: jest.Mocked; +let connectorMetricsCollector: ConnectorMetricsCollector; beforeEach(() => { configurationUtilities = actionsConfigMock.create(); connectorType = getConnectorType(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); describe('connector registration', () => { @@ -198,6 +200,7 @@ describe('execute', () => { params: {} as PostMessageParams, configurationUtilities, logger: mockedLogger, + connectorMetricsCollector, }) ).rejects.toThrowErrorMatchingInlineSnapshot( `"[Action][ExternalService] -> [Slack API] Unsupported subAction type undefined."` @@ -296,6 +299,7 @@ describe('execute', () => { }, configurationUtilities, logger: mockedLogger, + connectorMetricsCollector, }); expect(requestMock).toHaveBeenCalledWith({ @@ -306,6 +310,7 @@ describe('execute', () => { method: 'post', url: 'https://slack.com/api/chat.postMessage', data: { channel: 'general', text: 'some text' }, + connectorMetricsCollector, }); expect(response).toEqual({ @@ -386,6 +391,7 @@ describe('execute', () => { }, configurationUtilities, logger: mockedLogger, + connectorMetricsCollector, }); expect(requestMock).toHaveBeenCalledWith({ @@ -396,6 +402,7 @@ describe('execute', () => { method: 'post', url: 'https://slack.com/api/chat.postMessage', data: { channel: 'LKJHGF345', text: 'some text' }, + connectorMetricsCollector, }); expect(response).toEqual({ @@ -476,6 +483,7 @@ describe('execute', () => { }, configurationUtilities, logger: mockedLogger, + connectorMetricsCollector, }); expect(requestMock).toHaveBeenCalledWith({ @@ -486,6 +494,7 @@ describe('execute', () => { method: 'post', url: 'https://slack.com/api/chat.postMessage', data: { channel: 'LKJHGF345', blocks: testBlock.blocks }, + connectorMetricsCollector, }); expect(response).toEqual({ @@ -525,6 +534,7 @@ describe('execute', () => { }, configurationUtilities, logger: mockedLogger, + connectorMetricsCollector, }); expect(requestMock).toHaveBeenCalledWith({ @@ -534,6 +544,7 @@ describe('execute', () => { logger: mockedLogger, method: 'get', url: 'https://slack.com/api/conversations.info?channel=ZXCVBNM567', + connectorMetricsCollector, }); expect(response).toEqual({ diff --git a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.ts index 2389198b74cf1..4d5052f50fb35 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.ts @@ -102,7 +102,7 @@ const slackApiExecutor = async ({ secrets, configurationUtilities, logger, - connectorMetricsService, + connectorMetricsCollector, }: SlackApiExecutorOptions): Promise> => { const subAction = params.subAction; @@ -125,7 +125,7 @@ const slackApiExecutor = async ({ }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); if (subAction === 'validChannelId') { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.test.ts index dc2a9a4a61538..4befb126fe14f 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.test.ts @@ -13,7 +13,7 @@ import { actionsConfigMock } from '@kbn/actions-plugin/server/actions_config.moc import { createExternalService } from './service'; import { SlackApiService } from '../../../common/slack_api/types'; import { SLACK_API_CONNECTOR_ID } from '../../../common/slack_api/constants'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; const logger = loggingSystemMock.create().get() as jest.Mocked; @@ -29,7 +29,7 @@ jest.mock('@kbn/actions-plugin/server/lib/axios_utils', () => { axios.create = jest.fn(() => axios); const requestMock = request as jest.Mock; const configurationUtilities = actionsConfigMock.create(); -let connectorMetricsService: ConnectorMetricsService; +let connectorMetricsCollector: ConnectorMetricsCollector; const channel = { id: 'channel_id_1', @@ -119,14 +119,14 @@ describe('Slack API service', () => { let service: SlackApiService; beforeAll(() => { - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); service = createExternalService( { secrets: { token: 'token' }, }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); }); @@ -143,7 +143,7 @@ describe('Slack API service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ) ).toThrowErrorMatchingInlineSnapshot(`"[Action][Slack API]: Wrong configuration."`); }); @@ -177,7 +177,7 @@ describe('Slack API service', () => { configurationUtilities, method: 'get', url: 'https://slack.com/api/conversations.info?channel=channel_id_1', - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -213,7 +213,7 @@ describe('Slack API service', () => { method: 'post', url: 'https://slack.com/api/chat.postMessage', data: { channel: 'general', text: 'a message' }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -238,7 +238,7 @@ describe('Slack API service', () => { method: 'post', url: 'https://slack.com/api/chat.postMessage', data: { channel: 'QWEERTYU987', text: 'a message' }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -259,7 +259,7 @@ describe('Slack API service', () => { method: 'post', url: 'https://slack.com/api/chat.postMessage', data: { channel: 'QWEERTYU987', text: 'a message' }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -300,7 +300,7 @@ describe('Slack API service', () => { method: 'post', url: 'https://slack.com/api/chat.postMessage', data: { channel: 'general', blocks: testBlock.blocks }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -325,7 +325,7 @@ describe('Slack API service', () => { method: 'post', url: 'https://slack.com/api/chat.postMessage', data: { channel: 'QWEERTYU987', blocks: testBlock.blocks }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -349,7 +349,7 @@ describe('Slack API service', () => { method: 'post', url: 'https://slack.com/api/chat.postMessage', data: { channel: 'QWEERTYU987', blocks: testBlock.blocks }, - connectorMetricsService, + connectorMetricsCollector, }); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.ts b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.ts index eefb3713a6416..a21c07ccef45b 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.ts @@ -13,7 +13,7 @@ import { request } from '@kbn/actions-plugin/server/lib/axios_utils'; import { pipe } from 'fp-ts/lib/pipeable'; import { map, getOrElse } from 'fp-ts/lib/Option'; import type { ActionTypeExecutorResult as ConnectorTypeExecutorResult } from '@kbn/actions-plugin/server/types'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/types'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/types'; import { SLACK_CONNECTOR_NAME } from './translations'; import type { PostMessageSubActionParams, @@ -113,7 +113,7 @@ export const createExternalService = ( }, logger: Logger, configurationUtilities: ActionsConfigurationUtilities, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): SlackApiService => { const { token } = secrets; const { allowedChannels } = config || { allowedChannels: [] }; @@ -141,7 +141,7 @@ export const createExternalService = ( method: 'get', headers, url: `${SLACK_URL}conversations.info?channel=${channelId}`, - connectorMetricsService, + connectorMetricsCollector, }); }; if (channelId.length === 0) { @@ -210,7 +210,7 @@ export const createExternalService = ( data: { channel: channelToUse, text }, headers, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); return buildSlackExecutorSuccessResponse({ slackApiResponseData: result.data }); @@ -236,7 +236,7 @@ export const createExternalService = ( data: { channel: channelToUse, blocks: blockJson.blocks }, headers, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); return buildSlackExecutorSuccessResponse({ slackApiResponseData: result.data }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/swimlane/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/swimlane/index.ts index 2afc1624d034d..edf0a4a0edf2b 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/swimlane/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/swimlane/index.ts @@ -83,7 +83,7 @@ async function executor( secrets, configurationUtilities, logger, - connectorMetricsService, + connectorMetricsCollector, } = execOptions; const { subAction, subActionParams } = params as ExecutorParams; let data: SwimlaneExecutorResultData | null = null; @@ -95,7 +95,7 @@ async function executor( }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); if (!api[subAction]) { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/swimlane/service.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/swimlane/service.test.ts index 0749b2171bcea..2b17e1b480783 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/swimlane/service.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/swimlane/service.test.ts @@ -14,7 +14,7 @@ import { request, createAxiosResponse } from '@kbn/actions-plugin/server/lib/axi import { createExternalService } from './service'; import { mappings } from './mocks'; import { ExternalService } from './types'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; const logger = loggingSystemMock.create().get() as jest.Mocked; @@ -57,10 +57,10 @@ describe('Swimlane Service', () => { }; const url = config.apiUrl.slice(0, -1); - let connectorMetricsService: ConnectorMetricsService; + let connectorMetricsCollector: ConnectorMetricsCollector; beforeAll(() => { - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); service = createExternalService( { // The trailing slash at the end of the url is intended. @@ -70,7 +70,7 @@ describe('Swimlane Service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); }); beforeEach(() => { @@ -92,7 +92,7 @@ describe('Swimlane Service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ) ).toThrow(); }); @@ -110,7 +110,7 @@ describe('Swimlane Service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ) ).toThrow(); }); @@ -129,7 +129,7 @@ describe('Swimlane Service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ) ).toThrow(); }); @@ -146,7 +146,7 @@ describe('Swimlane Service', () => { }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); }).toThrow(); }); @@ -199,7 +199,7 @@ describe('Swimlane Service', () => { url: `${url}/api/app/${config.appId}/record`, method: 'post', configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -283,7 +283,7 @@ describe('Swimlane Service', () => { url: `${url}/api/app/${config.appId}/record/${incidentId}`, method: 'patch', configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -363,7 +363,7 @@ describe('Swimlane Service', () => { url: `${url}/api/app/${config.appId}/record/${incidentId}/${mappings.commentsConfig.id}/comment`, method: 'post', configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/swimlane/service.ts b/x-pack/plugins/stack_connectors/server/connector_types/swimlane/service.ts index 261de60646510..bd0f4367e1313 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/swimlane/service.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/swimlane/service.ts @@ -14,7 +14,7 @@ import { throwIfResponseIsNotValid, } from '@kbn/actions-plugin/server/lib/axios_utils'; import { ActionsConfigurationUtilities } from '@kbn/actions-plugin/server/actions_config'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; import { getBodyForEventAction } from './helpers'; import { CreateCommentParams, @@ -44,7 +44,7 @@ export const createExternalService = ( { config, secrets }: ExternalServiceCredentials, logger: Logger, configurationUtilities: ActionsConfigurationUtilities, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): ExternalService => { const { apiUrl: url, appId, mappings } = config as SwimlanePublicConfigurationType; const { apiToken } = secrets as SwimlaneSecretConfigurationType; @@ -94,7 +94,7 @@ export const createExternalService = ( logger, method: 'post', url: getPostRecordUrl(appId), - connectorMetricsService, + connectorMetricsCollector, }); throwIfResponseIsNotValid({ @@ -135,7 +135,7 @@ export const createExternalService = ( logger, method: 'patch', url: getPostRecordIdUrl(appId, params.incidentId), - connectorMetricsService, + connectorMetricsCollector, }); throwIfResponseIsNotValid({ @@ -185,7 +185,7 @@ export const createExternalService = ( logger, method: 'post', url: getPostCommentUrl(appId, incidentId, fieldId), - connectorMetricsService, + connectorMetricsCollector, }); /** diff --git a/x-pack/plugins/stack_connectors/server/connector_types/teams/index.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/teams/index.test.ts index 2600340b92526..ac88dfadf60db 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/teams/index.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/teams/index.test.ts @@ -6,7 +6,7 @@ */ import { Logger } from '@kbn/core/server'; -import { ConnectorMetricsService, Services } from '@kbn/actions-plugin/server/types'; +import { ConnectorMetricsCollector, Services } from '@kbn/actions-plugin/server/types'; import { validateParams, validateSecrets } from '@kbn/actions-plugin/server/lib'; import axios from 'axios'; import { getConnectorType, TeamsConnectorType, ConnectorTypeId } from '.'; @@ -34,12 +34,12 @@ const mockedLogger: jest.Mocked = loggerMock.create(); let connectorType: TeamsConnectorType; let configurationUtilities: jest.Mocked; -let connectorMetricsService: ConnectorMetricsService; +let connectorMetricsCollector: ConnectorMetricsCollector; beforeEach(() => { configurationUtilities = actionsConfigMock.create(); connectorType = getConnectorType(); - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); describe('connector registration', () => { @@ -169,13 +169,13 @@ describe('execute()', () => { params: { message: 'this invocation should succeed' }, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); delete requestMock.mock.calls[0][0].configurationUtilities; expect(requestMock.mock.calls[0][0]).toMatchInlineSnapshot(` Object { "axios": undefined, - "connectorMetricsService": ConnectorMetricsService { + "connectorMetricsCollector": ConnectorMetricsCollector { "metrics": Object { "requestBodyBytes": 0, }, @@ -231,13 +231,13 @@ describe('execute()', () => { params: { message: 'this invocation should succeed' }, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); delete requestMock.mock.calls[0][0].configurationUtilities; expect(requestMock.mock.calls[0][0]).toMatchInlineSnapshot(` Object { "axios": undefined, - "connectorMetricsService": ConnectorMetricsService { + "connectorMetricsCollector": ConnectorMetricsCollector { "metrics": Object { "requestBodyBytes": 0, }, diff --git a/x-pack/plugins/stack_connectors/server/connector_types/teams/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/teams/index.ts index ce578a2f66c86..a4a89501773d1 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/teams/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/teams/index.ts @@ -119,7 +119,7 @@ function validateConnectorTypeConfig( async function teamsExecutor( execOptions: TeamsConnectorTypeExecutorOptions ): Promise> { - const { actionId, secrets, params, configurationUtilities, logger, connectorMetricsService } = + const { actionId, secrets, params, configurationUtilities, logger, connectorMetricsCollector } = execOptions; const { webhookUrl } = secrets; const { message } = params; @@ -135,7 +135,7 @@ async function teamsExecutor( logger, data, configurationUtilities, - connectorMetricsService, + connectorMetricsCollector, }) ); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/tines/tines.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/tines/tines.test.ts index 3ed2d3afa46db..c6c6e02e2c4de 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/tines/tines.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/tines/tines.test.ts @@ -12,7 +12,7 @@ import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { TinesConnector } from './tines'; import { request } from '@kbn/actions-plugin/server/lib/axios_utils'; import { API_MAX_RESULTS, TINES_CONNECTOR_ID } from '../../../common/tines/constants'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; jest.mock('axios'); (axios as jest.Mocked).create.mockImplementation( @@ -79,7 +79,7 @@ const storiesGetRequestExpected = { 'Content-Type': 'application/json', }, params: { per_page: API_MAX_RESULTS }, - connectorMetricsService: expect.any(ConnectorMetricsService), + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }; const agentsGetRequestExpected = { @@ -93,10 +93,10 @@ const agentsGetRequestExpected = { 'Content-Type': 'application/json', }, params: { story_id: story.id, per_page: API_MAX_RESULTS }, - connectorMetricsService: expect.any(ConnectorMetricsService), + connectorMetricsCollector: expect.any(ConnectorMetricsCollector), }; -let connectorMetricsService: ConnectorMetricsService; +let connectorMetricsCollector: ConnectorMetricsCollector; describe('TinesConnector', () => { const connector = new TinesConnector({ @@ -110,7 +110,7 @@ describe('TinesConnector', () => { beforeEach(() => { jest.clearAllMocks(); - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); describe('getStories', () => { @@ -119,13 +119,13 @@ describe('TinesConnector', () => { }); it('should request Tines stories', async () => { - await connector.getStories(undefined, connectorMetricsService); + await connector.getStories(undefined, connectorMetricsCollector); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith(storiesGetRequestExpected); }); it('should return the Tines stories reduced array', async () => { - const { stories } = await connector.getStories(undefined, connectorMetricsService); + const { stories } = await connector.getStories(undefined, connectorMetricsCollector); expect(stories).toEqual([storyResult]); }); @@ -133,7 +133,7 @@ describe('TinesConnector', () => { mockRequest.mockReturnValueOnce({ data: { stories: [story], meta: { pages: 1 } }, }); - const response = await connector.getStories(undefined, connectorMetricsService); + const response = await connector.getStories(undefined, connectorMetricsCollector); expect(response.incompleteResponse).toEqual(false); }); @@ -141,7 +141,7 @@ describe('TinesConnector', () => { mockRequest.mockReturnValueOnce({ data: { stories: [story], meta: { pages: 2 } }, }); - const response = await connector.getStories(undefined, connectorMetricsService); + const response = await connector.getStories(undefined, connectorMetricsCollector); expect(response.incompleteResponse).toEqual(true); }); }); @@ -152,7 +152,7 @@ describe('TinesConnector', () => { }); it('should request Tines webhook actions', async () => { - await connector.getWebhooks({ storyId: story.id }, connectorMetricsService); + await connector.getWebhooks({ storyId: story.id }, connectorMetricsCollector); expect(mockRequest).toBeCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith(agentsGetRequestExpected); @@ -161,7 +161,7 @@ describe('TinesConnector', () => { it('should return the Tines webhooks reduced array', async () => { const { webhooks } = await connector.getWebhooks( { storyId: story.id }, - connectorMetricsService + connectorMetricsCollector ); expect(webhooks).toEqual([webhookResult]); }); @@ -170,7 +170,10 @@ describe('TinesConnector', () => { mockRequest.mockReturnValueOnce({ data: { agents: [webhookAgent], meta: { pages: 1 } }, }); - const response = await connector.getWebhooks({ storyId: story.id }, connectorMetricsService); + const response = await connector.getWebhooks( + { storyId: story.id }, + connectorMetricsCollector + ); expect(response.incompleteResponse).toEqual(false); }); @@ -178,7 +181,10 @@ describe('TinesConnector', () => { mockRequest.mockReturnValueOnce({ data: { agents: [webhookAgent], meta: { pages: 2 } }, }); - const response = await connector.getWebhooks({ storyId: story.id }, connectorMetricsService); + const response = await connector.getWebhooks( + { storyId: story.id }, + connectorMetricsCollector + ); expect(response.incompleteResponse).toEqual(true); }); }); @@ -194,7 +200,7 @@ describe('TinesConnector', () => { webhook: webhookResult, body: '[]', }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); @@ -206,7 +212,7 @@ describe('TinesConnector', () => { headers: { 'Content-Type': 'application/json', }, - connectorMetricsService, + connectorMetricsCollector, }); }); @@ -216,7 +222,7 @@ describe('TinesConnector', () => { webhookUrl, body: '[]', }, - connectorMetricsService + connectorMetricsCollector ); expect(mockRequest).toBeCalledTimes(1); @@ -228,7 +234,7 @@ describe('TinesConnector', () => { headers: { 'Content-Type': 'application/json', }, - connectorMetricsService, + connectorMetricsCollector, }); }); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/tines/tines.ts b/x-pack/plugins/stack_connectors/server/connector_types/tines/tines.ts index 9b9234894f189..0a1f3964731d6 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/tines/tines.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/tines/tines.ts @@ -8,7 +8,7 @@ import { ServiceParams, SubActionConnector } from '@kbn/actions-plugin/server'; import type { AxiosError } from 'axios'; import { SubActionRequestParams } from '@kbn/actions-plugin/server/sub_action_framework/types'; -import { ConnectorMetricsService } from '@kbn/actions-plugin/server/lib'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; import { TinesStoriesActionParamsSchema, TinesWebhooksActionParamsSchema, @@ -110,14 +110,14 @@ export class TinesConnector extends SubActionConnector( req: SubActionRequestParams, reducer: (response: R) => T, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const response = await this.request( { ...req, params: { ...req.params, per_page: API_MAX_RESULTS }, }, - connectorMetricsService + connectorMetricsCollector ); return { ...reducer(response.data), @@ -137,7 +137,7 @@ export class TinesConnector extends SubActionConnector { return this.tinesApiRequest( { @@ -146,13 +146,13 @@ export class TinesConnector extends SubActionConnector { return this.tinesApiRequest( { @@ -162,13 +162,13 @@ export class TinesConnector extends SubActionConnector { if (!webhook && !webhookUrl) { throw Error('Invalid subActionsParams: [webhook] or [webhookUrl] expected but got none'); @@ -180,7 +180,7 @@ export class TinesConnector extends SubActionConnector = loggerMock.create(); let configurationUtilities: jest.Mocked; -let connectorMetricsService: ConnectorMetricsService; +let connectorMetricsCollector: ConnectorMetricsCollector; beforeAll(() => { actionType = getActionType(); configurationUtilities = actionsConfigMock.create(); - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); describe('actionType', () => { @@ -178,14 +178,14 @@ describe('execute Torq action', () => { params: { body: '{"msg": "some data"}' }, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); delete requestMock.mock.calls[0][0].configurationUtilities; expect(requestMock.mock.calls[0][0]).toMatchInlineSnapshot(` Object { "axios": [MockFunction], - "connectorMetricsService": ConnectorMetricsService { + "connectorMetricsCollector": ConnectorMetricsCollector { "metrics": Object { "requestBodyBytes": 0, }, diff --git a/x-pack/plugins/stack_connectors/server/connector_types/torq/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/torq/index.ts index 3667ec5e7f072..af03b10667dea 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/torq/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/torq/index.ts @@ -146,7 +146,7 @@ export async function executor( const { webhookIntegrationUrl } = execOptions.config; const { body: data } = execOptions.params; const configurationUtilities = execOptions.configurationUtilities; - const connectorMetricsService = execOptions.connectorMetricsService; + const connectorMetricsCollector = execOptions.connectorMetricsCollector; const secrets: ActionTypeSecretsType = execOptions.secrets; const token = secrets.token; @@ -172,7 +172,7 @@ export async function executor( configurationUtilities, logger: execOptions.logger, validateStatus: (status: number) => status >= 200 && status < 300, - connectorMetricsService, + connectorMetricsCollector, }) ); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/webhook/index.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/webhook/index.test.ts index a2e7794eaeadb..8bb52b90d309a 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/webhook/index.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/webhook/index.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { ConnectorMetricsService, Services } from '@kbn/actions-plugin/server/types'; +import { ConnectorMetricsCollector, Services } from '@kbn/actions-plugin/server/types'; import { validateConfig, validateParams, validateSecrets } from '@kbn/actions-plugin/server/lib'; import { actionsConfigMock } from '@kbn/actions-plugin/server/actions_config.mock'; import { ActionsConfigurationUtilities } from '@kbn/actions-plugin/server/actions_config'; @@ -41,12 +41,12 @@ const mockedLogger: jest.Mocked = loggerMock.create(); let connectorType: WebhookConnectorType; let configurationUtilities: jest.Mocked; -let connectorMetricsService: ConnectorMetricsService; +let connectorMetricsCollector: ConnectorMetricsCollector; beforeEach(() => { configurationUtilities = actionsConfigMock.create(); connectorType = getConnectorType(); - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); describe('connectorType', () => { @@ -341,14 +341,14 @@ describe('execute()', () => { params: { body: 'some data' }, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); delete requestMock.mock.calls[0][0].configurationUtilities; expect(requestMock.mock.calls[0][0]).toMatchInlineSnapshot(` Object { "axios": undefined, - "connectorMetricsService": ConnectorMetricsService { + "connectorMetricsCollector": ConnectorMetricsCollector { "metrics": Object { "requestBodyBytes": 0, }, @@ -408,7 +408,7 @@ describe('execute()', () => { params: { body: 'some data' }, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); delete requestMock.mock.calls[0][0].configurationUtilities; @@ -416,7 +416,7 @@ describe('execute()', () => { expect(requestMock.mock.calls[0][0]).toMatchInlineSnapshot(` Object { "axios": undefined, - "connectorMetricsService": ConnectorMetricsService { + "connectorMetricsCollector": ConnectorMetricsCollector { "metrics": Object { "requestBodyBytes": 0, }, @@ -602,7 +602,7 @@ describe('execute()', () => { params: { body: 'some data' }, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); expect(mockedLogger.error).toBeCalledWith( 'error on some-id webhook event: maxContentLength size of 1000000 exceeded' @@ -633,14 +633,14 @@ describe('execute()', () => { params: { body: 'some data' }, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); delete requestMock.mock.calls[0][0].configurationUtilities; expect(requestMock.mock.calls[0][0]).toMatchInlineSnapshot(` Object { "axios": undefined, - "connectorMetricsService": ConnectorMetricsService { + "connectorMetricsCollector": ConnectorMetricsCollector { "metrics": Object { "requestBodyBytes": 0, }, diff --git a/x-pack/plugins/stack_connectors/server/connector_types/webhook/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/webhook/index.ts index d97f74e14b99e..a3cb8172b2237 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/webhook/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/webhook/index.ts @@ -128,7 +128,7 @@ function validateConnectorTypeConfig( export async function executor( execOptions: WebhookConnectorTypeExecutorOptions ): Promise> { - const { actionId, config, params, configurationUtilities, logger, connectorMetricsService } = + const { actionId, config, params, configurationUtilities, logger, connectorMetricsCollector } = execOptions; const { method, url, headers = {}, hasAuth, authType, ca, verificationMode } = config; const { body: data } = params; @@ -160,7 +160,7 @@ export async function executor( data, configurationUtilities, sslOverrides, - connectorMetricsService, + connectorMetricsCollector, }) ); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/xmatters/index.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/xmatters/index.test.ts index d74f95ee08cf1..5bb69deba4fa1 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/xmatters/index.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/xmatters/index.test.ts @@ -14,7 +14,7 @@ import { XmattersConnectorType, } from '.'; import { actionsMock } from '@kbn/actions-plugin/server/mocks'; -import { ConnectorMetricsService, Services } from '@kbn/actions-plugin/server/types'; +import { ConnectorMetricsCollector, Services } from '@kbn/actions-plugin/server/types'; import { validateConfig, validateConnector, @@ -45,12 +45,12 @@ const mockedLogger: jest.Mocked = loggerMock.create(); let connectorType: XmattersConnectorType; let configurationUtilities: jest.Mocked; -let connectorMetricsService: ConnectorMetricsService; +let connectorMetricsCollector: ConnectorMetricsCollector; beforeEach(() => { configurationUtilities = actionsConfigMock.create(); connectorType = getConnectorType(); - connectorMetricsService = new ConnectorMetricsService(); + connectorMetricsCollector = new ConnectorMetricsCollector(); }); describe('connectorType', () => { @@ -425,7 +425,7 @@ describe('execute()', () => { }, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); const { method, url, headers, data } = requestMock.mock.calls[0][0]; @@ -475,7 +475,7 @@ describe('execute()', () => { }, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); expect(mockedLogger.warn).toBeCalledWith( 'Error thrown triggering xMatters workflow: maxContentLength size of 1000000 exceeded' @@ -508,7 +508,7 @@ describe('execute()', () => { }, configurationUtilities, logger: mockedLogger, - connectorMetricsService, + connectorMetricsCollector, }); const { method, url, headers, data } = requestMock.mock.calls[0][0]; diff --git a/x-pack/plugins/stack_connectors/server/connector_types/xmatters/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/xmatters/index.ts index 1a1121e8a75a1..034a884573f9e 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/xmatters/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/xmatters/index.ts @@ -247,7 +247,7 @@ function validateConnectorTypeSecrets( export async function executor( execOptions: XmattersConnectorTypeExecutorOptions ): Promise> { - const { actionId, configurationUtilities, config, params, logger, connectorMetricsService } = + const { actionId, configurationUtilities, config, params, logger, connectorMetricsCollector } = execOptions; const { configUrl, usesBasic } = config; const data = getPayloadForRequest(params); @@ -268,7 +268,7 @@ export async function executor( { url, data, basicAuth }, logger, configurationUtilities, - connectorMetricsService + connectorMetricsCollector ); } catch (err) { const message = i18n.translate('xpack.stackConnectors.xmatters.postingErrorMessage', { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/xmatters/post_xmatters.ts b/x-pack/plugins/stack_connectors/server/connector_types/xmatters/post_xmatters.ts index 4051f75c8a4d0..d0dbba93e2fde 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/xmatters/post_xmatters.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/xmatters/post_xmatters.ts @@ -11,7 +11,7 @@ import { ActionsConfigurationUtilities } from '@kbn/actions-plugin/server/action import { request } from '@kbn/actions-plugin/server/lib/axios_utils'; import { combineHeadersWithBasicAuthHeader, - ConnectorMetricsService, + ConnectorMetricsCollector, } from '@kbn/actions-plugin/server/lib'; interface PostXmattersOptions { @@ -38,7 +38,7 @@ export async function postXmatters( options: PostXmattersOptions, logger: Logger, configurationUtilities: ActionsConfigurationUtilities, - connectorMetricsService: ConnectorMetricsService + connectorMetricsCollector: ConnectorMetricsCollector ): Promise { const { url, data, basicAuth } = options; const axiosInstance = axios.create(); @@ -54,6 +54,6 @@ export async function postXmatters( data, configurationUtilities, validateStatus: () => true, - connectorMetricsService, + connectorMetricsCollector, }); } diff --git a/x-pack/test/alerting_api_integration/common/plugins/alerts/server/sub_action_connector.ts b/x-pack/test/alerting_api_integration/common/plugins/alerts/server/sub_action_connector.ts index 7bd9db83dcc00..1dd361ebb814b 100644 --- a/x-pack/test/alerting_api_integration/common/plugins/alerts/server/sub_action_connector.ts +++ b/x-pack/test/alerting_api_integration/common/plugins/alerts/server/sub_action_connector.ts @@ -11,6 +11,7 @@ import type { ServiceParams } from '@kbn/actions-plugin/server'; import { PluginSetupContract as ActionsPluginSetup } from '@kbn/actions-plugin/server/plugin'; import { schema, TypeOf } from '@kbn/config-schema'; import { SubActionConnectorType } from '@kbn/actions-plugin/server/sub_action_framework/types'; +import { ConnectorMetricsCollector } from '@kbn/actions-plugin/server/lib'; const TestConfigSchema = schema.object({ url: schema.string() }); const TestSecretsSchema = schema.object({ @@ -69,7 +70,11 @@ export const getTestSubActionConnector = ( return `Message: ${error.response?.data.errorMessage}. Code: ${error.response?.data.errorCode}`; } - public async subActionWithParams({ id }: { id: string }) { + public async subActionWithParams( + { id }: { id: string }, + connectorMetricsCollector: ConnectorMetricsCollector + ) { + connectorMetricsCollector.addRequestBodyBytes(undefined, { id }); return { id }; } diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts index 93c8cd40fb37f..1b7bce71aaefc 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts @@ -20,8 +20,9 @@ import { ELASTIC_HTTP_VERSION_HEADER, X_ELASTIC_INTERNAL_ORIGIN_REQUEST, } from '@kbn/core-http-common'; +import { IValidatedEvent } from '@kbn/event-log-plugin/generated/schemas'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; -import { getUrlPrefix, ObjectRemover } from '../../../../../common/lib'; +import { getEventLog, getUrlPrefix, ObjectRemover } from '../../../../../common/lib'; const connectorTypeId = '.bedrock'; const name = 'A bedrock action'; @@ -456,9 +457,29 @@ export default function bedrockTest({ getService }: FtrProviderContext) { responseBuffer.push(chunk); }); - passThrough.on('end', () => { + passThrough.on('end', async () => { const parsed = parseBedrockBuffer(responseBuffer); expect(parsed).to.eql('Hello world, what a unique string!'); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: bedrockActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be( + 110 + ); + resolve(); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts index f26ba86f6fa3a..71198328160b5 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts @@ -14,13 +14,16 @@ import { ExternalServiceSimulator, } from '@kbn/actions-simulators-plugin/server/plugin'; import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; +import { IValidatedEvent } from '@kbn/event-log-plugin/generated/schemas'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; // eslint-disable-next-line import/no-default-export export default function casesWebhookTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const kibanaServer = getService('kibanaServer'); const configService = getService('config'); + const retry = getService('retry'); const config = { createCommentJson: '{"body":{{{case.comment}}}}', createCommentMethod: 'post', @@ -398,6 +401,23 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { const { pushedDate, ...dataWithoutTime } = body.data; body.data = dataWithoutTime; + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(125); + expect(body).to.eql({ status: 'ok', connector_id: simulatedActionId, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/d3security.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/d3security.ts index 7e1f0636b3a96..0c47f176efc42 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/d3security.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/d3security.ts @@ -12,7 +12,9 @@ import { d3SecuritySuccessResponse, } from '@kbn/actions-simulators-plugin/server/d3security_simulation'; import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; +import { IValidatedEvent } from '@kbn/event-log-plugin/generated/schemas'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; const connectorTypeId = '.d3security'; const name = 'A D3 Security action'; @@ -24,6 +26,7 @@ const secrets = { export default function d3SecurityTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const configService = getService('config'); + const retry = getService('retry'); const createConnector = async (url: string) => { const { body } = await supertest @@ -248,6 +251,24 @@ export default function d3SecurityTest({ getService }: FtrProviderContext) { }, }, }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: d3SecurityActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(99); + expect(body).to.eql({ status: 'ok', connector_id: d3SecurityActionId, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/email.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/email.ts index cfffe90126fac..21d0f8f5ee0f3 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/email.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/email.ts @@ -11,12 +11,15 @@ import { ExternalServiceSimulator, getExternalServiceSimulatorPath, } from '@kbn/actions-simulators-plugin/server/plugin'; +import { IValidatedEvent } from '@kbn/event-log-plugin/generated/schemas'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; // eslint-disable-next-line import/no-default-export export default function emailTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const kibanaServer = getService('kibanaServer'); + const retry = getService('retry'); describe('create email action', () => { let createdActionId = ''; @@ -103,7 +106,7 @@ export default function emailTest({ getService }: FtrProviderContext) { }, }) .expect(200) - .then((resp: any) => { + .then(async (resp: any) => { expect(resp.body.data.message.messageId).to.be.a('string'); expect(resp.body.data.messageId).to.be.a('string'); @@ -131,6 +134,23 @@ export default function emailTest({ getService }: FtrProviderContext) { headers: {}, }, }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: createdActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(350); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/es_index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/es_index.ts index 46287db208b87..0ffe702a50143 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/es_index.ts @@ -7,7 +7,9 @@ import type { Client } from '@elastic/elasticsearch'; import expect from '@kbn/expect'; +import { IValidatedEvent } from '@kbn/event-log-plugin/generated/schemas'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; const ES_TEST_INDEX_NAME = 'functional-test-actions-index'; @@ -16,6 +18,7 @@ export default function indexTest({ getService }: FtrProviderContext) { const es: Client = getService('es'); const supertest = getService('supertest'); const esDeleteAllIndices = getService('esDeleteAllIndices'); + const retry = getService('retry'); describe('index action', () => { beforeEach(() => esDeleteAllIndices(ES_TEST_INDEX_NAME)); @@ -214,6 +217,23 @@ export default function indexTest({ getService }: FtrProviderContext) { } expect(passed1).to.be(true); expect(passed2).to.be(true); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: createdAction.id, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(0); }); it('should execute successly with refresh false', async () => { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/jira.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/jira.ts index 054678996888f..f355e6793fecf 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/jira.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/jira.ts @@ -7,6 +7,7 @@ import httpProxy from 'http-proxy'; import expect from '@kbn/expect'; +import { IValidatedEvent } from '@kbn/event-log-plugin/generated/schemas'; import { getHttpProxyServer } from '@kbn/alerting-api-integration-helpers'; import { @@ -16,12 +17,14 @@ import { import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { MAX_OTHER_FIELDS_LENGTH } from '@kbn/stack-connectors-plugin/common/jira/constants'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; // eslint-disable-next-line import/no-default-export export default function jiraTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const kibanaServer = getService('kibanaServer'); const configService = getService('config'); + const retry = getService('retry'); const mockJira = { config: { @@ -517,6 +520,23 @@ export default function jiraTest({ getService }: FtrProviderContext) { url: `${jiraSimulatorURL}/browse/CK-1`, }, }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { gte: 2 }], + ['execute', { gte: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(124); }); it('should handle creating an incident with other fields', async () => { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/openai.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/openai.ts index a971f18b7130d..15a8296244906 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/openai.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/openai.ts @@ -6,6 +6,7 @@ */ import expect from '@kbn/expect'; +import { IValidatedEvent } from '@kbn/event-log-plugin/server'; import { OpenAISimulator, @@ -14,6 +15,7 @@ import { import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { getUrlPrefix, ObjectRemover } from '../../../../../common/lib'; +import { getEventLog } from '../../../../../common/lib'; const connectorTypeId = '.gen-ai'; const name = 'A genAi action'; @@ -274,7 +276,7 @@ export default function genAiTest({ getService }: FtrProviderContext) { }); describe('execution', () => { - describe('successful response simulator', () => { + describe('successful response simulator x', () => { const simulator = new OpenAISimulator({ proxy: { config: configService.get('kbnTestServer.serverArgs'), @@ -315,6 +317,23 @@ export default function genAiTest({ getService }: FtrProviderContext) { connector_id: genAiActionId, data: genAiSuccessResponse, }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: genAiActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(78); }); describe('Token tracking dashboard', () => { const dashboardId = 'specific-dashboard-id-default'; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/opsgenie.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/opsgenie.ts index 48386480b00da..4625364e9bb7a 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/opsgenie.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/opsgenie.ts @@ -6,6 +6,7 @@ */ import expect from '@kbn/expect'; +import { IValidatedEvent } from '@kbn/event-log-plugin/server'; import { OpsgenieSimulator, @@ -13,11 +14,13 @@ import { } from '@kbn/actions-simulators-plugin/server/opsgenie_simulation'; import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; // eslint-disable-next-line import/no-default-export export default function opsgenieTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const configService = getService('config'); + const retry = getService('retry'); describe('Opsgenie', () => { describe('action creation', () => { @@ -535,6 +538,23 @@ export default function opsgenieTest({ getService }: FtrProviderContext) { connector_id: opsgenieActionId, data: opsgenieSuccessResponse, }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: opsgenieActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(21); }); it('should preserve the alias when it is 512 characters when creating an alert', async () => { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/pagerduty.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/pagerduty.ts index 7148ac962c728..940ef8f89467f 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/pagerduty.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/pagerduty.ts @@ -7,6 +7,7 @@ import httpProxy from 'http-proxy'; import expect from '@kbn/expect'; +import { IValidatedEvent } from '@kbn/event-log-plugin/server'; import { getHttpProxyServer } from '@kbn/alerting-api-integration-helpers'; import { @@ -14,12 +15,14 @@ import { ExternalServiceSimulator, } from '@kbn/actions-simulators-plugin/server/plugin'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; // eslint-disable-next-line import/no-default-export export default function pagerdutyTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const kibanaServer = getService('kibanaServer'); const configService = getService('config'); + const retry = getService('retry'); describe('pagerduty action', () => { let simulatedActionId = ''; @@ -173,6 +176,23 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { status: 'success', }, }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(142); }); it('should execute successfully with links and customDetails', async () => { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/resilient.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/resilient.ts index c9b4e7ecafa3f..fd69794863164 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/resilient.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/resilient.ts @@ -6,15 +6,18 @@ */ import expect from '@kbn/expect'; +import { IValidatedEvent } from '@kbn/event-log-plugin/server'; import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { ResilientSimulator } from '@kbn/actions-simulators-plugin/server/resilient_simulation'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; // eslint-disable-next-line import/no-default-export export default function resilientTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const configService = getService('config'); + const retry = getService('retry'); const mockResilient = { config: { @@ -409,6 +412,23 @@ export default function resilientTest({ getService }: FtrProviderContext) { url: `${simulatorUrl}/#incidents/123`, }, }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: resilientActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(167); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/server_log.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/server_log.ts index a5f14e512ddb1..0fd72a2b8ec7a 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/server_log.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/server_log.ts @@ -6,12 +6,15 @@ */ import expect from '@kbn/expect'; +import { IValidatedEvent } from '@kbn/event-log-plugin/server'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; // eslint-disable-next-line import/no-default-export export default function serverLogTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); + const retry = getService('retry'); describe('server-log action', () => { let serverLogActionId: string; @@ -69,6 +72,23 @@ export default function serverLogTest({ getService }: FtrProviderContext) { .expect(200); expect(result.status).to.eql('ok'); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: serverLogActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(0); }); }); } diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itom.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itom.ts index 4702d3bbe6df7..c150003339f0d 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itom.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itom.ts @@ -10,16 +10,19 @@ import expect from '@kbn/expect'; import { asyncForEach } from '@kbn/std'; import getPort from 'get-port'; import http from 'http'; +import { IValidatedEvent } from '@kbn/event-log-plugin/server'; import { getHttpProxyServer } from '@kbn/alerting-api-integration-helpers'; import { getServiceNowServer } from '@kbn/actions-simulators-plugin/server/plugin'; import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; // eslint-disable-next-line import/no-default-export export default function serviceNowITOMTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const configService = getService('config'); + const retry = getService('retry'); const mockServiceNowCommon = { params: { @@ -500,6 +503,23 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { }) .expect(200); expect(result.status).to.eql('ok'); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(317); }); }); @@ -548,6 +568,23 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { }, ], }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 2 }], + ['execute', { equal: 2 }], + ]), + }); + }); + + const executeEvent = events[3]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(0); }); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itsm.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itsm.ts index ec62e6d30f6ff..ee470a85101ab 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itsm.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itsm.ts @@ -10,17 +10,20 @@ import expect from '@kbn/expect'; import { asyncForEach } from '@kbn/std'; import getPort from 'get-port'; import http from 'http'; +import { IValidatedEvent } from '@kbn/event-log-plugin/server'; import { getHttpProxyServer } from '@kbn/alerting-api-integration-helpers'; import { getServiceNowServer } from '@kbn/actions-simulators-plugin/server/plugin'; import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { MAX_ADDITIONAL_FIELDS_LENGTH } from '@kbn/stack-connectors-plugin/common/servicenow/constants'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; // eslint-disable-next-line import/no-default-export export default function serviceNowITSMTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const configService = getService('config'); + const retry = getService('retry'); const mockServiceNowCommon = { params: { @@ -708,6 +711,23 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { url: `${serviceNowSimulatorURL}/nav_to.do?uri=incident.do?sys_id=123`, }, }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(261); }); }); @@ -755,6 +775,23 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { url: `${serviceNowSimulatorURL}/nav_to.do?uri=incident.do?sys_id=123`, }, }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(239); }); }); @@ -803,6 +840,23 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { }, ], }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { gte: 2 }], + ['execute', { gte: 2 }], + ]), + }); + }); + + const executeEvent = events[3]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(0); }); }); @@ -829,6 +883,22 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, data: {}, }); + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { gte: 3 }], + ['execute', { gte: 3 }], + ]), + }); + }); + + const executeEvent = events[5]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(0); }); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_sir.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_sir.ts index fd4781f6d9e62..f5246766b744c 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_sir.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_sir.ts @@ -10,17 +10,20 @@ import expect from '@kbn/expect'; import { asyncForEach } from '@kbn/std'; import getPort from 'get-port'; import http from 'http'; +import { IValidatedEvent } from '@kbn/event-log-plugin/server'; import { getHttpProxyServer } from '@kbn/alerting-api-integration-helpers'; import { getServiceNowServer } from '@kbn/actions-simulators-plugin/server/plugin'; import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { MAX_ADDITIONAL_FIELDS_LENGTH } from '@kbn/stack-connectors-plugin/common/servicenow/constants'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; // eslint-disable-next-line import/no-default-export export default function serviceNowSIRTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const configService = getService('config'); + const retry = getService('retry'); const mockServiceNowCommon = { config: { @@ -721,6 +724,23 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { url: `${serviceNowSimulatorURL}/nav_to.do?uri=sn_si_incident.do?sys_id=123`, }, }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(645); }); }); @@ -768,6 +788,22 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { url: `${serviceNowSimulatorURL}/nav_to.do?uri=sn_si_incident.do?sys_id=123`, }, }); + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(429); }); }); @@ -816,6 +852,23 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { }, ], }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { gte: 2 }], + ['execute', { gte: 2 }], + ]), + }); + }); + + const executeEvent = events[3]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(0); }); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/slack_webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/slack_webhook.ts index 4941bec1844ca..ff574fd0aea31 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/slack_webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/slack_webhook.ts @@ -9,14 +9,18 @@ import httpProxy from 'http-proxy'; import expect from '@kbn/expect'; import http from 'http'; import getPort from 'get-port'; +import { IValidatedEvent } from '@kbn/event-log-plugin/server'; + import { getHttpProxyServer } from '@kbn/alerting-api-integration-helpers'; import { getSlackServer } from '@kbn/actions-simulators-plugin/server/plugin'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; // eslint-disable-next-line import/no-default-export export default function slackTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const configService = getService('config'); + const retry = getService('retry'); describe('Slack webhook action', () => { let simulatedActionId = ''; @@ -175,6 +179,23 @@ export default function slackTest({ getService }: FtrProviderContext) { .expect(200); expect(result.status).to.eql('ok'); expect(proxyHaveBeenCalled).to.equal(true); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(18); }); it('should handle an empty message error', async () => { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/swimlane.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/swimlane.ts index 859f4f952fe58..75cfc23bca764 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/swimlane.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/swimlane.ts @@ -9,16 +9,19 @@ import httpProxy from 'http-proxy'; import expect from '@kbn/expect'; import getPort from 'get-port'; import http from 'http'; +import { IValidatedEvent } from '@kbn/event-log-plugin/server'; import { getHttpProxyServer } from '@kbn/alerting-api-integration-helpers'; import { getSwimlaneServer } from '@kbn/actions-simulators-plugin/server/plugin'; import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; // eslint-disable-next-line import/no-default-export export default function swimlaneTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const configService = getService('config'); + const retry = getService('retry'); const mockSwimlane = { name: 'A swimlane action', @@ -459,6 +462,23 @@ export default function swimlaneTest({ getService }: FtrProviderContext) { url: `${swimlaneSimulatorURL}/record/123456asdf/wowzeronza`, }, }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(175); }); it('should handle updating an incident', async () => { @@ -490,6 +510,23 @@ export default function swimlaneTest({ getService }: FtrProviderContext) { url: `${swimlaneSimulatorURL}/record/123456asdf/wowzeronza`, }, }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { gte: 1 }], + ['execute', { gte: 2 }], + ]), + }); + }); + + const executeEvent = events[3]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(193); }); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/tines.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/tines.ts index 53dd3aaaf026a..7eeb2712cc81d 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/tines.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/tines.ts @@ -6,6 +6,7 @@ */ import expect from '@kbn/expect'; +import { IValidatedEvent } from '@kbn/event-log-plugin/server'; import { TinesSimulator, @@ -16,6 +17,7 @@ import { } from '@kbn/actions-simulators-plugin/server/tines_simulation'; import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; const connectorTypeId = '.tines'; const name = 'A tines action'; @@ -35,6 +37,7 @@ const webhook = { export default function tinesTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const configService = getService('config'); + const retry = getService('retry'); const createConnector = async (url: string) => { const { body } = await supertest @@ -392,6 +395,23 @@ export default function tinesTest({ getService }: FtrProviderContext) { incompleteResponse: false, }, }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: tinesActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(2); }); it('should get webhooks', async () => { @@ -422,6 +442,22 @@ export default function tinesTest({ getService }: FtrProviderContext) { incompleteResponse: false, }, }); + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: tinesActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { gte: 2 }], + ['execute', { gte: 2 }], + ]), + }); + }); + + const executeEvent = events[3]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(2); }); it('should run the webhook', async () => { @@ -440,6 +476,22 @@ export default function tinesTest({ getService }: FtrProviderContext) { connector_id: tinesActionId, data: tinesWebhookSuccessResponse, }); + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: tinesActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { gte: 3 }], + ['execute', { gte: 3 }], + ]), + }); + }); + + const executeEvent = events[5]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(8); }); it('should run the webhook url', async () => { @@ -464,6 +516,22 @@ export default function tinesTest({ getService }: FtrProviderContext) { connector_id: tinesActionId, data: tinesWebhookSuccessResponse, }); + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: tinesActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { gte: 3 }], + ['execute', { gte: 3 }], + ]), + }); + }); + + const executeEvent = events[5]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(8); }); }); @@ -506,6 +574,22 @@ export default function tinesTest({ getService }: FtrProviderContext) { errorSource: TaskErrorSource.FRAMEWORK, service_message: 'Status code: 422. Message: API Error: Unprocessable Entity', }); + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: tinesActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { gte: 1 }], + ['execute', { gte: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(2); }); it('should return a failure when attempting to get webhooks', async () => { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/torq.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/torq.ts index 257378b406da5..e5857443a0afd 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/torq.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/torq.ts @@ -7,6 +7,7 @@ import httpProxy from 'http-proxy'; import expect from '@kbn/expect'; +import { IValidatedEvent } from '@kbn/event-log-plugin/server'; import { getHttpProxyServer } from '@kbn/alerting-api-integration-helpers/get_proxy_server'; import { @@ -14,12 +15,14 @@ import { ExternalServiceSimulator, } from '@kbn/actions-simulators-plugin/server/plugin'; import { FtrProviderContext } from '../../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; // eslint-disable-next-line import/no-default-export export default function torqTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const kibanaServer = getService('kibanaServer'); const configService = getService('config'); + const retry = getService('retry'); describe('Torq action', () => { let simulatedActionId = ''; @@ -159,6 +162,22 @@ export default function torqTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, data: `{"msg": "test"}`, }); + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { gte: 1 }], + ['execute', { gte: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(14); }); it('should handle a 400 Torq error', async () => { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/webhook.ts index c7a8f1c1b2524..5e0298ac3b944 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/webhook.ts @@ -8,6 +8,8 @@ import httpProxy from 'http-proxy'; import http from 'http'; import expect from '@kbn/expect'; +import { IValidatedEvent } from '@kbn/event-log-plugin/server'; + import { URL, format as formatUrl } from 'url'; import getPort from 'get-port'; import { getHttpProxyServer } from '@kbn/alerting-api-integration-helpers'; @@ -17,6 +19,7 @@ import { getWebhookServer, } from '@kbn/actions-simulators-plugin/server/plugin'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; const defaultValues: Record = { headers: null, @@ -36,6 +39,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const kibanaServer = getService('kibanaServer'); const configService = getService('config'); + const retry = getService('retry'); async function createWebhookAction( webhookSimulatorURL: string, @@ -258,6 +262,23 @@ export default function webhookTest({ getService }: FtrProviderContext) { .expect(200); expect(result.status).to.eql('ok'); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: webhookActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { gte: 1 }], + ['execute', { gte: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(19); }); it('should support the PUT method against webhook target', async () => { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/xmatters.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/xmatters.ts index 4efacbf78f951..00dd7137fdf8f 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/xmatters.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/xmatters.ts @@ -7,6 +7,7 @@ import httpProxy from 'http-proxy'; import expect from '@kbn/expect'; +import { IValidatedEvent } from '@kbn/event-log-plugin/server'; import { getHttpProxyServer } from '@kbn/alerting-api-integration-helpers'; import { @@ -14,12 +15,14 @@ import { ExternalServiceSimulator, } from '@kbn/actions-simulators-plugin/server/plugin'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { getEventLog } from '../../../../../common/lib'; // eslint-disable-next-line import/no-default-export export default function xmattersTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const kibanaServer = getService('kibanaServer'); const configService = getService('config'); + const retry = getService('retry'); describe('xmatters action', () => { let simulatedActionId = ''; @@ -180,6 +183,23 @@ export default function xmattersTest({ getService }: FtrProviderContext) { spaceId: '', }, }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: simulatedActionId, + provider: 'actions', + actions: new Map([ + ['execute-start', { gte: 1 }], + ['execute', { gte: 1 }], + ]), + }); + }); + + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.be(130); }); it('should handle a 40x xmatters error', async () => { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/execute.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/execute.ts index acfb06e64cff6..6ce3261fe7790 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/execute.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/execute.ts @@ -652,6 +652,8 @@ export default function ({ getService }: FtrProviderContext) { expect(executeEvent?.message).to.eql(message); expect(startExecuteEvent?.message).to.eql(message.replace('executed', 'started')); + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.eql(0); + if (source) { expect(executeEvent?.kibana?.action?.execution?.source).to.eql(source.toLowerCase()); } diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/sub_action_framework/index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/sub_action_framework/index.ts index c8fb3e4b6ce2d..8582509722719 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/sub_action_framework/index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/sub_action_framework/index.ts @@ -8,8 +8,9 @@ import type SuperTest from 'supertest'; import expect from '@kbn/expect'; import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; +import { IValidatedEvent } from '@kbn/event-log-plugin/generated/schemas'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; -import { getUrlPrefix, ObjectRemover } from '../../../../../common/lib'; +import { getEventLog, getUrlPrefix, ObjectRemover } from '../../../../../common/lib'; /** * The sub action connector is defined here @@ -79,6 +80,7 @@ const executeSubAction = async ({ // eslint-disable-next-line import/no-default-export export default function createActionTests({ getService }: FtrProviderContext) { const supertest = getService('supertest'); + const retry = getService('retry'); describe('Sub action framework', () => { const objectRemover = new ObjectRemover(supertest); @@ -140,13 +142,35 @@ export default function createActionTests({ getService }: FtrProviderContext) { const res = await createSubActionConnector({ supertest }); objectRemover.add('default', res.body.id, 'action', 'actions'); + const connectorId = res.body.id as string; + const subActionParams = { id: 'test-id' }; + const execRes = await executeSubAction({ supertest, - connectorId: res.body.id as string, + connectorId, subAction: 'subActionWithParams', - subActionParams: { id: 'test-id' }, + subActionParams, + }); + + const events: IValidatedEvent[] = await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: 'default', + type: 'action', + id: connectorId, + provider: 'actions', + actions: new Map([ + ['execute-start', { equal: 1 }], + ['execute', { equal: 1 }], + ]), + }); }); + const executeEvent = events[1]; + expect(executeEvent?.kibana?.action?.execution?.metrics?.request_body_bytes).to.eql( + Buffer.byteLength(JSON.stringify(subActionParams)) + ); + expect(execRes.body).to.eql({ status: 'ok', data: { id: 'test-id' },