From 1d392b3fffb1e4e500390ac2e7788a2038f64095 Mon Sep 17 00:00:00 2001 From: Prabhat Sharma Date: Thu, 28 Mar 2024 15:28:02 +0530 Subject: [PATCH] Added MDS for rollup --- .../containers/CreateRollup/CreateRollup.tsx | 16 +++-- .../CreateRollupForm/CreateRollupForm.tsx | 67 ++++++++++++++++++- public/pages/Main/Main.tsx | 5 ++ .../Rollups/containers/Rollups/Rollups.tsx | 32 ++++++--- public/services/RollupService.ts | 34 +++++----- server/plugin.ts | 4 +- server/routes/rollups.ts | 19 +++++- server/services/PolicyService.ts | 6 +- server/services/RollupService.ts | 32 ++++----- 9 files changed, 160 insertions(+), 55 deletions(-) diff --git a/public/pages/CreateRollup/containers/CreateRollup/CreateRollup.tsx b/public/pages/CreateRollup/containers/CreateRollup/CreateRollup.tsx index a28b4a519..1572e0e89 100644 --- a/public/pages/CreateRollup/containers/CreateRollup/CreateRollup.tsx +++ b/public/pages/CreateRollup/containers/CreateRollup/CreateRollup.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { ChangeEvent, Component } from "react"; +import React, { ChangeEvent, Component, useContext } from "react"; import { EuiSpacer, EuiTitle, EuiFlexGroup, EuiFlexItem, EuiComboBoxOptionOption } from "@elastic/eui"; import { RouteComponentProps } from "react-router-dom"; import { RollupService } from "../../../../services"; @@ -12,8 +12,10 @@ import RollupIndices from "../../components/RollupIndices"; import CreateRollupSteps from "../../components/CreateRollupSteps"; import IndexService from "../../../../services/IndexService"; import { IndexItem } from "../../../../../models/interfaces"; +import { DataSourceMenuContext, DataSourceMenuProperties } from "../../../../services/DataSourceMenuContext"; +import { useUpdateUrlWithDataSourceProperties } from "../../../../components/MDSEnabledComponent"; -interface CreateRollupProps extends RouteComponentProps { +interface CreateRollupProps extends RouteComponentProps, DataSourceMenuProperties { rollupService: RollupService; indexService: IndexService; rollupId: string; @@ -34,7 +36,7 @@ interface CreateRollupProps extends RouteComponentProps { hasAggregation: boolean; } -export default class CreateRollup extends Component { +export class CreateRollup extends Component { render() { if (this.props.currentStep !== 1) { return null; @@ -53,7 +55,7 @@ export default class CreateRollup extends Component { - + @@ -61,3 +63,9 @@ export default class CreateRollup extends Component { ); } } + +export default function (props: CreateRollupProps) { + const dataSourceMenuProperties = useContext(DataSourceMenuContext); + useUpdateUrlWithDataSourceProperties(); + return ; +} diff --git a/public/pages/CreateRollup/containers/CreateRollupForm/CreateRollupForm.tsx b/public/pages/CreateRollup/containers/CreateRollupForm/CreateRollupForm.tsx index 85ce8d1b1..bf743f838 100644 --- a/public/pages/CreateRollup/containers/CreateRollupForm/CreateRollupForm.tsx +++ b/public/pages/CreateRollup/containers/CreateRollupForm/CreateRollupForm.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { ChangeEvent, Component } from "react"; +import React, { ChangeEvent, Component, useContext } from "react"; import { EuiButton, EuiButtonEmpty, EuiComboBoxOptionOption, EuiFlexGroup, EuiFlexItem } from "@elastic/eui"; import { RouteComponentProps } from "react-router-dom"; import moment from "moment"; @@ -21,8 +21,10 @@ import CreateRollupStep3 from "../CreateRollupStep3"; import CreateRollupStep4 from "../CreateRollupStep4"; import { compareFieldItem, parseFieldOptions } from "../../utils/helpers"; import { CoreServicesContext } from "../../../../components/core_services"; +import { DataSourceMenuContext, DataSourceMenuProperties } from "../../../../services/DataSourceMenuContext"; +import { useUpdateUrlWithDataSourceProperties } from "../../../../components/MDSEnabledComponent"; -interface CreateRollupFormProps extends RouteComponentProps { +interface CreateRollupFormProps extends RouteComponentProps, DataSourceMenuProperties { rollupService: RollupService; indexService: IndexService; } @@ -75,7 +77,7 @@ interface CreateRollupFormState { rollupJSON: any; } -export default class CreateRollupForm extends Component { +export class CreateRollupForm extends Component { static contextType = CoreServicesContext; _isMount: boolean; @@ -143,6 +145,59 @@ export default class CreateRollupForm extends Component) { + if (prevProps.dataSourceId != this.props.dataSourceId) { + // reset the state, if dataSourceId changes, i.e., clear state + this.setState({ + currentStep: 1, + rollupSeqNo: null, + rollupPrimaryTerm: null, + rollupId: "", + rollupIdError: "", + submitError: "", + isSubmitting: false, + hasSubmitted: false, + loadingIndices: true, + indices: [], + totalIndices: 0, + + mappings: "", + allMappings: [], + fields: [], + selectedFields: [], + selectedTerms: [], + selectedDimensionField: [], + selectedMetrics: [], + metricError: "", + + sourceIndex: [], + sourceIndexError: "", + targetIndex: [], + targetIndexError: "", + + timestamp: [], + timestampError: "", + intervalType: "fixed", + intervalValue: 1, + intervalError: "", + timezone: "UTC", + timeunit: "h", + + jobEnabledByDefault: true, + continuousJob: "no", + continuousDefinition: "fixed", + interval: 1, + intervalTimeunit: "MINUTES", + cronExpression: "", + cronTimezone: "UTC", + pageSize: 1000, + delayTime: undefined, + delayTimeunit: "MINUTES", + rollupJSON: JSON.parse(EMPTY_ROLLUP), + }); + } + } + getMappings = async (srcIndex: string): Promise => { if (!srcIndex.length) return; try { @@ -680,3 +735,9 @@ export default class CreateRollupForm extends Component) { + const dataSourceMenuProperties = useContext(DataSourceMenuContext); + useUpdateUrlWithDataSourceProperties(); + return ; +} diff --git a/public/pages/Main/Main.tsx b/public/pages/Main/Main.tsx index 5e82f30a1..dcbbd7ae1 100644 --- a/public/pages/Main/Main.tsx +++ b/public/pages/Main/Main.tsx @@ -157,6 +157,8 @@ const dataSourceEnabledPaths: string[] = [ ROUTES.COMPOSABLE_TEMPLATES, ROUTES.CREATE_COMPOSABLE_TEMPLATE, ROUTES.REINDEX, + ROUTES.ROLLUPS, + ROUTES.CREATE_ROLLUP, ]; export default class Main extends Component { @@ -212,6 +214,7 @@ export default class Main extends Component { services.managedIndexService = new ManagedIndexService(http, this.state.dataSourceId, this.props.multiDataSourceEnabled); services.policyService = new PolicyService(http, this.state.dataSourceId, this.props.multiDataSourceEnabled); services.notificationService = new NotificationService(http, this.state.dataSourceId, this.props.multiDataSourceEnabled); + services.rollupService = new RollupService(http, this.state.dataSourceId, this.props.multiDataSourceEnabled); } return services; } @@ -390,6 +393,8 @@ export default class Main extends Component { ROUTES.CREATE_POLICY, ROUTES.CHANGE_POLICY, ROUTES.TRANSFORMS, + ROUTES.ROLLUPS, + ROUTES.CREATE_ROLLUP, ]} render={() => ( { +export class Rollups extends MDSEnabledComponent { static contextType = CoreServicesContext; constructor(props: RollupsProps) { super(props); @@ -101,8 +104,16 @@ export default class Rollups extends Component { } } - static getQueryObjectFromState({ from, size, search, sortField, sortDirection }: RollupsState): RollupQueryParams { - return { from, size, search, sortField, sortDirection }; + static getQueryObjectFromState({ + from, + size, + search, + sortField, + sortDirection, + dataSourceId, + multiDataSourceEnabled, + }: RollupsState): RollupQueryParams { + return { from, size, search, sortField, sortDirection, ...(multiDataSourceEnabled ? { dataSourceId } : {}) }; } getRollups = async (): Promise => { @@ -110,9 +121,9 @@ export default class Rollups extends Component { try { const { rollupService, history } = this.props; const queryObject = Rollups.getQueryObjectFromState(this.state); - const queryParamsString = queryString.stringify(Rollups.getQueryObjectFromState(this.state)); + const queryParamsString = queryString.stringify({ ...queryObject, dataSourceLabel: this.state.dataSourceLabel }); history.replace({ ...this.props.location, search: queryParamsString }); - const rollupJobsResponse = await rollupService.getRollups(queryObject); + const rollupJobsResponse = await rollupService.getRollups(queryObject); // Add type assertion if (rollupJobsResponse.ok) { const { rollups, totalRollups, metadata } = rollupJobsResponse.response; this.setState({ rollups, totalRollups, rollupExplain: metadata }); @@ -480,3 +491,8 @@ export default class Rollups extends Component { ); } } + +export default function (props: Omit) { + const dataSourceMenuProps = useContext(DataSourceMenuContext); + return ; +} diff --git a/public/services/RollupService.ts b/public/services/RollupService.ts index a8c8f6605..a8ede7516 100644 --- a/public/services/RollupService.ts +++ b/public/services/RollupService.ts @@ -3,21 +3,17 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { HttpSetup } from "opensearch-dashboards/public"; +import { HttpFetchQuery, HttpSetup } from "opensearch-dashboards/public"; import { PutRollupResponse, GetRollupsResponse, GetFieldsResponse } from "../../server/models/interfaces"; import { ServerResponse } from "../../server/models/types"; import { NODE_API } from "../../utils/constants"; import { DocumentRollup, Rollup } from "../../models/interfaces"; +import { MDSEnabledClientService } from "./MDSEnabledClientService"; -export default class RollupService { - httpClient: HttpSetup; - - constructor(httpClient: HttpSetup) { - this.httpClient = httpClient; - } - - getRollups = async (queryObject: object): Promise> => { +export default class RollupService extends MDSEnabledClientService { + getRollups = async (queryObject?: HttpFetchQuery): Promise> => { let url = `..${NODE_API.ROLLUPS}`; + queryObject = this.patchQueryObjectWithDataSourceId(queryObject); const response = (await this.httpClient.get(url, { query: queryObject })) as ServerResponse; return response; }; @@ -29,7 +25,8 @@ export default class RollupService { primaryTerm?: number ): Promise> => { let url = `..${NODE_API.ROLLUPS}/${rollupId}`; - const response = (await this.httpClient.put(url, { query: { seqNo, primaryTerm }, body: JSON.stringify(rollup) })) as ServerResponse< + let queryObject = this.patchQueryObjectWithDataSourceId({ seqNo, primaryTerm }); + const response = (await this.httpClient.put(url, { query: queryObject, body: JSON.stringify(rollup) })) as ServerResponse< PutRollupResponse >; return response; @@ -37,25 +34,29 @@ export default class RollupService { getRollup = async (rollupId: string): Promise> => { const url = `..${NODE_API.ROLLUPS}/${rollupId}`; - const response = (await this.httpClient.get(url)) as ServerResponse; + const queryObject = this.patchQueryObjectWithDataSourceId(); + const response = (await this.httpClient.get(url, { query: queryObject })) as ServerResponse; return response; }; deleteRollup = async (rollupId: string): Promise> => { const url = `..${NODE_API.ROLLUPS}/${rollupId}`; - const response = (await this.httpClient.delete(url)) as ServerResponse; + const queryObject = this.patchQueryObjectWithDataSourceId(); + const response = (await this.httpClient.delete(url, { query: queryObject })) as ServerResponse; return response; }; startRollup = async (rollupId: string): Promise> => { const url = `..${NODE_API.ROLLUPS}/${rollupId}/_start`; - const response = (await this.httpClient.post(url)) as ServerResponse; + const queryObject = this.patchQueryObjectWithDataSourceId(); + const response = (await this.httpClient.post(url, { query: queryObject })) as ServerResponse; return response; }; stopRollup = async (rollupId: string): Promise> => { const url = `..${NODE_API.ROLLUPS}/${rollupId}/_stop`; - const response = (await this.httpClient.post(url)) as ServerResponse; + const queryObject = this.patchQueryObjectWithDataSourceId(); + const response = (await this.httpClient.post(url, { query: queryObject })) as ServerResponse; return response; }; @@ -63,7 +64,10 @@ export default class RollupService { getMappings = async (index: string): Promise> => { const url = `..${NODE_API._MAPPINGS}`; const body = { index: index }; - const response = (await this.httpClient.post(url, { body: JSON.stringify(body) })) as ServerResponse; + const queryObject = this.patchQueryObjectWithDataSourceId(); + const response = (await this.httpClient.post(url, { query: queryObject, body: JSON.stringify(body) })) as ServerResponse< + GetFieldsResponse + >; return response; }; } diff --git a/server/plugin.ts b/server/plugin.ts index 0e52f45df..38a536a13 100644 --- a/server/plugin.ts +++ b/server/plugin.ts @@ -52,7 +52,7 @@ export class IndexPatternManagementPlugin implements Plugin ({ + const policies: DocumentPolicy[] = getResponse.policies.map((p: any) => ({ seqNo: p._seq_no, primaryTerm: p._primary_term, id: p._id, diff --git a/server/services/RollupService.ts b/server/services/RollupService.ts index 6ba8a5cd9..e7f8a0014 100644 --- a/server/services/RollupService.ts +++ b/server/services/RollupService.ts @@ -5,7 +5,6 @@ import _ from "lodash"; import { - ILegacyCustomClusterClient, OpenSearchDashboardsRequest, OpenSearchDashboardsResponseFactory, IOpenSearchDashboardsResponse, @@ -15,14 +14,9 @@ import { import { DeleteRollupParams, DeleteRollupResponse, GetRollupsResponse, PutRollupParams, PutRollupResponse } from "../models/interfaces"; import { ServerResponse } from "../models/types"; import { DocumentRollup, Rollup } from "../../models/interfaces"; +import { MDSEnabledClientService } from "./MDSEnabledClientService"; -export default class RollupService { - osDriver: ILegacyCustomClusterClient; - - constructor(osDriver: ILegacyCustomClusterClient) { - this.osDriver = osDriver; - } - +export default class RollupService extends MDSEnabledClientService { /** * Calls backend Put Rollup API */ @@ -45,8 +39,8 @@ export default class RollupService { method = "ism.createRollup"; params = { rollupId: id, body: JSON.stringify(request.body) }; } - const { callAsCurrentUser: callWithRequest } = this.osDriver.asScoped(request); - const putRollupResponse: PutRollupResponse = await callWithRequest(method, params); + const callWithRequest = this.getClientBasedOnDataSource(context, request); + const putRollupResponse: PutRollupResponse = (await callWithRequest(method, params)) as PutRollupResponse; return response.custom({ statusCode: 200, body: { @@ -77,8 +71,8 @@ export default class RollupService { try { const { id } = request.params as { id: string }; const params: DeleteRollupParams = { rollupId: id }; - const { callAsCurrentUser: callWithRequest } = this.osDriver.asScoped(request); - const deleteRollupResponse: DeleteRollupResponse = await callWithRequest("ism.deleteRollup", params); + const callWithRequest = this.getClientBasedOnDataSource(context, request); + const deleteRollupResponse: DeleteRollupResponse = (await callWithRequest("ism.deleteRollup", params)) as DeleteRollupResponse; if (deleteRollupResponse.result !== "deleted") { return response.custom({ statusCode: 200, @@ -115,7 +109,7 @@ export default class RollupService { try { const { id } = request.params as { id: string }; const params = { rollupId: id }; - const { callAsCurrentUser: callWithRequest } = this.osDriver.asScoped(request); + const callWithRequest = this.getClientBasedOnDataSource(context, request); const startResponse = await callWithRequest("ism.startRollup", params); const acknowledged = _.get(startResponse, "acknowledged"); if (acknowledged) { @@ -146,7 +140,7 @@ export default class RollupService { try { const { id } = request.params as { id: string }; const params = { rollupId: id }; - const { callAsCurrentUser: callWithRequest } = this.osDriver.asScoped(request); + const callWithRequest = this.getClientBasedOnDataSource(context, request); const stopResponse = await callWithRequest("ism.stopRollup", params); const acknowledged = _.get(stopResponse, "acknowledged"); if (acknowledged) { @@ -180,7 +174,7 @@ export default class RollupService { try { const { id } = request.params as { id: string }; const params = { rollupId: id }; - const { callAsCurrentUser: callWithRequest } = this.osDriver.asScoped(request); + const callWithRequest = this.getClientBasedOnDataSource(context, request); const getResponse = await callWithRequest("ism.getRollup", params); const metadata = await callWithRequest("ism.explainRollup", params); const rollup = _.get(getResponse, "rollup", null); @@ -240,7 +234,7 @@ export default class RollupService { try { const { index } = request.body as { index: string }; const params = { index: index }; - const { callAsCurrentUser: callWithRequest } = this.osDriver.asScoped(request); + const callWithRequest = this.getClientBasedOnDataSource(context, request); const mappings = await callWithRequest("indices.getMapping", params); return response.custom({ statusCode: 200, @@ -292,8 +286,8 @@ export default class RollupService { sortDirection, }; - const { callAsCurrentUser: callWithRequest } = this.osDriver.asScoped(request); - const getRollupResponse = await callWithRequest("ism.getRollups", params); + const callWithRequest = this.getClientBasedOnDataSource(context, request); + const getRollupResponse: any = await callWithRequest("ism.getRollups", params); const totalRollups = getRollupResponse.total_rollups; const rollups = getRollupResponse.rollups.map((rollup: DocumentRollup) => ({ _seqNo: rollup._seqNo as number, @@ -307,7 +301,7 @@ export default class RollupService { if (totalRollups) { // Concat rollup job ids const ids = rollups.map((rollup: DocumentRollup) => rollup._id).join(","); - const explainResponse = await callWithRequest("ism.explainRollup", { rollupId: ids }); + const explainResponse: any = await callWithRequest("ism.explainRollup", { rollupId: ids }); if (!explainResponse.error) { rollups.map((rollup: DocumentRollup) => { rollup.metadata = explainResponse[rollup._id];