Skip to content

Commit

Permalink
Support MDS on workflows and workflow_detail pages (#274) (#276)
Browse files Browse the repository at this point in the history
* Added MDS support

Signed-off-by: saimedhi <[email protected]>

* Added MDS support, Fixed failing tests

Signed-off-by: saimedhi <[email protected]>

* Fixing MDS Support

Signed-off-by: saimedhi <[email protected]>

* Fixing MDS Support

Signed-off-by: saimedhi <[email protected]>

* Fixing MDS Support

Signed-off-by: saimedhi <[email protected]>

* Fixing MDS Support

Signed-off-by: saimedhi <[email protected]>

* Fixing MDS Support

Signed-off-by: saimedhi <[email protected]>

* Fixing MDS Support

Signed-off-by: saimedhi <[email protected]>

* Fixing MDS Support

Signed-off-by: saimedhi <[email protected]>

* Fixing MDS Support

Signed-off-by: saimedhi <[email protected]>

* Fixing MDS Support

Signed-off-by: saimedhi <[email protected]>

* Fixing MDS Support

Signed-off-by: saimedhi <[email protected]>

---------

Signed-off-by: saimedhi <[email protected]>
Signed-off-by: Sai Medhini Reddy Maryada <[email protected]>
(cherry picked from commit c8bc682)

Co-authored-by: Sai Medhini Reddy Maryada <[email protected]>
  • Loading branch information
opensearch-trigger-bot[bot] and saimedhi committed Aug 12, 2024
1 parent 57a86b8 commit e424be1
Show file tree
Hide file tree
Showing 31 changed files with 1,327 additions and 333 deletions.
3 changes: 3 additions & 0 deletions common/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ export type Index = {
/**
********** WORKFLOW TYPES/INTERFACES **********
*/
export type MDSQueryParams = {
dataSourceId?: string;
};

export type ConfigFieldType =
| 'string'
Expand Down
15 changes: 15 additions & 0 deletions common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,22 @@

import moment from 'moment';
import { DATE_FORMAT_PATTERN } from './';
import { isEmpty } from 'lodash';

export function toFormattedDate(timestampMillis: number): String {
return moment(new Date(timestampMillis)).format(DATE_FORMAT_PATTERN);
}

const PERMISSIONS_ERROR_PATTERN = /no permissions for \[(.+)\] and User \[name=(.+), backend_roles/;

export const prettifyErrorMessage = (rawErrorMessage: string) => {
if (isEmpty(rawErrorMessage) || rawErrorMessage === 'undefined') {
return 'Unknown error is returned.';
}
const match = rawErrorMessage.match(PERMISSIONS_ERROR_PATTERN);
if (isEmpty(match)) {
return rawErrorMessage;
} else {
return `User ${match[2]} has no permissions to [${match[1]}].`;
}
};
2 changes: 1 addition & 1 deletion opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
"navigation",
"opensearchDashboardsUtils"
],
"optionalPlugins": []
"optionalPlugins": ["dataSource","dataSourceManagement"]
}
41 changes: 35 additions & 6 deletions public/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
*/

import React from 'react';
import { Route, RouteComponentProps, Switch } from 'react-router-dom';
import {
Route,
RouteComponentProps,
Switch,
useLocation,
} from 'react-router-dom';
import {
EuiPageSideBar,
EuiSideNav,
Expand All @@ -18,13 +23,24 @@ import {
WorkflowDetailRouterProps,
WorkflowsRouterProps,
} from './pages';
import { MountPoint } from '../../../src/core/public';
import {
constructHrefWithDataSourceId,
getDataSourceFromURL,
} from './utils/utils';

// styling
import './global-styles.scss';

interface Props extends RouteComponentProps {}
interface Props extends RouteComponentProps {
setHeaderActionMenu: (menuMount?: MountPoint) => void;
}

export const FlowFrameworkDashboardsApp = (props: Props) => {
const { setHeaderActionMenu } = props;
const location = useLocation();
const queryParams = getDataSourceFromURL(location);
const dataSourceId = queryParams.dataSourceId;
const sidebar = (
<EuiPageSideBar style={{ minWidth: 190 }} hidden={false} paddingSize="l">
<EuiSideNav
Expand All @@ -37,7 +53,10 @@ export const FlowFrameworkDashboardsApp = (props: Props) => {
{
name: Navigation.Workflows,
id: 1,
href: `#${APP_PATH.WORKFLOWS}`,
href: constructHrefWithDataSourceId(
APP_PATH.WORKFLOWS,
dataSourceId
),
isSelected: props.location.pathname === APP_PATH.WORKFLOWS,
},
],
Expand All @@ -61,12 +80,17 @@ export const FlowFrameworkDashboardsApp = (props: Props) => {
path={APP_PATH.WORKFLOW_DETAIL}
render={(
routeProps: RouteComponentProps<WorkflowDetailRouterProps>
) => <WorkflowDetail {...routeProps} />}
) => (
<WorkflowDetail
setActionMenu={setHeaderActionMenu}
{...routeProps}
/>
)}
/>
<Route
path={APP_PATH.WORKFLOWS}
render={(routeProps: RouteComponentProps<WorkflowsRouterProps>) => (
<Workflows {...routeProps} />
<Workflows setActionMenu={setHeaderActionMenu} {...routeProps} />
)}
/>
{/*
Expand All @@ -82,7 +106,12 @@ export const FlowFrameworkDashboardsApp = (props: Props) => {
pathname: APP_PATH.WORKFLOWS,
});
}
return <Workflows {...routeProps} />;
return (
<Workflows
setActionMenu={setHeaderActionMenu}
{...routeProps}
/>
);
}}
/>
</Switch>
Expand Down
63 changes: 53 additions & 10 deletions public/pages/workflow_detail/workflow_detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React, { useEffect } from 'react';
import React, { useEffect, ReactElement } from 'react';
import { RouteComponentProps } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { ReactFlowProvider } from 'reactflow';
Expand All @@ -22,17 +22,30 @@ import {
DEFAULT_NEW_WORKFLOW_NAME,
FETCH_ALL_QUERY_BODY,
} from '../../../common';
import { MountPoint } from '../../../../../src/core/public';

// styling
import './workflow-detail-styles.scss';
import '../../global-styles.scss';

import { getDataSourceId } from '../../utils/utils';

import {
getDataSourceManagementPlugin,
getDataSourceEnabled,
getNotifications,
getSavedObjectsClient,
} from '../../services';
import { DataSourceViewConfig } from '../../../../../src/plugins/data_source_management/public';

export interface WorkflowDetailRouterProps {
workflowId: string;
}

interface WorkflowDetailProps
extends RouteComponentProps<WorkflowDetailRouterProps> {}
extends RouteComponentProps<WorkflowDetailRouterProps> {
setActionMenu: (menuMount?: MountPoint) => void;
}

/**
* The workflow details page. This is where users will configure, create, and
Expand All @@ -42,6 +55,8 @@ interface WorkflowDetailProps

export function WorkflowDetail(props: WorkflowDetailProps) {
const dispatch = useAppDispatch();
const dataSourceEnabled = getDataSourceEnabled().enabled;
const dataSourceId = getDataSourceId();
const { workflows } = useSelector((state: AppState) => state.workflows);

// selected workflow state
Expand All @@ -50,23 +65,51 @@ export function WorkflowDetail(props: WorkflowDetailProps) {
const workflowName = workflow ? workflow.name : DEFAULT_NEW_WORKFLOW_NAME;

useEffect(() => {
getCore().chrome.setBreadcrumbs([
BREADCRUMBS.FLOW_FRAMEWORK,
BREADCRUMBS.WORKFLOWS,
{ text: workflowName },
]);
});
if (dataSourceEnabled) {
getCore().chrome.setBreadcrumbs([
BREADCRUMBS.FLOW_FRAMEWORK,
BREADCRUMBS.WORKFLOWS(dataSourceId),
{ text: workflowName },
]);
} else {
getCore().chrome.setBreadcrumbs([
BREADCRUMBS.FLOW_FRAMEWORK,
BREADCRUMBS.WORKFLOWS(),
{ text: workflowName },
]);
}
}, []);

// On initial load:
// - fetch workflow
// - fetch available models as their IDs may be used when building flows
useEffect(() => {
dispatch(getWorkflow(workflowId));
dispatch(searchModels(FETCH_ALL_QUERY_BODY));
dispatch(getWorkflow({ workflowId, dataSourceId }));
dispatch(searchModels({ apiBody: FETCH_ALL_QUERY_BODY, dataSourceId }));
}, []);

let renderDataSourceComponent: ReactElement | null = null;
if (dataSourceEnabled && getDataSourceManagementPlugin()) {
const DataSourceMenu = getDataSourceManagementPlugin().ui.getDataSourceMenu<
DataSourceViewConfig
>();
renderDataSourceComponent = (
<DataSourceMenu
setMenuMountPoint={props.setActionMenu}
componentType={'DataSourceView'}
componentConfig={{
activeOption: [{ id: dataSourceId }],
fullWidth: false,
savedObjects: getSavedObjectsClient(),
notifications: getNotifications(),
}}
/>
);
}

return (
<ReactFlowProvider>
{dataSourceEnabled && renderDataSourceComponent}
<EuiPage>
<EuiPageBody className="workflow-detail stretch-relative">
<WorkflowDetailHeader workflow={workflow} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
useAppDispatch,
} from '../../../../store';
import { getCore } from '../../../../services';
import { getDataSourceId } from '../../../../utils/utils';
import { MapArrayField } from '../input_fields';

interface InputTransformModalProps {
Expand All @@ -68,6 +69,7 @@ interface InputTransformModalProps {
*/
export function InputTransformModal(props: InputTransformModalProps) {
const dispatch = useAppDispatch();
const dataSourceId = getDataSourceId();
const { values } = useFormikContext<WorkflowFormValues>();

// source input / transformed output state
Expand Down Expand Up @@ -120,8 +122,11 @@ export function InputTransformModal(props: InputTransformModalProps) {
);
await dispatch(
simulatePipeline({
pipeline: curIngestPipeline as IngestPipelineConfig,
docs: curDocs,
apiBody: {
pipeline: curIngestPipeline as IngestPipelineConfig,
docs: curDocs,
},
dataSourceId,
})
)
.unwrap()
Expand Down Expand Up @@ -169,11 +174,14 @@ export function InputTransformModal(props: InputTransformModalProps) {
// the partial search pipeline (inline) to get the latest transformed version of the response.
dispatch(
searchIndex({
index: values.ingest.index.name,
body: JSON.stringify({
...JSON.parse(values.search.request as string),
search_pipeline: curSearchPipeline,
}),
apiBody: {
index: values.ingest.index.name,
body: JSON.stringify({
...JSON.parse(values.search.request as string),
search_pipeline: curSearchPipeline,
}),
},
dataSourceId,
})
)
.unwrap()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
} from '../../../../store';
import { getCore } from '../../../../services';
import { MapArrayField } from '../input_fields';
import { getDataSourceId } from '../../../../utils/utils';

interface OutputTransformModalProps {
uiConfig: WorkflowConfig;
Expand All @@ -65,6 +66,7 @@ interface OutputTransformModalProps {
*/
export function OutputTransformModal(props: OutputTransformModalProps) {
const dispatch = useAppDispatch();
const dataSourceId = getDataSourceId();
const { values } = useFormikContext<WorkflowFormValues>();

// source input / transformed output state
Expand Down Expand Up @@ -124,8 +126,11 @@ export function OutputTransformModal(props: OutputTransformModalProps) {
);
await dispatch(
simulatePipeline({
pipeline: curIngestPipeline,
docs: curDocs,
apiBody: {
pipeline: curIngestPipeline,
docs: curDocs,
},
dataSourceId,
})
)
.unwrap()
Expand Down Expand Up @@ -162,11 +167,14 @@ export function OutputTransformModal(props: OutputTransformModalProps) {
// version of the request.
dispatch(
searchIndex({
index: values.ingest.index.name,
body: JSON.stringify({
...JSON.parse(values.search.request as string),
search_pipeline: curSearchPipeline,
}),
apiBody: {
index: values.ingest.index.name,
body: JSON.stringify({
...JSON.parse(values.search.request as string),
search_pipeline: curSearchPipeline,
}),
},
dataSourceId,
})
)
.unwrap()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
searchIndex,
useAppDispatch,
} from '../../../../store';
import { getDataSourceId } from '../../../../utils/utils';

interface ConfigureSearchRequestProps {
setQuery: (query: string) => void;
Expand All @@ -42,6 +43,7 @@ interface ConfigureSearchRequestProps {
*/
export function ConfigureSearchRequest(props: ConfigureSearchRequestProps) {
const dispatch = useAppDispatch();
const dataSourceId = getDataSourceId();

// Form state
const { values, setFieldValue, setFieldTouched } = useFormikContext<
Expand Down Expand Up @@ -80,7 +82,7 @@ export function ConfigureSearchRequest(props: ConfigureSearchRequestProps) {
useEffect(() => {
if (!ingestEnabled) {
// Fetch all indices besides system indices
dispatch(catIndices('*,-.*'));
dispatch(catIndices({ pattern: '*,-.*', dataSourceId }));
}
}, []);

Expand Down Expand Up @@ -177,9 +179,12 @@ export function ConfigureSearchRequest(props: ConfigureSearchRequestProps) {
// see https://opensearch.org/docs/latest/search-plugins/search-pipelines/using-search-pipeline/#disabling-the-default-pipeline-for-a-request
dispatch(
searchIndex({
index: values.search.index.name,
body: values.search.request,
searchPipeline: '_none',
apiBody: {
index: values.search.index.name,
body: values.search.request,
searchPipeline: '_none',
},
dataSourceId,
})
)
.unwrap()
Expand Down
Loading

0 comments on commit e424be1

Please sign in to comment.