diff --git a/x-pack/plugins/data_usage/common/rest_types/usage_metrics.ts b/x-pack/plugins/data_usage/common/rest_types/usage_metrics.ts index 09a6481f24455..ccc8158ecace7 100644 --- a/x-pack/plugins/data_usage/common/rest_types/usage_metrics.ts +++ b/x-pack/plugins/data_usage/common/rest_types/usage_metrics.ts @@ -82,56 +82,45 @@ export type UsageMetricsRequestBody = TypeOf; export const UsageMetricsResponseSchema = { body: () => - schema.object({ - metrics: schema.recordOf( - metricTypesSchema, - schema.arrayOf( - schema.object({ - name: schema.string(), - error: schema.nullable(schema.string()), - data: schema.arrayOf( - schema.object({ - x: schema.number(), - y: schema.number(), - }) - ), - }) - ) - ), - }), + schema.recordOf( + metricTypesSchema, + schema.arrayOf( + schema.object({ + name: schema.string(), + error: schema.nullable(schema.string()), + data: schema.arrayOf( + schema.object({ + x: schema.number(), + y: schema.number(), + }) + ), + }) + ) + ), }; -export type UsageMetricsResponseSchemaBody = Omit< - TypeOf, - 'metrics' -> & { - metrics: Partial>; -}; -export type MetricSeries = TypeOf< - typeof UsageMetricsResponseSchema.body ->['metrics'][MetricTypes][number]; + +export type UsageMetricsResponseSchemaBody = Partial>; + +export type MetricSeries = TypeOf[MetricTypes][number]; export const UsageMetricsAutoOpsResponseSchema = { body: () => - schema.object({ - metrics: schema.recordOf( - metricTypesSchema, - schema.arrayOf( - schema.object({ - name: schema.string(), - error: schema.nullable(schema.string()), - data: schema.arrayOf(schema.arrayOf(schema.number(), { minSize: 2, maxSize: 2 })), - }) - ) - ), - }), + schema.recordOf( + metricTypesSchema, + schema.arrayOf( + schema.object({ + name: schema.string(), + error: schema.nullable(schema.string()), + data: schema.arrayOf(schema.arrayOf(schema.number(), { minSize: 2, maxSize: 2 })), + }) + ) + ), }; + export type UsageMetricsAutoOpsResponseMetricSeries = TypeOf< typeof UsageMetricsAutoOpsResponseSchema.body ->['metrics'][MetricTypes][number]; +>[MetricTypes][number]; -export type UsageMetricsAutoOpsResponseSchemaBody = Omit< - TypeOf, - 'metrics' -> & { - metrics: Partial>; -}; +export type UsageMetricsAutoOpsResponseSchemaBody = Partial< + Record +>; diff --git a/x-pack/plugins/data_usage/public/app/components/charts.tsx b/x-pack/plugins/data_usage/public/app/components/charts.tsx index 56857e7a63ff9..4a2b9b4fbc875 100644 --- a/x-pack/plugins/data_usage/public/app/components/charts.tsx +++ b/x-pack/plugins/data_usage/public/app/components/charts.tsx @@ -24,7 +24,7 @@ export const Charts: React.FC = ({ data, 'data-test-subj': dataTest return ( - {Object.entries(data.metrics).map(([metricType, series], idx) => ( + {Object.entries(data).map(([metricType, series], idx) => ( { ...getBaseMockedDataUsageMetrics, isFetched: true, data: { - metrics: { - ingest_rate: [ - { - name: '.ds-1', - data: [{ x: new Date(), y: 1000 }], - }, - { - name: '.ds-10', - data: [{ x: new Date(), y: 1100 }], - }, - ], - storage_retained: [ - { - name: '.ds-2', - data: [{ x: new Date(), y: 2000 }], - }, - { - name: '.ds-20', - data: [{ x: new Date(), y: 2100 }], - }, - ], - }, + ingest_rate: [ + { + name: '.ds-1', + data: [{ x: new Date(), y: 1000 }], + }, + { + name: '.ds-10', + data: [{ x: new Date(), y: 1100 }], + }, + ], + storage_retained: [ + { + name: '.ds-2', + data: [{ x: new Date(), y: 2000 }], + }, + { + name: '.ds-20', + data: [{ x: new Date(), y: 2100 }], + }, + ], }, }); const { getByTestId } = render(); diff --git a/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.tsx b/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.tsx index 8bedde117785a..5460c7ada0389 100644 --- a/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.tsx +++ b/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.tsx @@ -206,7 +206,7 @@ export const DataUsageMetrics = memo( - {isFetched && data?.metrics ? ( + {isFetched && data ? ( ) : isFetching ? ( diff --git a/x-pack/plugins/data_usage/server/routes/internal/usage_metrics_handler.ts b/x-pack/plugins/data_usage/server/routes/internal/usage_metrics_handler.ts index 07625ad4c0898..6907a683696a7 100644 --- a/x-pack/plugins/data_usage/server/routes/internal/usage_metrics_handler.ts +++ b/x-pack/plugins/data_usage/server/routes/internal/usage_metrics_handler.ts @@ -83,18 +83,16 @@ export const getUsageMetricsHandler = ( export function transformMetricsData( data: UsageMetricsAutoOpsResponseSchemaBody ): UsageMetricsResponseSchemaBody { - return { - metrics: Object.fromEntries( - Object.entries(data.metrics).map(([metricType, series]) => [ - metricType, - series.map((metricSeries) => ({ - name: metricSeries.name, - data: (metricSeries.data as Array<[number, number]>).map(([timestamp, value]) => ({ - x: timestamp, - y: value, - })), + return Object.fromEntries( + Object.entries(data).map(([metricType, series]) => [ + metricType, + series.map((metricSeries) => ({ + name: metricSeries.name, + data: (metricSeries.data as Array<[number, number]>).map(([timestamp, value]) => ({ + x: timestamp, + y: value, })), - ]) - ), - }; + })), + ]) + ) as UsageMetricsResponseSchemaBody; } diff --git a/x-pack/plugins/data_usage/server/services/autoops_api.ts b/x-pack/plugins/data_usage/server/services/autoops_api.ts index 582cd7ab33046..9fd742a3e73fa 100644 --- a/x-pack/plugins/data_usage/server/services/autoops_api.ts +++ b/x-pack/plugins/data_usage/server/services/autoops_api.ts @@ -164,11 +164,7 @@ export class AutoOpsAPIService { } ); - const validatedResponse = response.data.metrics - ? UsageMetricsAutoOpsResponseSchema.body().validate(response.data) - : UsageMetricsAutoOpsResponseSchema.body().validate({ - metrics: response.data, - }); + const validatedResponse = UsageMetricsAutoOpsResponseSchema.body().validate(response.data); this.logger.debug(`[AutoOps API] Successfully created an autoops agent ${response}`); return validatedResponse; diff --git a/x-pack/test_serverless/api_integration/test_suites/common/data_usage/mock_data.ts b/x-pack/test_serverless/api_integration/test_suites/common/data_usage/mock_data.ts index 7ee5513e1352d..7bd4b7f3e7a22 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/data_usage/mock_data.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/data_usage/mock_data.ts @@ -6,42 +6,40 @@ */ export const mockAutoOpsResponse = { - metrics: { - ingest_rate: [ - { - name: 'metrics-system.cpu-default', - error: null, - data: [ - [1726858530000, 13756849], - [1726862130000, 14657904], - ], - }, - { - name: 'logs-nginx.access-default', - error: null, - data: [ - [1726858530000, 12894623], - [1726862130000, 14436905], - ], - }, - ], - storage_retained: [ - { - name: 'metrics-system.cpu-default', - error: null, - data: [ - [1726858530000, 12576413], - [1726862130000, 13956423], - ], - }, - { - name: 'logs-nginx.access-default', - error: null, - data: [ - [1726858530000, 12894623], - [1726862130000, 14436905], - ], - }, - ], - }, + ingest_rate: [ + { + name: 'metrics-system.cpu-default', + error: null, + data: [ + [1726858530000, 13756849], + [1726862130000, 14657904], + ], + }, + { + name: 'logs-nginx.access-default', + error: null, + data: [ + [1726858530000, 12894623], + [1726862130000, 14436905], + ], + }, + ], + storage_retained: [ + { + name: 'metrics-system.cpu-default', + error: null, + data: [ + [1726858530000, 12576413], + [1726862130000, 13956423], + ], + }, + { + name: 'logs-nginx.access-default', + error: null, + data: [ + [1726858530000, 12894623], + [1726862130000, 14436905], + ], + }, + ], }; diff --git a/x-pack/test_serverless/api_integration/test_suites/common/data_usage/tests/data_streams.ts b/x-pack/test_serverless/api_integration/test_suites/common/data_usage/tests/data_streams.ts index d805b8ccff6fe..b6559c3efc9b6 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/data_usage/tests/data_streams.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/data_usage/tests/data_streams.ts @@ -6,9 +6,9 @@ */ import expect from '@kbn/expect'; -import { SupertestWithRoleScope } from '@kbn/test-suites-xpack/api_integration/deployment_agnostic/services/role_scoped_supertest'; import { DataStreamsResponseBodySchemaBody } from '@kbn/data-usage-plugin/common/rest_types'; import { DATA_USAGE_DATA_STREAMS_API_ROUTE } from '@kbn/data-usage-plugin/common'; +import { SupertestWithRoleScope } from '@kbn/test-suites-xpack/api_integration/deployment_agnostic/services/role_scoped_supertest'; import { FtrProviderContext } from '../../../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { @@ -43,14 +43,5 @@ export default function ({ getService }: FtrProviderContext) { expect(foundStream?.storageSizeBytes).to.be(0); expect(res.statusCode).to.be(200); }); - it('returns system indices', async () => { - const res = await supertestAdminWithCookieCredentials - .get(DATA_USAGE_DATA_STREAMS_API_ROUTE) - .set('elastic-api-version', '1'); - const dataStreams: DataStreamsResponseBodySchemaBody = res.body; - const systemDataStreams = dataStreams.filter((stream) => stream.name.startsWith('.')); - expect(systemDataStreams.length).to.be.greaterThan(0); - expect(res.statusCode).to.be(200); - }); }); } diff --git a/x-pack/test_serverless/api_integration/test_suites/common/data_usage/tests/metrics.ts b/x-pack/test_serverless/api_integration/test_suites/common/data_usage/tests/metrics.ts index 8985757ab1cab..5460b750a5b21 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/data_usage/tests/metrics.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/data_usage/tests/metrics.ts @@ -16,6 +16,12 @@ import { FtrProviderContext } from '../../../../ftr_provider_context'; import { setupMockServer } from '../mock_api'; import { mockAutoOpsResponse } from '../mock_data'; +const now = new Date(); +const to = now.toISOString(); // Current time in ISO format + +const nowMinus24Hours = new Date(now.getTime() - 24 * 60 * 60 * 1000); +const from = nowMinus24Hours.toISOString(); + export default function ({ getService }: FtrProviderContext) { const svlDatastreamsHelpers = getService('svlDatastreamsHelpers'); const roleScopedSupertest = getService('roleScopedSupertest'); @@ -46,8 +52,8 @@ export default function ({ getService }: FtrProviderContext) { after(async () => await svlDatastreamsHelpers.deleteDataStream(testDataStreamName)); it('returns 400 with non-existent data streams', async () => { const requestBody: UsageMetricsRequestBody = { - from: 'now-24h/h', - to: 'now', + from, + to, metricTypes: ['ingest_rate', 'storage_retained'], dataStreams: ['invalid-data-stream'], }; @@ -61,8 +67,8 @@ export default function ({ getService }: FtrProviderContext) { it('returns 400 when requesting no data streams', async () => { const requestBody = { - from: 'now-24h/h', - to: 'now', + from, + to, metricTypes: ['ingest_rate'], dataStreams: [], }; @@ -76,8 +82,8 @@ export default function ({ getService }: FtrProviderContext) { it('returns 400 when requesting an invalid metric type', async () => { const requestBody = { - from: 'now-24h/h', - to: 'now', + from, + to, metricTypes: [testDataStreamName], dataStreams: ['datastream'], }; @@ -93,8 +99,8 @@ export default function ({ getService }: FtrProviderContext) { it('returns 200 with valid request', async () => { const requestBody: UsageMetricsRequestBody = { - from: 'now-24h/h', - to: 'now', + from, + to, metricTypes: ['ingest_rate', 'storage_retained'], dataStreams: [testDataStreamName], }; diff --git a/x-pack/test_serverless/functional/test_suites/common/data_usage/main.ts b/x-pack/test_serverless/functional/test_suites/common/data_usage/main.ts index fa6e4199bdc09..0b59557229cd4 100644 --- a/x-pack/test_serverless/functional/test_suites/common/data_usage/main.ts +++ b/x-pack/test_serverless/functional/test_suites/common/data_usage/main.ts @@ -24,8 +24,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await pageObjects.svlManagementPage.clickDataUsageManagementCard(); }); - after(async () => {}); - it('renders data usage page', async () => { await retry.waitFor('page to be visible', async () => { return await testSubjects.exists('DataUsagePage');