Skip to content

Commit

Permalink
[Maps] fix Kibana Maps UI upload geojson failure should be received a…
Browse files Browse the repository at this point in the history
…s such (elastic#149969)

Fixes elastic#138122

PR updates geo spatial file upload to show error callout if all features
fail indexing. PR updates geo spatial file upload to show warning
callout if some features fail indexing.

<img width="150" alt="Screen Shot 2023-01-31 at 11 34 49 AM"
src="https://user-images.githubusercontent.com/373691/215851548-11cf9fa8-7c59-4d21-9257-664ab00f418d.png">

<img width="150" alt="Screen Shot 2023-01-31 at 11 34 32 AM"
src="https://user-images.githubusercontent.com/373691/215851557-09dfbef3-ae0e-4ddd-b617-9c70a66fa712.png">

To test save the following geojson samples as a file with the name
`<filename>.geojson`. Then upload the files in kibana. Verify errors are
displayed as expected

all invalid features
```
{
  "type" : "FeatureCollection",
  "features" : [{ 
    "type" : "Feature", 
    "geometry" : { 
      "type" : "Point", 
      "coordinates" : [ 100000, 42.417500 ] 
    }
  }]
}
```

some invalid features
```
{
  "type" : "FeatureCollection",
  "features" : [{ 
    "type" : "Feature", 
    "geometry" : { 
      "type" : "Point", 
      "coordinates" : [ 0, 0 ] 
    }
  },
  { 
    "type" : "Feature", 
    "geometry" : { 
      "type" : "Point", 
      "coordinates" : [ 100000, 0 ] 
    }
  }]
}
```

---------

Co-authored-by: kibanamachine <[email protected]>
  • Loading branch information
2 people authored and kqualters-elastic committed Feb 6, 2023
1 parent 0ab7722 commit 0e9d9c8
Show file tree
Hide file tree
Showing 8 changed files with 710 additions and 20 deletions.

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions x-pack/plugins/file_upload/public/components/geo_upload_wizard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { ImportResults } from '../importer';
import { GeoFileImporter } from '../importer/geo';
import type { Settings } from '../../common/types';
import { hasImportPermission } from '../api';
import { getPartialImportMessage } from './utils';

enum PHASE {
CONFIGURE = 'CONFIGURE',
Expand Down Expand Up @@ -175,6 +176,25 @@ export class GeoUploadWizard extends Component<FileUploadComponentProps, State>
});
this.props.onUploadError();
return;
} else if (importResults.docCount === importResults.failures?.length) {
this.setState({
// Force importResults into failure shape when no features are indexed
importResults: {
...importResults,
success: false,
error: {
error: {
reason: getPartialImportMessage(
importResults.failures!.length,
importResults.docCount
),
},
},
},
phase: PHASE.COMPLETE,
});
this.props.onUploadError();
return;
}

//
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* 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 from 'react';
import { shallow } from 'enzyme';

import { ImportCompleteView } from './import_complete_view';

jest.mock('../kibana_services', () => ({
get: jest.fn(),
getDocLinks: () => {
return {
links: {
maps: {
importGeospatialPrivileges: 'linkToPrvilegesDocs',
},
},
};
},
getHttp: () => {
return {
basePath: {
prepend: (path: string) => `abc${path}`,
},
};
},
getUiSettings: () => {
return {
get: jest.fn(),
};
},
}));

test('Should render success', () => {
const component = shallow(
<ImportCompleteView
failedPermissionCheck={false}
importResults={{
success: true,
docCount: 10,
}}
dataViewResp={{}}
indexName="myIndex"
/>
);

expect(component).toMatchSnapshot();
});

test('Should render warning when some features failed import', () => {
const component = shallow(
<ImportCompleteView
failedPermissionCheck={false}
importResults={{
success: true,
docCount: 10,
failures: [
{
item: 1,
reason: 'simulated feature import failure',
doc: {},
},
],
}}
dataViewResp={{}}
indexName="myIndex"
/>
);

expect(component).toMatchSnapshot();
});

test('Should render error when upload fails from http request timeout', () => {
const component = shallow(
<ImportCompleteView
failedPermissionCheck={false}
importResults={{
success: false,
docCount: 10,
error: {
body: {
message: 'simulated http request timeout',
},
},
}}
indexName="myIndex"
/>
);

expect(component).toMatchSnapshot();
});

