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

Support MDS on DetectorDetails page #719

Closed

Conversation

jackiehanyang
Copy link
Collaborator

@jackiehanyang jackiehanyang commented Apr 7, 2024

Description

This PR adds MDS support to the DetectorDetails page. The page's functionality and appearance remain the same, with the exception of the following changes:

  • a dataSourceId will be appended to the url for both /results, /historical, and /configurations tab
  • A read-only data source view will be rendered in the top right corner. Currently, it displays a placeholder label as the Neo team is implementing the feature to allow the data source view to take only a dataSourceId instead of requiring both an id and a label.

Please note:

  • This PR branch was created from the neoListPage branch, which has another open PR. We will aim to merge that PR first to provide a clearer view for this PR.
  • Efforts were made to decouple page interactions to allow for incremental PRs. However, hard-coded values were used in some places to ensure functionality. These hard-coded values will be removed in future updates when working on adding MDS support on those specific pages.
OpenSearch.Dashboards.-.8.April.2024.mp4

-fbe5-4621-97dd-2a5b663cb2bf)

Issues Resolved

[List any issues this PR will resolve]

Check List

  • New functionality includes testing.
    • All tests pass
  • New functionality has been documented.
  • Commits are signed per the DCO using --signoff

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

Copy link
Member

@ohltyler ohltyler Apr 9, 2024

Choose a reason for hiding this comment

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

Can we consistently have this set for all routes as part of a single change? That way we can ensure no APIs are missed. Same goes for alerting and opensearch routes pages. If it causes problems (rendering a non-integrated page causes crashes), then can you help open a tracking issue to include in a MDS meta issue that all routes are covered and tested?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I was planning to update all the routes in a single change, but then I found that it created barriers when testing my change. Some pages and calls were crashing, which prevented me from accessing certain pages and tabs. As a result, I switched to updating the routes on a per-page basis.

Opened this meta issue that can help track every pages/redux store/route updates - #721 Will do a sanity test/bug bash after code complete as well.

@ohltyler
Copy link
Member

ohltyler commented Apr 9, 2024

However, hard-coded values were used in some places to ensure functionality. These hard-coded values will be removed in future updates when working on adding MDS support on those specific pages.

Same goes for this. Please add details in tracking issues for all workarounds / hardcoded values / etc. so nothing is missed in the end. Especially since this is being committed directly to main and no feature branch.

@jackiehanyang
Copy link
Collaborator Author

However, hard-coded values were used in some places to ensure functionality. These hard-coded values will be removed in future updates when working on adding MDS support on those specific pages.

Same goes for this. Please add details in tracking issues for all workarounds / hardcoded values / etc. so nothing is missed in the end. Especially since this is being committed directly to main and no feature branch.

Added a section in the meta issue to track hardcoded value that was added while sending out incremental prs - #721

@jackiehanyang jackiehanyang mentioned this pull request Apr 9, 2024
25 tasks
Copy link
Member

@huyaboo huyaboo left a comment

Choose a reason for hiding this comment

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

A couple overall comments:

  • +1 to @ohltyler comment. We have to ensure that all relevant changes to the routes are consistent and functioning.
  • For a lot of the routes, dataSourceId is part of the route but how are Local Cluster cases handled? Double slashes // should be avoided. In the same vein, we should ensure that dataSourceId is handled consistently. In some cases dataSourceId is an optional field whereas in others it is required.

