Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ jest.mock('../../../../../util/index_utils', () => {
};
}
),
isCcsIndexPattern: (a: string) => a.includes(':'),
};
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { useMlKibana, useNavigateToPath } from '../../../../../contexts/kibana';

import { getNestedProperty } from '../../../../../util/object_utils';

import { getIndexPatternAndSavedSearch } from '../../../../../util/index_utils';
import { getIndexPatternAndSavedSearch, isCcsIndexPattern } from '../../../../../util/index_utils';

const fixedPageSize: number = 8;

Expand Down Expand Up @@ -61,7 +61,7 @@ export const SourceSelection: FC<Props> = ({ onClose }) => {
indexPatternTitle = indexPatternAndSavedSearch.indexPattern?.title ?? '';
}

if (indexPatternTitle.includes(':')) {
if (isCcsIndexPattern(indexPatternTitle)) {
setIsCcsCallOut(true);
if (type === 'search') {
setCcsCallOutBodyText(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ import {
CategorizationAnalyzer,
CategoryFieldExample,
FieldExampleCheck,
VALIDATION_RESULT,
} from '../../../../../../common/types/categories';
import { getRichDetectors } from './util/general';
import { CategorizationExamplesLoader } from '../results_loader';
import { getNewJobDefaults } from '../../../../services/ml_server_info';
import { isCcsIndexPattern } from '../../../../util/index_utils';

export class CategorizationJobCreator extends JobCreator {
protected _type: JOB_TYPE = JOB_TYPE.CATEGORIZATION;
Expand All @@ -43,6 +45,7 @@ export class CategorizationJobCreator extends JobCreator {
private _categorizationAnalyzer: CategorizationAnalyzer = {};
private _defaultCategorizationAnalyzer: CategorizationAnalyzer;
private _partitionFieldName: string | null = null;
private _ccsVersionFailure: boolean = false;

constructor(
indexPattern: IndexPattern,
Expand Down Expand Up @@ -126,9 +129,38 @@ export class CategorizationJobCreator extends JobCreator {
this._validationChecks = validationChecks;
this._overallValidStatus = overallValidStatus;

this._ccsVersionFailure = this._checkCcsFailure(examples, overallValidStatus, validationChecks);
if (this._ccsVersionFailure === true) {
// if the index pattern contains a cross-cluster search, one of the clusters may
// be on a version which doesn't support the fields API (e.g. 6.8)
// and so the categorization examples endpoint will fail
// if this is the case, we need to allow the user to progress in the wizard.
this._overallValidStatus = CATEGORY_EXAMPLES_VALIDATION_STATUS.VALID;
}

this._wizardInitialized$.next(true);

return { examples, sampleSize, overallValidStatus, validationChecks };
return {
examples,
sampleSize,
overallValidStatus,
validationChecks,
ccsVersionFailure: this._ccsVersionFailure,
};
}

// Check to see if the examples failed due to a cross-cluster search being used
private _checkCcsFailure(
examples: CategoryFieldExample[],
status: CATEGORY_EXAMPLES_VALIDATION_STATUS,
checks: FieldExampleCheck[]
) {
return (
examples.length === 0 &&
status === CATEGORY_EXAMPLES_VALIDATION_STATUS.INVALID &&
checks[0]?.id === VALIDATION_RESULT.NO_EXAMPLES &&
isCcsIndexPattern(this.indexPatternTitle)
);
}

public get categoryFieldExamples() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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 React, { FC } from 'react';
import { EuiCallOut } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';

export const InvalidCssVersionCallout: FC = () => {
return (
<EuiCallOut
color="warning"
title={i18n.translate(
'xpack.ml.newJob.wizard.pickFieldsStep.invalidCssVersionCallout.title',
{
defaultMessage: 'The index pattern appears to be cross-cluster',
}
)}
>
<FormattedMessage
id="xpack.ml.newJob.wizard.pickFieldsStep.invalidCssVersionCallout.mesage"
defaultMessage="No example categories could be found, this could be due to one of the clusters being an unsupported version."
/>
</EuiCallOut>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { CategorizationPerPartitionField } from '../categorization_partition_fie

import { FieldExamples } from './field_examples';
import { ExamplesValidCallout } from './examples_valid_callout';
import { InvalidCssVersionCallout } from './invalid_ccs_version_valid_callout';
import {
CategoryFieldExample,
FieldExampleCheck,
Expand All @@ -33,6 +34,7 @@ export const CategorizationDetectors: FC<Props> = ({ setIsValid }) => {
const jobCreator = jc as CategorizationJobCreator;

const [loadingData, setLoadingData] = useState(false);
const [ccsVersionFailure, setCcsVersionFailure] = useState(false);
const [start, setStart] = useState(jobCreator.start);
const [end, setEnd] = useState(jobCreator.end);
const [categorizationAnalyzerString, setCategorizationAnalyzerString] = useState(
Expand Down Expand Up @@ -85,22 +87,26 @@ export const CategorizationDetectors: FC<Props> = ({ setIsValid }) => {
examples,
overallValidStatus: tempOverallValidStatus,
validationChecks: tempValidationChecks,
ccsVersionFailure: tempCcsVersionFailure,
} = await jobCreator.loadCategorizationFieldExamples();
setFieldExamples(examples);
setOverallValidStatus(tempOverallValidStatus);
setValidationChecks(tempValidationChecks);
setCcsVersionFailure(tempCcsVersionFailure);
setLoadingData(false);
} catch (error) {
setLoadingData(false);
setFieldExamples(null);
setValidationChecks([]);
setOverallValidStatus(CATEGORY_EXAMPLES_VALIDATION_STATUS.INVALID);
getToastNotificationService().displayErrorToast(error);
setCcsVersionFailure(false);
}
} else {
setFieldExamples(null);
setValidationChecks([]);
setOverallValidStatus(CATEGORY_EXAMPLES_VALIDATION_STATUS.INVALID);
setCcsVersionFailure(false);
}
setIsValid(categorizationFieldName !== null);
}
Expand All @@ -119,7 +125,7 @@ export const CategorizationDetectors: FC<Props> = ({ setIsValid }) => {
<div />
</LoadingWrapper>
)}
{fieldExamples !== null && loadingData === false && (
{ccsVersionFailure === false && fieldExamples !== null && loadingData === false && (
<>
<ExamplesValidCallout
overallValidStatus={overallValidStatus}
Expand All @@ -129,6 +135,7 @@ export const CategorizationDetectors: FC<Props> = ({ setIsValid }) => {
<FieldExamples fieldExamples={fieldExamples} />
</>
)}
{ccsVersionFailure === true && <InvalidCssVersionCallout />}
<EuiHorizontalRule />
<CategorizationPerPartitionField />
</>
Expand Down
8 changes: 8 additions & 0 deletions x-pack/plugins/ml/public/application/util/index_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,11 @@ export function timeBasedIndexCheck(indexPattern: IndexPattern, showNotification
return true;
}
}

/**
* Returns true if the index pattern contains a :
* which means it is cross-cluster
*/
export function isCcsIndexPattern(indexPatternTitle: string) {
return indexPatternTitle.includes(':');
}