kibana/x-pack/plugins/ml/server/routes/results_service.ts
James Gowdy 18df677da7
[ML] Fixing file import, module creation and results viewing permission checks (#72825)
* [ML] Fixing file import and module creation permission checks

* correcting searches on results index

* fixing test

* removing unnecessary index

* updating apidoc

* fixing test

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
2020-07-23 16:11:15 +01:00

268 lines
7.5 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 { schema } from '@kbn/config-schema';
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';
import { ML_RESULTS_INDEX_PATTERN } from '../../common/constants/index_patterns';
function getAnomaliesTableData(context: RequestHandlerContext, payload: any) {
const rs = resultsServiceProvider(context.ml!.mlClient);
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);
return rs.getCategoryDefinition(payload.jobId, payload.categoryId);
}
function getCategoryExamples(context: RequestHandlerContext, payload: any) {
const rs = resultsServiceProvider(context.ml!.mlClient);
const { jobId, categoryIds, maxExamples } = payload;
return rs.getCategoryExamples(jobId, categoryIds, maxExamples);
}
function getMaxAnomalyScore(context: RequestHandlerContext, payload: any) {
const rs = resultsServiceProvider(context.ml!.mlClient);
const { jobIds, earliestMs, latestMs } = payload;
return rs.getMaxAnomalyScore(jobIds, earliestMs, latestMs);
}
function getPartitionFieldsValues(context: RequestHandlerContext, payload: any) {
const rs = resultsServiceProvider(context.ml!.mlClient);
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));
}
})
);
/**
* @apiGroup ResultsService
*
* @api {post} /api/ml/results/anomaly_search Performs a search on the anomaly results index
* @apiName AnomalySearch
*/
router.post(
{
path: '/api/ml/results/anomaly_search',
validate: {
body: schema.maybe(schema.any()),
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
const body = {
...request.body,
index: ML_RESULTS_INDEX_PATTERN,
};
try {
return response.ok({
body: await context.ml!.mlClient.callAsInternalUser('search', body),
});
} catch (error) {
return response.customError(wrapError(error));
}
})
);
}