@@ -43,7 +43,8 @@ export const useFetchDetectorInfo = (
useEffect(() => {
const fetchDetector = async () => {
if (!detector) {
await dispatch(getDetector(detectorId));
// hardcoding the datasource id for now, will update it later when working on create page
Copy link
Member

Choose a reason for hiding this comment

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

Can we have a tracker for all the TODOs so we don't forget what needs to be done?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

tracked here - #721

setMenuMountPoint={props.setActionMenu}
componentType={'DataSourceView'}
componentConfig={{
activeOption: [{ id: dataSourceId}],
Copy link
Member

Choose a reason for hiding this comment

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

Non-blocking: Can label be inserted here as well if the context/parent props has found a label earlier? It's not required but it can help with reducing network calls for DataSourceMenu component.

@@ -552,6 +574,16 @@ export const DetectorList = (props: ListProps) => {
});
};

const handleDataSourceChange = (e) => {
const dataConnectionId = e[0] ? e[0].id : undefined;
Copy link
Member

Choose a reason for hiding this comment

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

If dataConnectionId = undefined, this is the invalid state returned from the component. Could you please handle this as an error state before calling setState()? If an undefined data source id is propagated, there is a chance of unpredictable behavior happening.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yes I had this change in the list page pr, too many open prs.... I will include that change here

<DetectorList
dataSourceEnabled={dataSourceEnabled}
setActionMenu={setHeaderActionMenu}
{...props}
Copy link
Member

@huyaboo huyaboo Apr 9, 2024

Choose a reason for hiding this comment

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

Since props already contains dataSourceEnabled and setHeaderActionMenu within it as required args, I think {...props} is sufficient.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't think props already contains dataSourceEnabled and setHeaderActionMenu?

<DetectorDetail
dataSourceEnabled={dataSourceEnabled}
setActionMenu={setHeaderActionMenu}
{...props} />
Copy link
Member

Choose a reason for hiding this comment

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

Same deal as the DetectorList. {...props} should be sufficient.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

same reply as above. I don't think props has these two things in it. We still need to pass them in

type: START_DETECTOR,
request: (client: HttpSetup) =>
client.post(`..${AD_NODE_API.DETECTOR}/${detectorId}/start`),
client.post(`..${AD_NODE_API.DETECTOR}/${detectorId}/${dataSourceId}/start`),
Copy link
Member

Choose a reason for hiding this comment

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

How are Local Cluster queries handled here? If Local Clusters are "", there is a possibility that the post request will contain the endpoint /detector-id//start

Provided a suggested change below:

Suggested change
client.post(`..${AD_NODE_API.DETECTOR}/${detectorId}/${dataSourceId}/start`),
client.post(`..${AD_NODE_API.DETECTOR}/${detectorId}${dataSourceId ? '/' + dataSourceId : ''}/start`),

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I will make a change to define two separate routes. one includes dataSourceId, one doesn’t. This can make the API structure clearer and avoids ambiguity. Something like this

apiRouter.get('/detectors/{id}/results/{isHistorical}', adService.getAnomalyResultsWithoutDataSource);
apiRouter.get('/detectors/{id}/{dataSourceId}/results/{isHistorical}', adService.getAnomalyResultsWithDataSource);

Copy link
Member

@ohltyler ohltyler Apr 9, 2024

Choose a reason for hiding this comment

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

That example points to 2 different functions - can we make multiple routes point to the same fn and have shared logic at the top of each fn to parse the optional data source ID?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yes, I gave a bad example above. Here's an example of existing code that has multiple routes point to the same post function searchResults:

  apiRouter.post('/detectors/_search', adService.searchDetector);
  apiRouter.post('/detectors/results/_search/', adService.searchResults);
  apiRouter.post('/detectors/results/{dataSourceId}/_search', adService.searchResults);
  apiRouter.post(
    '/detectors/results/{dataSourceId}/_search/{resultIndex}/{onlyQueryCustomResultIndex}',
    adService.searchResults
  );

Planning to parse out data source id like this

      const { dataSourceId = "" } = request.params as { dataSourceId?: string };

So when it doesn't exist in the request, just assign empty value to it so it can fallback to local cluster client

public/redux/reducers/ad.ts Show resolved Hide resolved
public/redux/reducers/ad.ts Show resolved Hide resolved
public/redux/reducers/ad.ts Show resolved Hide resolved
public/redux/reducers/anomalyResults.ts Show resolved Hide resolved
@@ -43,7 +43,8 @@ export const useFetchDetectorInfo = (
useEffect(() => {
const fetchDetector = async () => {
if (!detector) {
await dispatch(getDetector(detectorId));
// hardcoding the datasource id for now, will update it later when working on create page
await dispatch(getDetector(detectorId, '4585f560-d1ef-11ee-aa63-2181676cc573'));
Copy link

Choose a reason for hiding this comment

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

Can we add a TODO in the comment so it is clear


const location = useLocation();
const queryParams = new URLSearchParams(location.search);
const dataSourceId = queryParams.get('dataSourceId') as string;
Copy link

Choose a reason for hiding this comment

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

does dataSourceId always exist in the query param?

setMenuMountPoint={props.setActionMenu}
componentType={'DataSourceView'}
componentConfig={{
// give a placeholder label for now, will update it once neo team allows empty label field
Copy link

Choose a reason for hiding this comment

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

Probably adding a TODO: give a place holder ... here so it is easier to find the location that needs rework


setState({
...state,
page: 0,
Copy link

Choose a reason for hiding this comment

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

what does page: 0 state do here?

export function renderApp(
coreStart: CoreStart,
params: AppMountParameters,
dataSource: DataSourcePluginSetup
Copy link

Choose a reason for hiding this comment

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

looks like the dataSource object is not used below

@@ -218,6 +219,7 @@ export type DetectorListItem = {
lastUpdateTime: number;
enabledTime?: number;
detectorType?: string;
dataSourceId: string;
Copy link

Choose a reason for hiding this comment

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

Is dataSourceId optional?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants