* [ML] Adding endpoint capability checks * adding missing capability checks * fixing test * removing commented code * fixing functional test * fixing functional tests * changes based on review Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
235 lines
6.7 KiB
TypeScript
235 lines
6.7 KiB
TypeScript
/*
|
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
* or more contributor license agreements. Licensed under the Elastic License;
|
|
* you may not use this file except in compliance with the Elastic License.
|
|
*/
|
|
|
|
import { RequestHandlerContext } from 'kibana/server';
|
|
import { wrapError } from '../client/error_wrapper';
|
|
import { RouteInitialization } from '../types';
|
|
import {
|
|
anomaliesTableDataSchema,
|
|
categoryDefinitionSchema,
|
|
categoryExamplesSchema,
|
|
maxAnomalyScoreSchema,
|
|
partitionFieldValuesSchema,
|
|
} from './schemas/results_service_schema';
|
|
import { resultsServiceProvider } from '../models/results_service';
|
|
|
|
function getAnomaliesTableData(context: RequestHandlerContext, payload: any) {
|
|
const rs = resultsServiceProvider(context.ml!.mlClient.callAsCurrentUser);
|
|
const {
|
|
jobIds,
|
|
criteriaFields,
|
|
influencers,
|
|
aggregationInterval,
|
|
threshold,
|
|
earliestMs,
|
|
latestMs,
|
|
dateFormatTz,
|
|
maxRecords,
|
|
maxExamples,
|
|
influencersFilterQuery,
|
|
} = payload;
|
|
return rs.getAnomaliesTableData(
|
|
jobIds,
|
|
criteriaFields,
|
|
influencers,
|
|
aggregationInterval,
|
|
threshold,
|
|
earliestMs,
|
|
latestMs,
|
|
dateFormatTz,
|
|
maxRecords,
|
|
maxExamples,
|
|
influencersFilterQuery
|
|
);
|
|
}
|
|
|
|
function getCategoryDefinition(context: RequestHandlerContext, payload: any) {
|
|
const rs = resultsServiceProvider(context.ml!.mlClient.callAsCurrentUser);
|
|
return rs.getCategoryDefinition(payload.jobId, payload.categoryId);
|
|
}
|
|
|
|
function getCategoryExamples(context: RequestHandlerContext, payload: any) {
|
|
const rs = resultsServiceProvider(context.ml!.mlClient.callAsCurrentUser);
|
|
const { jobId, categoryIds, maxExamples } = payload;
|
|
return rs.getCategoryExamples(jobId, categoryIds, maxExamples);
|
|
}
|
|
|
|
function getMaxAnomalyScore(context: RequestHandlerContext, payload: any) {
|
|
const rs = resultsServiceProvider(context.ml!.mlClient.callAsCurrentUser);
|
|
const { jobIds, earliestMs, latestMs } = payload;
|
|
return rs.getMaxAnomalyScore(jobIds, earliestMs, latestMs);
|
|
}
|
|
|
|
function getPartitionFieldsValues(context: RequestHandlerContext, payload: any) {
|
|
const rs = resultsServiceProvider(context.ml!.mlClient.callAsCurrentUser);
|
|
const { jobId, searchTerm, criteriaFields, earliestMs, latestMs } = payload;
|
|
return rs.getPartitionFieldsValues(jobId, searchTerm, criteriaFields, earliestMs, latestMs);
|
|
}
|
|
|
|
/**
|
|
* Routes for results service
|
|
*/
|
|
export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization) {
|
|
/**
|
|
* @apiGroup ResultsService
|
|
*
|
|
* @api {post} /api/ml/results/anomalies_table_data Prepare anomalies records for table display
|
|
* @apiName GetAnomaliesTableData
|
|
* @apiDescription Retrieves anomaly records for an anomaly detection job and formats them for anomalies table display
|
|
*
|
|
* @apiSchema (body) anomaliesTableDataSchema
|
|
*/
|
|
router.post(
|
|
{
|
|
path: '/api/ml/results/anomalies_table_data',
|
|
validate: {
|
|
body: anomaliesTableDataSchema,
|
|
},
|
|
options: {
|
|
tags: ['access:ml:canGetJobs'],
|
|
},
|
|
},
|
|
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
|
|
try {
|
|
const resp = await getAnomaliesTableData(context, request.body);
|
|
|
|
return response.ok({
|
|
body: resp,
|
|
});
|
|
} catch (e) {
|
|
return response.customError(wrapError(e));
|
|
}
|
|
})
|
|
);
|
|
|
|
/**
|
|
* @apiGroup ResultsService
|
|
*
|
|
* @api {post} /api/ml/results/category_definition Returns category definition
|
|
* @apiName GetCategoryDefinition
|
|
* @apiDescription Returns the definition of the category with the specified ID and job ID
|
|
*
|
|
* @apiSchema (body) categoryDefinitionSchema
|
|
*/
|
|
router.post(
|
|
{
|
|
path: '/api/ml/results/category_definition',
|
|
validate: {
|
|
body: categoryDefinitionSchema,
|
|
},
|
|
options: {
|
|
tags: ['access:ml:canGetJobs'],
|
|
},
|
|
},
|
|
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
|
|
try {
|
|
const resp = await getCategoryDefinition(context, request.body);
|
|
|
|
return response.ok({
|
|
body: resp,
|
|
});
|
|
} catch (e) {
|
|
return response.customError(wrapError(e));
|
|
}
|
|
})
|
|
);
|
|
|
|
/**
|
|
* @apiGroup ResultsService
|
|
*
|
|
* @api {post} /api/ml/results/max_anomaly_score Returns the maximum anomaly_score
|
|
* @apiName GetMaxAnomalyScore
|
|
* @apiDescription Returns the maximum anomaly score of the bucket results for the request job ID(s) and time range
|
|
*
|
|
* @apiSchema (body) maxAnomalyScoreSchema
|
|
*/
|
|
router.post(
|
|
{
|
|
path: '/api/ml/results/max_anomaly_score',
|
|
validate: {
|
|
body: maxAnomalyScoreSchema,
|
|
},
|
|
options: {
|
|
tags: ['access:ml:canGetJobs'],
|
|
},
|
|
},
|
|
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
|
|
try {
|
|
const resp = await getMaxAnomalyScore(context, request.body);
|
|
|
|
return response.ok({
|
|
body: resp,
|
|
});
|
|
} catch (e) {
|
|
return response.customError(wrapError(e));
|
|
}
|
|
})
|
|
);
|
|
|
|
/**
|
|
* @apiGroup ResultsService
|
|
*
|
|
* @api {post} /api/ml/results/category_examples Returns category examples
|
|
* @apiName GetCategoryExamples
|
|
* @apiDescription Returns examples for the categories with the specified IDs from the job with the supplied ID
|
|
*
|
|
* @apiSchema (body) categoryExamplesSchema
|
|
*/
|
|
router.post(
|
|
{
|
|
path: '/api/ml/results/category_examples',
|
|
validate: {
|
|
body: categoryExamplesSchema,
|
|
},
|
|
options: {
|
|
tags: ['access:ml:canGetJobs'],
|
|
},
|
|
},
|
|
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
|
|
try {
|
|
const resp = await getCategoryExamples(context, request.body);
|
|
|
|
return response.ok({
|
|
body: resp,
|
|
});
|
|
} catch (e) {
|
|
return response.customError(wrapError(e));
|
|
}
|
|
})
|
|
);
|
|
|
|
/**
|
|
* @apiGroup ResultsService
|
|
*
|
|
* @api {post} /api/ml/results/partition_fields_values Returns partition fields values
|
|
* @apiName GetPartitionFieldsValues
|
|
* @apiDescription Returns the partition fields with values that match the provided criteria for the specified job ID.
|
|
*
|
|
* @apiSchema (body) partitionFieldValuesSchema
|
|
*/
|
|
router.post(
|
|
{
|
|
path: '/api/ml/results/partition_fields_values',
|
|
validate: {
|
|
body: partitionFieldValuesSchema,
|
|
},
|
|
options: {
|
|
tags: ['access:ml:canGetJobs'],
|
|
},
|
|
},
|
|
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
|
|
try {
|
|
const resp = await getPartitionFieldsValues(context, request.body);
|
|
|
|
return response.ok({
|
|
body: resp,
|
|
});
|
|
} catch (e) {
|
|
return response.customError(wrapError(e));
|
|
}
|
|
})
|
|
);
|
|
}
|