Fix index pattern create with cross cluster search _and_ partial results (#94664) (#94818)

* fix index pattern create with cross cluster  and partial results and update tests

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Matthew Kime 2021-03-17 22:27:06 -05:00 committed by GitHub
parent b714b332fe
commit a576e2a0dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 81 additions and 9 deletions

View file

@ -7,5 +7,5 @@
<b>Signature:</b>
```typescript
isErrorResponse: (response?: IKibanaSearchResponse<any> | undefined) => boolean | undefined
isErrorResponse: (response?: IKibanaSearchResponse<any> | undefined) => boolean
```

View file

@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [QueryStringInputProps](./kibana-plugin-plugins-data-public.querystringinputprops.md) &gt; [submitOnBlur](./kibana-plugin-plugins-data-public.querystringinputprops.submitonblur.md)
## QueryStringInputProps.submitOnBlur property
<b>Signature:</b>
```typescript
submitOnBlur?: boolean;
```

View file

@ -12,7 +12,7 @@ import type { IKibanaSearchResponse } from './types';
* @returns true if response had an error while executing in ES
*/
export const isErrorResponse = (response?: IKibanaSearchResponse) => {
return !response || (!response.isRunning && response.isPartial);
return !response || (!response.isRunning && !!response.isPartial);
};
/**

View file

@ -1702,7 +1702,7 @@ export interface ISearchStartSearchSource {
// Warning: (ae-missing-release-tag) "isErrorResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const isErrorResponse: (response?: IKibanaSearchResponse<any> | undefined) => boolean | undefined;
export const isErrorResponse: (response?: IKibanaSearchResponse<any> | undefined) => boolean;
// Warning: (ae-forgotten-export) The symbol "SessionsClient" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "ISessionsClient" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)

View file

@ -6,7 +6,12 @@
* Side Public License, v 1.
*/
import { getIndices, responseToItemArray, dedupeMatchedItems } from './get_indices';
import {
getIndices,
getIndicesViaSearch,
responseToItemArray,
dedupeMatchedItems,
} from './get_indices';
import { httpServiceMock } from '../../../../../../core/public/mocks';
import { ResolveIndexResponseItemIndexAttrs, MatchedItem } from '../types';
import { Observable } from 'rxjs';
@ -34,6 +39,8 @@ export const successfulResolveResponse = {
};
const successfulSearchResponse = {
isPartial: false,
isRunning: false,
rawResponse: {
aggregations: {
indices: {
@ -43,6 +50,22 @@ const successfulSearchResponse = {
},
};
const partialSearchResponse = {
isPartial: true,
isRunning: true,
rawResponse: {
hits: {
total: 2,
hits: [],
},
},
};
const errorSearchResponse = {
isPartial: true,
isRunning: false,
};
const getIndexTags = () => [];
const searchClient = () =>
new Observable((observer) => {
@ -93,6 +116,22 @@ describe('getIndices', () => {
).toBe(0);
});
it('should work with partial responses', async () => {
const searchClientPartialResponse = () =>
new Observable((observer) => {
observer.next(partialSearchResponse);
observer.next(successfulSearchResponse);
observer.complete();
}) as any;
const result = await getIndices({
http,
getIndexTags,
pattern: '*:kibana',
searchClient: searchClientPartialResponse,
});
expect(result.length).toBe(4);
});
it('response object to item array', () => {
const result = {
indices: [
@ -129,12 +168,27 @@ describe('getIndices', () => {
});
describe('errors', () => {
it('should handle errors gracefully', async () => {
it('should handle thrown errors gracefully', async () => {
http.get.mockImplementationOnce(() => {
throw new Error('Test error');
});
const result = await getIndices({ http, getIndexTags, pattern: 'kibana', searchClient });
expect(result.length).toBe(0);
});
it('getIndicesViaSearch should handle error responses gracefully', async () => {
const searchClientErrorResponse = () =>
new Observable((observer) => {
observer.next(errorSearchResponse);
observer.complete();
}) as any;
const result = await getIndicesViaSearch({
getIndexTags,
pattern: '*:kibana',
searchClient: searchClientErrorResponse,
showAllIndices: false,
});
expect(result.length).toBe(0);
});
});
});

View file

@ -9,10 +9,15 @@
import { sortBy } from 'lodash';
import { HttpStart } from 'kibana/public';
import { i18n } from '@kbn/i18n';
import { map, scan } from 'rxjs/operators';
import { map, filter } from 'rxjs/operators';
import { IndexPatternCreationConfig } from '../../../../../index_pattern_management/public';
import { MatchedItem, ResolveIndexResponse, ResolveIndexResponseItemIndexAttrs } from '../types';
import { DataPublicPluginStart, IEsSearchResponse } from '../../../../../data/public';
import {
DataPublicPluginStart,
IEsSearchResponse,
isErrorResponse,
isCompleteResponse,
} from '../../../../../data/public';
import { MAX_SEARCH_SIZE } from '../constants';
const aliasLabel = i18n.translate('indexPatternManagement.aliasLabel', { defaultMessage: 'Alias' });
@ -86,8 +91,10 @@ export const getIndicesViaSearch = async ({
},
},
})
.pipe(map(searchResponseToArray(getIndexTags, showAllIndices)))
.pipe(scan((accumulator = [], value) => accumulator.join(value)))
.pipe(
filter((resp) => isCompleteResponse(resp) || isErrorResponse(resp)),
map(searchResponseToArray(getIndexTags, showAllIndices))
)
.toPromise()
.catch(() => []);