Skip to content

Commit

Permalink
Fix Stream Routing indexset oldest message in index date (#20935)
Browse files Browse the repository at this point in the history
* show oldest message in index date

* fix lint

---------

Co-authored-by: Mohamed OULD HOCINE <[email protected]>
  • Loading branch information
ousmaneo and gally47 authored Nov 15, 2024
1 parent d5bfa63 commit 3a3cc4b
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { useState } from 'react';
import styled, { css } from 'styled-components';

import { ARCHIVE_RETENTION_STRATEGY } from 'stores/indices/IndicesStore';
import { Icon, Section, Spinner, Timestamp } from 'components/common';
import { Icon, Section, Spinner } from 'components/common';
import { IndexSetsStore, type IndexSet } from 'stores/indices/IndexSetsStore';
import { Table, Button, Alert } from 'components/bootstrap';
import { LinkContainer } from 'components/common/router';
Expand All @@ -35,6 +35,9 @@ import DestinationSwitch from 'components/streams/StreamDetails/routing-destinat
import SectionCountLabel from 'components/streams/StreamDetails/SectionCountLabel';
import useIndexSetStats from 'hooks/useIndexSetStats';
import { DEFAULT_PAGINATION } from 'stores/PaginationTypes';
import useIndexerOverview from 'hooks/useIndexerOverview';

import IndexSetOldestMessageCell from './IndexSetOldestMessageCell';

type Props = {
indexSet: IndexSet,
Expand All @@ -49,12 +52,13 @@ const DestinationIndexSetSection = ({ indexSet, stream }: Props) => {
const [pagination, setPagination] = useState(DEFAULT_PAGINATION);
const archivingEnabled = indexSet.retention_strategy_class === ARCHIVE_RETENTION_STRATEGY || indexSet?.data_tiering?.archive_before_deletion;
const { indexSets } = useStore(IndexSetsStore);
const { data, isLoading } = useStreamOutputFilters(stream.id, 'indexer', pagination);
const { data: streamOutputFilters, isLoading: isLoadingStreamOutputFilters } = useStreamOutputFilters(stream.id, 'indexer', pagination);
const { data: indexerOverview, isSuccess: isLoadingIndexerOverviewSuccess } = useIndexerOverview(indexSet.id);
/* eslint-disable no-constant-condition */
const title = true ? 'Enabled' : 'Disabled'; // TODO use api to check if enabled
const { data: indexSetStats, isSuccess: isStatsLoaded } = useIndexSetStats(indexSet.id);

if (isLoading) {
if (isLoadingStreamOutputFilters) {
<Spinner />;
}

Expand All @@ -76,7 +80,7 @@ const DestinationIndexSetSection = ({ indexSet, stream }: Props) => {
label={title}
disabled
onChange={() => {}} />
<SectionCountLabel>FILTERS {data?.pagination?.total || 0}</SectionCountLabel>
<SectionCountLabel>FILTERS {streamOutputFilters?.pagination?.total || 0}</SectionCountLabel>
</>
)}
actions={(
Expand All @@ -102,11 +106,10 @@ const DestinationIndexSetSection = ({ indexSet, stream }: Props) => {
<tr>
<td>{indexSet?.title}</td>
<td>{(isStatsLoaded && indexSetStats?.size) ? NumberUtils.formatBytes(indexSetStats.size) : 0}</td>
<td><Timestamp dateTime={indexSet.creation_date} /></td>
<td>{isLoadingIndexerOverviewSuccess && <IndexSetOldestMessageCell index={indexerOverview?.indices?.pop()} />}</td>
<td>
<IndexSetArchivingCell isArchivingEnabled={archivingEnabled} streamId={stream.id} />
</td>
{}
<td>
<ActionButtonsWrap>
<LinkContainer to={Routes.SYSTEM.INDEX_SETS.SHOW(indexSet.id)}>
Expand All @@ -122,7 +125,7 @@ const DestinationIndexSetSection = ({ indexSet, stream }: Props) => {
</tr>
</tbody>
</Table>
{data && (<IndexSetFilters streamId={stream.id} paginatedFilters={data} onPaginationChange={onPaginationChange} />)}
{streamOutputFilters && (<IndexSetFilters streamId={stream.id} paginatedFilters={streamOutputFilters} onPaginationChange={onPaginationChange} />)}
</Section>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
import * as React from 'react';

import { Timestamp } from 'components/common';
import type { IndexSummary } from 'stores/indexers/IndexerOverviewStore';

type Props = {
index?: IndexSummary;
};

const IndexSetOldestMessageCell = ({ index = null }: Props) => (
<Timestamp dateTime={index?.range?.begin} />
);

export default IndexSetOldestMessageCell;
56 changes: 56 additions & 0 deletions graylog2-web-interface/src/hooks/useIndexerOverview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
import { useQuery } from '@tanstack/react-query';

import UserNotification from 'util/UserNotification';
import type FetchError from 'logic/errors/FetchError';
import fetch from 'logic/rest/FetchProvider';
import { qualifyUrl } from 'util/URLUtils';
import ApiRoutes from 'routing/ApiRoutes';
import type { IndexerOverview } from 'stores/indexers/IndexerOverviewStore';

const fetchIndexerOverview = (indexSetId: string) => fetch('GET', qualifyUrl(ApiRoutes.IndexerOverviewApiResource.list(indexSetId).url));

const useIndexerOverview = (indexSetId: string): {
data: IndexerOverview,
refetch: () => void,
isLoading: boolean,
error: FetchError,
isSuccess: boolean,
} => {
const { data, refetch, isLoading, error, isSuccess } = useQuery<IndexerOverview, FetchError>(
['indexerOverview', indexSetId, 'stats'],
() => fetchIndexerOverview(indexSetId),
{
onError: (errorThrown) => {
UserNotification.error(`Loading indexer overview for index set failed with status: ${errorThrown}`,
'Could not load indexer overview.');
},
notifyOnChangeProps: ['data', 'error'],
},
);

return ({
data,
refetch,
isLoading,
error,
isSuccess,
});
};

export default useIndexerOverview;

0 comments on commit 3a3cc4b

Please sign in to comment.