Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discover Changes for Point in Time POC #4

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
8 changes: 4 additions & 4 deletions config/opensearch_dashboards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,9 @@

# Set the value of this setting to true to enables the experimental multiple data source
# support feature. Use with caution.
#data_source.enabled: false
data_source.enabled: true
# Set the value of these settings to custermize crypto materials to encryption saved credentials
# in data sources.
#data_source.encryption.wrappingKeyName: 'changeme'
#data_source.encryption.wrappingKeyNamespace: 'changeme'
#data_source.encryption.wrappingKey: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
data_source.encryption.wrappingKeyName: 'changeme'
data_source.encryption.wrappingKeyNamespace: 'changeme'
data_source.encryption.wrappingKey: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
"@hapi/podium": "^4.1.3",
"@hapi/vision": "^6.1.0",
"@hapi/wreck": "^17.1.0",
"@opensearch-dashboards-test/opensearch-dashboards-test-library": "^1.0.3",
"@opensearch-project/opensearch": "^1.1.0",
"@osd/ace": "1.0.0",
"@osd/analytics": "1.0.0",
Expand All @@ -151,6 +152,7 @@
"angular-elastic": "^2.5.1",
"angular-sanitize": "^1.8.0",
"bluebird": "3.5.5",
"caniuse-lite": "^1.0.30001397",
"chalk": "^4.1.0",
"chokidar": "^3.4.2",
"color": "1.0.3",
Expand Down Expand Up @@ -212,6 +214,7 @@
"type-detect": "^4.0.8",
"uuid": "3.3.2",
"whatwg-fetch": "^3.0.0",
"yarn": "^1.22.19",
"yauzl": "^2.10.0"
},
"devDependencies": {
Expand Down Expand Up @@ -461,4 +464,4 @@
"node": "14.20.0",
"yarn": "^1.21.1"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ export function getSearchParamsFromRequest(
const { getConfig } = dependencies;
const searchParams = getSearchParams(getConfig);

if (searchRequest.body.pit) {
delete searchParams.preference;
return {
body: searchRequest.body, ...searchParams,
};
}
return {
index: searchRequest.index.title || searchRequest.index,
body: searchRequest.body,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
* under the License.
*/

import { GetFieldsOptions, IIndexPatternsApiClient } from '../../common/index_patterns/types';
import { GetFieldsOptions, IIndexPatternsApiClient } from '../../common';

export class IndexPatternsApiServer implements IIndexPatternsApiClient {
async getFieldsForTimePattern(options: GetFieldsOptions = {}) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export async function getDefaultSearchParams(uiSettingsClient: IUiSettingsClient
maxConcurrentShardRequests:
maxConcurrentShardRequests > 0 ? maxConcurrentShardRequests : undefined,
ignoreThrottled,
ignoreUnavailable: true, // Don't fail if the index/indices don't exist
ignoreUnavailable: false, // Don't fail if the index/indices don't exist
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to make a different function to be called for fetching the default params for PIT searches.

trackTotalHits: true,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,14 @@ export const opensearchSearchStrategyProvider = (

// ignoreThrottled is not supported in OSS
const { ignoreThrottled, ...defaultParams } = await getDefaultSearchParams(uiSettingsClient);

const params = toSnakeCase({
...defaultParams,
...getShardTimeout(config),
...request.params,
});

if (params.body.pit) {
Copy link
Owner Author

@Arpit-Bandejiya Arpit-Bandejiya Oct 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need to make changes in the search strategy as well since there are some fields which can't be passed in PIT search.

delete params.ignore_unavailable;
}
try {
const client = await decideClient(context, request);
const promise = shimAbortSignal(client.search(params), options?.abortSignal);
Expand Down
185 changes: 147 additions & 38 deletions src/plugins/discover/public/application/angular/discover.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import dateMath from '@elastic/datemath';
import { i18n } from '@osd/i18n';
import { getState, splitState } from './discover_state';

import { RequestAdapter } from '../../../../inspector/public';
import { RequestAdapter } from '../../../../inspector';
import {
opensearchFilters,
indexPatterns as indexPatternsUtils,
Expand Down Expand Up @@ -77,6 +77,7 @@ const {
toastNotifications,
uiSettings: config,
visualizations,
savedObjectsClient,
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need savedObjectClient to fetch the PIT saved object. Since we already have the necessary dependencies in the plugin. We have imported it in the discover page

} = getServices();

import { getRootBreadcrumbs, getSavedSearchBreadcrumbs } from '../helpers/breadcrumbs';
Expand All @@ -102,6 +103,33 @@ const fetchStatuses = {

const app = getAngularModule();

export async function getpits(savedObjectsClient) {

This comment was marked as resolved.

return (
savedObjectsClient
.find({
type: 'point-in-time',
perPage: 10000,
})
.then((response) =>
response.savedObjects
.map((pattern) => {
return {
...pattern,
};
})
.sort((a, b) => {
if (a.sort < b.sort) {
return -1;
} else if (a.sort > b.sort) {
return 1;
} else {
return 0;
}
})
) || []
);
}

app.config(($routeProvider) => {
const defaults = {
requireDefaultIndex: true,
Expand Down Expand Up @@ -129,14 +157,14 @@ app.config(($routeProvider) => {
template: indexTemplateLegacy,
reloadOnSearch: false,
resolve: {
savedObjects: function ($route, Promise) {
savedObjects: async function ($route, Promise) {
const history = getHistory();
const savedSearchId = $route.current.params.id;
return data.indexPatterns.ensureDefaultIndexPattern(history).then(() => {
return await data.indexPatterns.ensureDefaultIndexPattern(history).then(async () => {
const { appStateContainer } = getState({ history });
const { index } = appStateContainer.getState();
return Promise.props({
ip: indexPatterns.getCache().then((indexPatternList) => {
const { index, pitid } = appStateContainer.getState();
return await Promise.props({
ip: await indexPatterns.getCache().then(async (indexPatternList) => {
/**
* In making the indexPattern modifiable it was placed in appState. Unfortunately,
* the load order of AppState conflicts with the load order of many other things
Expand All @@ -154,16 +182,22 @@ app.config(($routeProvider) => {
stateValFound: !!index && id === index,
});
}),
savedSearch: getServices()
pit: await Promise.props({
list: await getpits(savedObjectsClient, history),
pitid: pitid,
}),
savedSearch: await getServices()
.getSavedSearchById(savedSearchId)
.then((savedSearch) => {
// console.log("Invoking this to make a internal call");
if (savedSearchId) {
chrome.recentlyAccessed.add(
savedSearch.getFullPath(),
savedSearch.title,
savedSearchId
);
}
console.log(savedSearch);
return savedSearch;
})
.catch(
Expand Down Expand Up @@ -208,7 +242,10 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
let inspectorRequest;
const savedSearch = $route.current.locals.savedObjects.savedSearch;
$scope.searchSource = savedSearch.searchSource;
// console.log("This is the search store",$scope.searchSource);
$scope.indexPattern = resolveIndexPatternLoading();
$scope.selectedPointInTime = $route.current.locals.savedObjects.pit.pitid || undefined;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is no pitid in the state, make it undefined

// console.log($scope.indexPattern);
//used for functional testing
$scope.fetchCounter = 0;

Expand Down Expand Up @@ -249,7 +286,6 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
// sync initial app filters from state to filterManager
filterManager.setAppFilters(_.cloneDeep(appStateContainer.getState().filters));
data.query.queryString.setQuery(appStateContainer.getState().query);

const stopSyncingQueryAppStateWithStateContainer = connectToQueryState(
data.query,
appStateContainer,
Expand Down Expand Up @@ -294,20 +330,49 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
});

$scope.setIndexPattern = async (id) => {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore this function since the same legacy code.

const nextIndexPattern = await indexPatterns.get(id);
if (nextIndexPattern) {
const nextAppState = getSwitchIndexPatternAppState(
$scope.indexPattern,
nextIndexPattern,
$scope.state.columns,
$scope.state.sort,
config.get(MODIFY_COLUMNS_ON_SWITCH)
);
await replaceUrlAppState(nextAppState);
$route.reload();
try {
const nextIndexPattern = await indexPatterns.get(id);
if (nextIndexPattern) {
const nextAppState = getSwitchIndexPatternAppState(
$scope.indexPattern,
nextIndexPattern,
$scope.state.columns,
$scope.state.sort,
config.get(MODIFY_COLUMNS_ON_SWITCH)
);
await replaceUrlAppState(nextAppState);
$route.reload();
}
} catch (e) {
const nextIndexPattern = await indexPatterns.get(id);
if (nextIndexPattern) {
const nextAppState = getSwitchIndexPatternAppState(
$scope.indexPattern,
nextIndexPattern,
$scope.state.columns,
$scope.state.sort,
config.get(MODIFY_COLUMNS_ON_SWITCH)
);
await replaceUrlAppState(nextAppState);
$route.reload();
}
};
}

$scope.setPointInTime = async (id) => {
console.log('This is teh pit list', $route.current.locals.savedObjects.pit.list);
const pitList = await $route.current.locals.savedObjects.pit.list;
const nextPit = pitList.find((pit) => pit.id === id);
console.log(nextPit);
const nextAppState = getSwitchIndexPatternAppState(
$scope.indexPattern,
nextPit,
$scope.state.columns,
$scope.state.sort,
config.get(MODIFY_COLUMNS_ON_SWITCH)
);
await replaceUrlAppState(nextAppState);
await $route.reload();
};
// update data source when filters update
subscriptions.add(
subscribeWithScope(
Expand Down Expand Up @@ -613,6 +678,7 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
? savedSearch.columns
: config.get(DEFAULT_COLUMNS_SETTING).slice(),
index: $scope.indexPattern.id,
pit: $scope.selectedPointInTime,
interval: 'auto',
filters: _.cloneDeep($scope.searchSource.getOwnField('filter')),
};
Expand All @@ -627,6 +693,7 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
timefield: getTimeField(),
savedSearch: savedSearch,
indexPatternList: $route.current.locals.savedObjects.ip.list,
pointInTimeList: $route.current.locals.savedObjects.pit.list,
config: config,
fixedScroll: createFixedScroll($scope, $timeout),
setHeaderActionMenu: getHeaderActionMenuMounter(),
Expand Down Expand Up @@ -804,27 +871,66 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
// Abort any in-progress requests before fetching again
if (abortController) abortController.abort();
abortController = new AbortController();
// if selected Point in time is not null that means the user has selected a PIT saved object
if ($scope.selectedPointInTime != null) {
$scope
.updateDataSource()
.then(setupVisualization)
.then(async function () {
$scope.fetchStatus = fetchStatuses.LOADING;
logInspectorRequest();
// eslint-disable-next-line camelcase
// Since search source does not support pit, this is an work around to make the fetch call
const search_source_local = _.cloneDeep($scope.searchSource);
// search_source_local = $scope.searchSource;
console.log('This is the local search source');
const pit_object = {
pit: {
id: $scope.selectedPointInTime,
keep_alive: '1m',
},
};
const pit_json = JSON.parse(JSON.stringify(pit_object));
// searchRequest.params.body = { ...searchRequest.params.body, ...pit_json };
search_source_local.fields = { ...search_source_local.fields, ...pit_json };
delete search_source_local.fields.index;
return await search_source_local.fetch({
abortSignal: abortController.signal,
});
})
.then(onResults)
.catch((error) => {
// If the request was aborted then no need to surface this error in the UI
if (error instanceof Error && error.name === 'AbortError') return;

$scope
.updateDataSource()
.then(setupVisualization)
.then(function () {
$scope.fetchStatus = fetchStatuses.LOADING;
logInspectorRequest();
return $scope.searchSource.fetch({
abortSignal: abortController.signal,
$scope.fetchStatus = fetchStatuses.NO_RESULTS;
$scope.rows = [];

data.search.showError(error);
});
})
.then(onResults)
.catch((error) => {
// If the request was aborted then no need to surface this error in the UI
if (error instanceof Error && error.name === 'AbortError') return;
} else {
// this is the default call for fetching the index pattern results
$scope
.updateDataSource()
.then(setupVisualization)
.then(async function () {
$scope.fetchStatus = fetchStatuses.LOADING;
logInspectorRequest();
return await $scope.searchSource.fetch({
abortSignal: abortController.signal,
});
})
.then(onResults)
.catch((error) => {
// If the request was aborted then no need to surface this error in the UI
if (error instanceof Error && error.name === 'AbortError') return;

$scope.fetchStatus = fetchStatuses.NO_RESULTS;
$scope.rows = [];
$scope.fetchStatus = fetchStatuses.NO_RESULTS;
$scope.rows = [];

data.search.showError(error);
});
data.search.showError(error);
});
}
};

$scope.handleRefresh = function (_payload, isUpdate) {
Expand Down Expand Up @@ -876,6 +982,7 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
}

function onResults(resp) {
console.log('response after fetching the results', resp);
inspectorRequest.stats(getResponseInspectorStats(resp, $scope.searchSource)).ok({ json: resp });

if (getTimeField()) {
Expand All @@ -890,7 +997,9 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise

$scope.hits = resp.hits.total;
$scope.rows = resp.hits.hits;

debugger;
console.log($scope.hits);
console.log($scope.rows);
// if we haven't counted yet, reset the counts
const counts = ($scope.fieldCounts = $scope.fieldCounts || {});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
saved-search="savedSearch"
search-source="searchSource"
set-index-pattern="setIndexPattern"
set-point-in-time="setPointInTime"
selected-point-in-time = "selectedPointInTime"
show-save-query="showSaveQuery"
state="state"
time-filter-update-handler="timefilterUpdateHandler"
Expand Down
Loading