"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.jobValidationRoutes = jobValidationRoutes; var _boom = _interopRequireDefault(require("@hapi/boom")); var _app = require("../../common/constants/app"); var _error_wrapper = require("../client/error_wrapper"); var _job_validation_schema = require("./schemas/job_validation_schema"); var _bucket_span_estimator = require("../models/bucket_span_estimator"); var _calculate_model_memory_limit = require("../models/calculate_model_memory_limit"); var _job_validation = require("../models/job_validation"); var _request_authorization = require("../lib/request_authorization"); /* * 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. */ /** * Routes for job validation */ function jobValidationRoutes({ router, mlLicense, routeGuard }) { function calculateModelMemoryLimit(client, mlClient, payload) { const { datafeedConfig, analysisConfig, indexPattern, query, timeFieldName, earliestMs, latestMs } = payload; return (0, _calculate_model_memory_limit.calculateModelMemoryLimitProvider)(client, mlClient)(analysisConfig, indexPattern, query, timeFieldName, earliestMs, latestMs, undefined, datafeedConfig); } /** * @apiGroup JobValidation * * @api {post} /internal/ml/validate/estimate_bucket_span Estimate bucket span * @apiName EstimateBucketSpan * @apiDescription Estimates minimum viable bucket span based on the characteristics of a pre-viewed subset of the data * * @apiSchema (body) estimateBucketSpanSchema */ router.versioned.post({ path: `${_app.ML_INTERNAL_BASE_PATH}/validate/estimate_bucket_span`, access: 'internal', options: { tags: ['access:ml:canCreateJob'] } }).addVersion({ version: '1', validate: { request: { body: _job_validation_schema.estimateBucketSpanSchema } } }, routeGuard.fullLicenseAPIGuard(async ({ client, request, response }) => { try { let errorResp; const resp = await (0, _bucket_span_estimator.estimateBucketSpanFactory)(client)(request.body) // this catch gets triggered when the estimation code runs without error // but isn't able to come up with a bucket span estimation. // this doesn't return a HTTP error but an object with an error message a HTTP error would be // too severe for this case. .catch(error => { errorResp = { error: true, message: error }; }); return response.ok({ body: errorResp !== undefined ? errorResp : resp }); } catch (e) { // this catch gets triggered when an actual error gets thrown when running // the estimation code, for example when the request payload is malformed throw _boom.default.badRequest(e); } })); /** * @apiGroup JobValidation * * @api {post} /internal/ml/validate/calculate_model_memory_limit Calculates model memory limit * @apiName CalculateModelMemoryLimit * @apiDescription Calls _estimate_model_memory endpoint to retrieve model memory estimation. * * @apiSchema (body) modelMemoryLimitSchema * * @apiSuccess {String} modelMemoryLimit */ router.versioned.post({ path: `${_app.ML_INTERNAL_BASE_PATH}/validate/calculate_model_memory_limit`, access: 'internal', options: { tags: ['access:ml:canCreateJob'] } }).addVersion({ version: '1', validate: { request: { body: _job_validation_schema.modelMemoryLimitSchema } } }, routeGuard.fullLicenseAPIGuard(async ({ client, mlClient, request, response }) => { try { const resp = await calculateModelMemoryLimit(client, mlClient, request.body); return response.ok({ body: resp }); } catch (e) { return response.customError((0, _error_wrapper.wrapError)(e)); } })); /** * @apiGroup JobValidation * * @api {post} /internal/ml/validate/cardinality Validate cardinality * @apiName ValidateCardinality * @apiDescription Validates cardinality for the given job configuration * * @apiSchema (body) validateCardinalitySchema */ router.versioned.post({ path: `${_app.ML_INTERNAL_BASE_PATH}/validate/cardinality`, access: 'internal', options: { tags: ['access:ml:canCreateJob'] } }).addVersion({ version: '1', validate: { request: { body: _job_validation_schema.validateCardinalitySchema } } }, routeGuard.fullLicenseAPIGuard(async ({ client, request, response }) => { try { // @ts-expect-error datafeed config is incorrect const resp = await (0, _job_validation.validateCardinality)(client, request.body); return response.ok({ body: resp }); } catch (e) { return response.customError((0, _error_wrapper.wrapError)(e)); } })); /** * @apiGroup JobValidation * * @api {post} /internal/ml/validate/job Validates job * @apiName ValidateJob * @apiDescription Validates the given job configuration * * @apiSchema (body) validateJobSchema */ router.versioned.post({ path: `${_app.ML_INTERNAL_BASE_PATH}/validate/job`, access: 'internal', options: { tags: ['access:ml:canCreateJob'] } }).addVersion({ version: '1', validate: { request: { body: _job_validation_schema.validateJobSchema } } }, routeGuard.fullLicenseAPIGuard(async ({ client, mlClient, request, response }) => { try { const resp = await (0, _job_validation.validateJob)(client, mlClient, request.body, (0, _request_authorization.getAuthorizationHeader)(request), mlLicense.isSecurityEnabled() === false); return response.ok({ body: resp }); } catch (e) { return response.customError((0, _error_wrapper.wrapError)(e)); } })); /** * @apiGroup DataFeedPreviewValidation * * @api {post} /internal/ml/validate/datafeed_preview Validates datafeed preview * @apiName ValidateDataFeedPreview * @apiDescription Validates that the datafeed preview runs successfully and produces results * * @apiSchema (body) validateDatafeedPreviewSchema */ router.versioned.post({ path: `${_app.ML_INTERNAL_BASE_PATH}/validate/datafeed_preview`, access: 'internal', options: { tags: ['access:ml:canCreateJob'] } }).addVersion({ version: '1', validate: { request: { body: _job_validation_schema.validateDatafeedPreviewSchema } } }, routeGuard.fullLicenseAPIGuard(async ({ client, mlClient, request, response }) => { try { const { body: { job, start, end } } = request; const resp = await (0, _job_validation.validateDatafeedPreview)(mlClient, (0, _request_authorization.getAuthorizationHeader)(request), job, start, end); return response.ok({ body: resp }); } catch (e) { return response.customError((0, _error_wrapper.wrapError)(e)); } })); }