test('Should render error when upload fails from elasticsearch request failure', () => {
const component = shallow(
<ImportCompleteView
failedPermissionCheck={false}
importResults={{
success: false,
docCount: 10,
error: {
error: {
reason: 'simulated elasticsearch request failure',
},
},
}}
indexName="myIndex"
/>
);

expect(component).toMatchSnapshot();
});
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
import { CodeEditor, KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { getDocLinks, getHttp, getUiSettings } from '../kibana_services';
import { ImportResults } from '../importer';
import { getPartialImportMessage } from './utils';

const services = {
uiSettings: getUiSettings(),
Expand Down Expand Up @@ -133,7 +134,7 @@ export class ImportCompleteView extends Component<Props, {}> {
// Display http request error message
reason = this.props.importResults.error.body.message;
} else if (this.props.importResults?.error?.error?.reason) {
// Display elasticxsearch request error message
// Display elasticsearch request error message
reason = this.props.importResults.error.error.reason;
}
const errorMsg = reason
Expand All @@ -156,21 +157,25 @@ export class ImportCompleteView extends Component<Props, {}> {
);
}

const successMsg = i18n.translate('xpack.fileUpload.importComplete.uploadSuccessMsg', {
defaultMessage: 'Indexed {numFeatures} features.',
values: {
numFeatures: this.props.importResults.docCount,
},
});

const failedFeaturesMsg = this.props.importResults.failures?.length
? i18n.translate('xpack.fileUpload.importComplete.failedFeaturesMsg', {
defaultMessage: 'Unable to index {numFailures} features.',
values: {
numFailures: this.props.importResults.failures.length,
},
})
: '';
if (this.props.importResults.failures?.length) {
return (
<EuiCallOut
title={i18n.translate('xpack.fileUpload.importComplete.uploadSuccessWithFailuresTitle', {
defaultMessage: 'File upload complete with failures',
})}
color="warning"
iconType="help"
data-test-subj={STATUS_CALLOUT_DATA_TEST_SUBJ}
>
<p>
{getPartialImportMessage(
this.props.importResults.failures!.length,
this.props.importResults.docCount
)}
</p>
</EuiCallOut>
);
}

return (
<EuiCallOut
Expand All @@ -179,7 +184,14 @@ export class ImportCompleteView extends Component<Props, {}> {
})}
data-test-subj={STATUS_CALLOUT_DATA_TEST_SUBJ}
>
<p>{`${successMsg} ${failedFeaturesMsg}`}</p>
<p>
{i18n.translate('xpack.fileUpload.importComplete.uploadSuccessMsg', {
defaultMessage: 'Indexed {numFeatures} features.',
values: {
numFeatures: this.props.importResults.docCount,
},
})}
</p>
</EuiCallOut>
);
}
Expand Down
27 changes: 27 additions & 0 deletions x-pack/plugins/file_upload/public/components/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* 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 { i18n } from '@kbn/i18n';

export function getPartialImportMessage(failedFeaturesCount: number, totalFeaturesCount?: number) {
const outOfTotalMsg =
typeof totalFeaturesCount === 'number'
? i18n.translate('xpack.fileUpload.geoUploadWizard.outOfTotalMsg', {
defaultMessage: 'of {totalFeaturesCount}',
values: {
totalFeaturesCount,
},
})
: '';
return i18n.translate('xpack.fileUpload.geoUploadWizard.partialImportMsg', {
defaultMessage: 'Unable to index {failedFeaturesCount} {outOfTotalMsg} features.',
values: {
failedFeaturesCount,
outOfTotalMsg,
},
});
}
1 change: 0 additions & 1 deletion x-pack/plugins/translations/translations/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -13244,7 +13244,6 @@
"xpack.fileUpload.geoUploadWizard.creatingDataView": "Création de la vue de données : {indexName}",
"xpack.fileUpload.geoUploadWizard.dataIndexingStarted": "Création de l'index : {indexName}",
"xpack.fileUpload.geoUploadWizard.writingToIndex": "Écriture dans l'index : {progress} % terminé",
"xpack.fileUpload.importComplete.failedFeaturesMsg": "Impossible d'indexer {numFailures} fonctionnalités.",
"xpack.fileUpload.importComplete.permissionFailureMsg": "Vous ne disposez pas d'autorisation pour créer ni importer des données dans l'index \"{indexName}\".",
"xpack.fileUpload.importComplete.uploadFailureMsgErrorBlock": "Erreur : {reason}",
"xpack.fileUpload.importComplete.uploadSuccessMsg": "{numFeatures} fonctionnalités indexées.",
Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/translations/translations/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -13231,7 +13231,6 @@
"xpack.fileUpload.geoUploadWizard.creatingDataView": "データビュー{indexName}を作成しています",
"xpack.fileUpload.geoUploadWizard.dataIndexingStarted": "インデックスを作成中:{indexName}",
"xpack.fileUpload.geoUploadWizard.writingToIndex": "インデックスに書き込み中:{progress}%完了",
"xpack.fileUpload.importComplete.failedFeaturesMsg": "{numFailures}個の特長量にインデックスを作成できませんでした。",
"xpack.fileUpload.importComplete.permissionFailureMsg": "インデックス\"{indexName}\"にデータを作成またはインポートするアクセス権がありません。",
"xpack.fileUpload.importComplete.uploadFailureMsgErrorBlock": "エラー:{reason}",
"xpack.fileUpload.importComplete.uploadSuccessMsg": "{numFeatures}個の特徴量にインデックスを作成しました。",
Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/translations/translations/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -13248,7 +13248,6 @@
"xpack.fileUpload.geoUploadWizard.creatingDataView": "正在创建数据视图:{indexName}",
"xpack.fileUpload.geoUploadWizard.dataIndexingStarted": "正在创建索引:{indexName}",
"xpack.fileUpload.geoUploadWizard.writingToIndex": "正在写入索引:已完成 {progress}%",
"xpack.fileUpload.importComplete.failedFeaturesMsg": "无法索引 {numFailures} 个特征。",
"xpack.fileUpload.importComplete.permissionFailureMsg": "您无权创建或将数据导入索引“{indexName}”。",
"xpack.fileUpload.importComplete.uploadFailureMsgErrorBlock": "错误:{reason}",
"xpack.fileUpload.importComplete.uploadSuccessMsg": "已索引 {numFeatures} 个特征。",
Expand Down

0 comments on commit 0e9d9c8

Please sign in to comment.