[ML] Fix put job endpoint when payload contains datafeed (#134986)

* [ML] Fix put job endpoint when payload contains datafeed

* adding tests
This commit is contained in:
James Gowdy 2022-06-23 12:35:44 +01:00 committed by GitHub
parent 8e1feb327a
commit ad10bf1334
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 108 additions and 6 deletions

View file

@ -25,6 +25,7 @@ import {
forceQuerySchema,
jobResetQuerySchema,
} from './schemas/anomaly_detectors_schema';
import { getAuthorizationHeader } from '../lib/request_authorization';
/**
* Routes for the anomaly detectors
@ -180,11 +181,14 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) {
routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => {
try {
const { jobId } = request.params;
const body = await mlClient.putJob({
job_id: jobId,
// @ts-expect-error job type custom_rules is incorrect
body: request.body,
});
const body = await mlClient.putJob(
{
job_id: jobId,
// @ts-expect-error job type custom_rules is incorrect
body: request.body,
},
getAuthorizationHeader(request)
);
return response.ok({
body,

View file

@ -6,6 +6,7 @@
*/
import { schema } from '@kbn/config-schema';
import { datafeedConfigSchema } from './datafeeds_schema';
const customRulesSchema = schema.maybe(
schema.arrayOf(
@ -121,7 +122,7 @@ export const anomalyDetectionJobSchema = {
description: schema.maybe(schema.string()),
established_model_memory: schema.maybe(schema.number()),
finished_time: schema.maybe(schema.number()),
job_id: schema.string(),
job_id: schema.maybe(schema.string()),
job_type: schema.maybe(schema.string()),
job_version: schema.maybe(schema.string()),
groups: schema.maybe(schema.arrayOf(schema.maybe(schema.string()))),
@ -136,6 +137,7 @@ export const anomalyDetectionJobSchema = {
results_index_name: schema.maybe(schema.string()),
results_retention_days: schema.maybe(schema.number()),
state: schema.maybe(schema.string()),
datafeed_config: schema.maybe(datafeedConfigSchema),
};
export const jobIdSchema = schema.object({

View file

@ -0,0 +1,95 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../../ftr_provider_context';
import { USER } from '../../../../functional/services/ml/security_common';
import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api';
export default ({ getService }: FtrProviderContext) => {
const esArchiver = getService('esArchiver');
const supertest = getService('supertestWithoutAuth');
const ml = getService('ml');
const jobId = `fq_single_${Date.now()}`;
const testDataList = [
{
testTitle: 'ML Poweruser creates a single metric job with datafeed',
user: USER.ML_POWERUSER,
jobId: `${jobId}_1`,
requestBody: {
job_id: `${jobId}_1`,
description:
'Single metric job based on the farequote dataset with 30m bucketspan and mean(responsetime)',
groups: ['automated', 'farequote', 'single-metric'],
analysis_config: {
bucket_span: '30m',
detectors: [{ function: 'mean', field_name: 'responsetime' }],
influencers: [],
summary_count_field_name: 'doc_count',
},
data_description: { time_field: '@timestamp' },
analysis_limits: { model_memory_limit: '11MB' },
model_plot_config: { enabled: true },
datafeed_config: {
datafeed_id: `datafeed-${jobId}_1`,
indices: ['farequote-*'],
query: {
match_all: {},
},
},
},
expected: {
responseCode: 200,
responseBody: {
// skipping parts of the job config we're not going to check
// we're only interesting in the datafeed_config for this test
datafeed_config: {
job_id: `${jobId}_1`,
datafeed_id: `datafeed-${jobId}_1`,
indices: ['farequote-*'],
query: {
match_all: {},
},
},
},
},
},
];
describe('PUT anomaly_detectors which contain a datafeed config', function () {
before(async () => {
await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote');
await ml.testResources.setKibanaTimeZoneToUTC();
});
after(async () => {
await ml.api.cleanMlIndices();
});
for (const testData of testDataList) {
it(`${testData.testTitle}`, async () => {
const { body, status } = await supertest
.put(`/api/ml/anomaly_detectors/${testData.jobId}`)
.auth(testData.user, ml.securityCommon.getPasswordForUser(testData.user))
.set(COMMON_REQUEST_HEADERS)
.send(testData.requestBody);
ml.api.assertResponseStatusCode(testData.expected.responseCode, status, body);
// Validate the important parts of the response.
const expectedResponse = testData.expected.responseBody;
expect(body.datafeed_config.datafeed_id).to.eql(
expectedResponse.datafeed_config.datafeed_id
);
expect(body.datafeed_config.job_id).to.eql(expectedResponse.datafeed_config.job_id);
expect(body.datafeed_config.indices).to.eql(expectedResponse.datafeed_config.indices);
});
}
});
};

View file

@ -18,5 +18,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./delete_with_spaces'));
loadTestFile(require.resolve('./create_with_spaces'));
loadTestFile(require.resolve('./forecast_with_spaces'));
loadTestFile(require.resolve('./create_with_datafeed'));
});
}