Skip to content

Commit

Permalink
[APM] Offer users upgrade to multi-metric job (#119980)
Browse files Browse the repository at this point in the history
  • Loading branch information
dgieselaar authored Dec 7, 2021
1 parent 8a49859 commit 0ed5cb9
Show file tree
Hide file tree
Showing 33 changed files with 1,157 additions and 431 deletions.
17 changes: 17 additions & 0 deletions x-pack/plugins/apm/common/anomaly_detection/apm_ml_job.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* 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.
*/
import { DATAFEED_STATE, JOB_STATE } from '../../../ml/common';
import { Environment } from '../environment_rt';

export interface ApmMlJob {
environment: Environment;
version: number;
jobId: string;
jobState?: JOB_STATE;
datafeedId?: string;
datafeedState?: DATAFEED_STATE;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* 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.
*/
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { FETCH_STATUS } from '../../public/hooks/use_fetcher';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import type { APIReturnType } from '../../public/services/rest/createCallApmApi';
import { ENVIRONMENT_ALL } from '../environment_filter_values';

export enum AnomalyDetectionSetupState {
Loading = 'pending',
Failure = 'failure',
Unknown = 'unknown',
NoJobs = 'noJobs',
NoJobsForEnvironment = 'noJobsForEnvironment',
LegacyJobs = 'legacyJobs',
UpgradeableJobs = 'upgradeableJobs',
UpToDate = 'upToDate',
}

export function getAnomalyDetectionSetupState({
environment,
jobs,
fetchStatus,
isAuthorized,
}: {
environment: string;
jobs: APIReturnType<'GET /internal/apm/settings/anomaly-detection/jobs'>['jobs'];
fetchStatus: FETCH_STATUS;
isAuthorized: boolean;
}): AnomalyDetectionSetupState {
if (!isAuthorized) {
return AnomalyDetectionSetupState.Unknown;
}

if (fetchStatus === FETCH_STATUS.LOADING) {
return AnomalyDetectionSetupState.Loading;
}

if (fetchStatus === FETCH_STATUS.FAILURE) {
return AnomalyDetectionSetupState.Failure;
}

if (fetchStatus !== FETCH_STATUS.SUCCESS) {
return AnomalyDetectionSetupState.Unknown;
}

const jobsForEnvironment =
environment === ENVIRONMENT_ALL.value
? jobs
: jobs.filter((job) => job.environment === environment);

const hasV1Jobs = jobs.some((job) => job.version === 1);
const hasV2Jobs = jobsForEnvironment.some((job) => job.version === 2);
const hasV3Jobs = jobsForEnvironment.some((job) => job.version === 3);
const hasAnyJobs = jobs.length > 0;

if (hasV3Jobs) {
return AnomalyDetectionSetupState.UpToDate;
}

if (hasV2Jobs) {
return AnomalyDetectionSetupState.UpgradeableJobs;
}

if (hasV1Jobs) {
return AnomalyDetectionSetupState.LegacyJobs;
}

if (hasAnyJobs) {
return AnomalyDetectionSetupState.NoJobsForEnvironment;
}

return AnomalyDetectionSetupState.NoJobs;
}
12 changes: 7 additions & 5 deletions x-pack/plugins/apm/common/environment_rt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import {
ENVIRONMENT_NOT_DEFINED,
} from './environment_filter_values';

export const environmentStringRt = t.union([
t.literal(ENVIRONMENT_NOT_DEFINED.value),
t.literal(ENVIRONMENT_ALL.value),
nonEmptyStringRt,
]);

export const environmentRt = t.type({
environment: t.union([
t.literal(ENVIRONMENT_NOT_DEFINED.value),
t.literal(ENVIRONMENT_ALL.value),
nonEmptyStringRt,
]),
environment: environmentStringRt,
});

export type Environment = t.TypeOf<typeof environmentRt>['environment'];
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,14 @@ import { ML_ERRORS } from '../../../../../common/anomaly_detection';
import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context';
import { JobsList } from './jobs_list';
import { AddEnvironments } from './add_environments';
import { useFetcher } from '../../../../hooks/use_fetcher';
import { LicensePrompt } from '../../../shared/license_prompt';
import { useLicenseContext } from '../../../../context/license/use_license_context';
import { APIReturnType } from '../../../../services/rest/createCallApmApi';
import { useAnomalyDetectionJobsContext } from '../../../../context/anomaly_detection_jobs/use_anomaly_detection_jobs_context';

export type AnomalyDetectionApiResponse =
APIReturnType<'GET /internal/apm/settings/anomaly-detection/jobs'>;

const DEFAULT_VALUE: AnomalyDetectionApiResponse = {
jobs: [],
hasLegacyJobs: false,
};

export function AnomalyDetection() {
const plugin = useApmPluginContext();
const canGetJobs = !!plugin.core.application.capabilities.ml?.canGetJobs;
Expand All @@ -33,20 +28,14 @@ export function AnomalyDetection() {
const [viewAddEnvironments, setViewAddEnvironments] = useState(false);

const {
refetch,
data = DEFAULT_VALUE,
status,
} = useFetcher(
(callApmApi) => {
if (canGetJobs) {
return callApmApi({
endpoint: `GET /internal/apm/settings/anomaly-detection/jobs`,
});
}
},
[canGetJobs],
{ preservePreviousData: false, showToastOnError: false }
);
anomalyDetectionJobsStatus,
anomalyDetectionJobsRefetch,
anomalyDetectionJobsData = {
jobs: [],
hasLegacyJobs: false,
} as AnomalyDetectionApiResponse,
anomalyDetectionSetupState,
} = useAnomalyDetectionJobsContext();

if (!hasValidLicense) {
return (
Expand All @@ -71,9 +60,11 @@ export function AnomalyDetection() {
<>
{viewAddEnvironments ? (
<AddEnvironments
currentEnvironments={data.jobs.map(({ environment }) => environment)}
currentEnvironments={anomalyDetectionJobsData.jobs.map(
({ environment }) => environment
)}
onCreateJobSuccess={() => {
refetch();
anomalyDetectionJobsRefetch();
setViewAddEnvironments(false);
}}
onCancel={() => {
Expand All @@ -82,11 +73,15 @@ export function AnomalyDetection() {
/>
) : (
<JobsList
data={data}
status={status}
data={anomalyDetectionJobsData}
status={anomalyDetectionJobsStatus}
setupState={anomalyDetectionSetupState}
onAddEnvironments={() => {
setViewAddEnvironments(true);
}}
onUpdateComplete={() => {
anomalyDetectionJobsRefetch();
}}
/>
)}
</>
Expand Down
Loading

0 comments on commit 0ed5cb9

Please sign in to comment.