Skip to content

Commit

Permalink
[ML] support legacy callWithRequest for job validation
Browse files Browse the repository at this point in the history
  • Loading branch information
darnautov committed Feb 4, 2020
1 parent c810f48 commit 11dfb5a
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { RequestHandlerContext } from 'kibana/server';
import { CallAPIOptions, RequestHandlerContext } from 'kibana/server';
import _ from 'lodash';
import { ML_JOB_FIELD_TYPES } from '../../../common/constants/field_types';
import { getSafeAggregationName } from '../../../common/util/job_utils';
Expand Down Expand Up @@ -107,10 +107,15 @@ type BatchStats =
| FieldExamples;

export class DataVisualizer {
context: RequestHandlerContext;

constructor(context: RequestHandlerContext) {
this.context = context;
callAsCurrentUser: (
endpoint: string,
clientParams: Record<string, any>,
options?: CallAPIOptions
) => Promise<any>;

constructor(client: RequestHandlerContext | (() => any)) {
this.callAsCurrentUser =
typeof client === 'object' ? client.ml!.mlClient.callAsCurrentUser : client;
}

// Obtains overall stats on the fields in the supplied index pattern, returning an object
Expand Down Expand Up @@ -367,7 +372,7 @@ export class DataVisualizer {
aggs: buildSamplerAggregation(aggs, samplerShardSize),
};

const resp = await this.context.ml!.mlClient.callAsCurrentUser('search', {
const resp = await this.callAsCurrentUser('search', {
index,
rest_total_hits_as_int: true,
size,
Expand Down Expand Up @@ -434,7 +439,7 @@ export class DataVisualizer {
};
filterCriteria.push({ exists: { field } });

const resp = await this.context.ml!.mlClient.callAsCurrentUser('search', {
const resp = await this.callAsCurrentUser('search', {
index,
rest_total_hits_as_int: true,
size,
Expand Down Expand Up @@ -476,7 +481,7 @@ export class DataVisualizer {
aggs,
};

const resp = await this.context.ml!.mlClient.callAsCurrentUser('search', {
const resp = await this.callAsCurrentUser('search', {
index,
size,
body,
Expand Down Expand Up @@ -579,7 +584,7 @@ export class DataVisualizer {
aggs: buildSamplerAggregation(aggs, samplerShardSize),
};

const resp = await this.context.ml!.mlClient.callAsCurrentUser('search', {
const resp = await this.callAsCurrentUser('search', {
index,
size,
body,
Expand Down Expand Up @@ -700,7 +705,7 @@ export class DataVisualizer {
aggs: buildSamplerAggregation(aggs, samplerShardSize),
};

const resp = await this.context.ml!.mlClient.callAsCurrentUser('search', {
const resp = await this.callAsCurrentUser('search', {
index,
size,
body,
Expand Down Expand Up @@ -774,7 +779,7 @@ export class DataVisualizer {
aggs: buildSamplerAggregation(aggs, samplerShardSize),
};

const resp = await this.context.ml!.mlClient.callAsCurrentUser('search', {
const resp = await this.callAsCurrentUser('search', {
index,
size,
body,
Expand Down Expand Up @@ -841,7 +846,7 @@ export class DataVisualizer {
aggs: buildSamplerAggregation(aggs, samplerShardSize),
};

const resp = await this.context.ml!.mlClient.callAsCurrentUser('search', {
const resp = await this.callAsCurrentUser('search', {
index,
size,
body,
Expand Down Expand Up @@ -903,7 +908,7 @@ export class DataVisualizer {
},
};

const resp = await this.context.ml!.mlClient.callAsCurrentUser('search', {
const resp = await this.callAsCurrentUser('search', {
index,
rest_total_hits_as_int: true,
size,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ const PARTITION_FIELD_CARDINALITY_THRESHOLD = 1000;
const BY_FIELD_CARDINALITY_THRESHOLD = 1000;
const MODEL_PLOT_THRESHOLD_HIGH = 100;

const validateFactory = (context, job) => {
const dv = new DataVisualizer(context);
const validateFactory = (callWithRequest, job) => {
const dv = new DataVisualizer(callWithRequest);

const modelPlotConfigTerms = _.get(job, ['model_plot_config', 'terms'], '');
const modelPlotConfigFieldCount =
Expand All @@ -55,7 +55,7 @@ const validateFactory = (context, job) => {
const uniqueFieldNames = _.uniq(relevantDetectors.map(f => f[fieldName]));

// use fieldCaps endpoint to get data about whether fields are aggregatable
const fieldCaps = await context.ml.mlClient.callAsCurrentUser('fieldCaps', {
const fieldCaps = await callWithRequest('fieldCaps', {
index: job.datafeed_config.indices.join(','),
fields: uniqueFieldNames,
});
Expand Down Expand Up @@ -129,7 +129,7 @@ const validateFactory = (context, job) => {
};
};

export async function validateCardinality(context, job) {
export async function validateCardinality(callWithRequest, job) {
const messages = [];

validateJobObject(job);
Expand All @@ -144,7 +144,7 @@ export async function validateCardinality(context, job) {
}

// validate({ type, isInvalid }) asynchronously returns an array of validation messages
const validate = validateFactory(context, job);
const validate = validateFactory(callWithRequest, job);

const modelPlotEnabled =
(job.model_plot_config && job.model_plot_config.enabled === true) || false;
Expand Down
38 changes: 12 additions & 26 deletions x-pack/legacy/plugins/ml/server/routes/job_validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,20 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { schema } from '@kbn/config-schema';
import Boom from 'boom';

import { callWithRequestFactory } from '../client/call_with_request_factory';
import { wrapError } from '../client/errors';
import { wrapError as errorWrapper } from '../client/error_wrapper';
import { estimateBucketSpanFactory } from '../models/bucket_span_estimator';
import { calculateModelMemoryLimitProvider } from '../models/calculate_model_memory_limit';
import { validateJob, validateCardinality } from '../models/job_validation';
import { licensePreRoutingFactory } from '../new_platform/licence_check_pre_routing_factory';

export function jobValidationRoutes({
commonRouteConfig,
config,
elasticsearchPlugin,
route,
xpackMainPlugin,
router,
}) {
function calculateModelMemoryLimit(callWithRequest, payload) {
const {
Expand Down Expand Up @@ -94,29 +90,19 @@ export function jobValidationRoutes({
},
});

/**
* @apiGroup JobValidation
*
* @api {post} /api/ml/validate/cardinality Validate cardinality
* @apiName ValidateCardinality
* @apiDescription Returns cardinality validation result.
*/
router.post(
{
path: '/api/ml/validate/cardinality',
validate: {
body: schema.any(),
},
route({
method: 'POST',
path: '/api/ml/validate/cardinality',
handler(request, reply) {
const callWithRequest = callWithRequestFactory(elasticsearchPlugin, request);
return validateCardinality(callWithRequest, request.payload)
.then(reply)
.catch(resp => wrapError(resp));
},
licensePreRoutingFactory(xpackMainPlugin, async (context, request, response) => {
try {
const result = await validateCardinality(context, request.body);
return response.ok({ body: result });
} catch (e) {
return response.customError(errorWrapper(e));
}
})
);
config: {
...commonRouteConfig,
},
});

route({
method: 'POST',
Expand Down

0 comments on commit 11dfb5a

Please sign in to comment.