kibana/x-pack/plugins/ml/server/routes/results_service.ts
James Gowdy d8c15f5ad3
[ML] Adding endpoint capability checks (#64662)
* [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>
2020-04-29 18:25:48 +01:00

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));
}
})
);
}