From 21eb0e0bd53e0fdea1f3d4960733234aefa7ffec Mon Sep 17 00:00:00 2001 From: Andy Taylor Date: Mon, 24 Mar 2025 13:44:33 +0000 Subject: [PATCH] ARTEMIS-5367 - add a max address preference for the broker diagram and also a filter --- .../artemis/ArtemisPreferences.tsx | 22 ++++++++++++++- .../artemis/artemis-preferences-service.ts | 4 ++- .../artemis/artemis-service.ts | 18 +++++++++--- .../artemis/brokers/BrokerDiagram.tsx | 28 +++++++++++++++---- 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/ArtemisPreferences.tsx b/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/ArtemisPreferences.tsx index 9a9b906..7aeceb2 100644 --- a/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/ArtemisPreferences.tsx +++ b/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/ArtemisPreferences.tsx @@ -15,7 +15,7 @@ * limitations under the License. */ import { CardBody, Flex, FlexItem, Form, FormGroup, FormSection, MenuToggle, MenuToggleElement, Select, SelectList, SelectOption, TextInput } from '@patternfly/react-core' -import React, { useState } from 'react' +import React, { FormEvent, useState } from 'react' import { artemisPreferencesService, ArtemisOptions } from './artemis-preferences-service' import { Icon, Tooltip } from '@patternfly/react-core' import { HelpIcon } from '@patternfly/react-icons' @@ -60,6 +60,8 @@ const ArtemisPreferencesForm: React.FunctionComponent = () => { const [selectedFormat, setSelectedFormat] = useState(format ? format.description : off.description); const [selectedPageSize, setSelectedPageSize] = useState(artemisPreferencesService.loadArtemisPreferences().artemisDefaultPageSize) + const [artemisMaxDiagramAddressSize, setArtemisMaxDiagramAddressSize] = useState(artemisPreferencesService.loadArtemisPreferences().artemisMaxDiagramAddressSize) + const [isPageSizeDropdownOpen, setPageSizeDropdownOpen] = React.useState(false); const updatePreferences = (value: string | number | boolean, key: keyof ArtemisOptions): void => { @@ -101,6 +103,10 @@ const ArtemisPreferencesForm: React.FunctionComponent = () => { artemisPreferencesService.resetPageSizes(); } + const handleMaxDiagramAddressSize = (event: FormEvent, value: string) => { + setArtemisMaxDiagramAddressSize(Number(value)); + updatePreferences(Number(value), 'artemisMaxDiagramAddressSize'); + } return ( @@ -197,6 +203,20 @@ const ArtemisPreferencesForm: React.FunctionComponent = () => { + } + > + + + ) } diff --git a/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/artemis-preferences-service.ts b/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/artemis-preferences-service.ts index bf3acc9..afcb7b3 100644 --- a/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/artemis-preferences-service.ts +++ b/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/artemis-preferences-service.ts @@ -39,13 +39,15 @@ export type ArtemisOptions = { artemisExpiryQueue: string artemisBrowseBytesMessages: number artemisDefaultPageSize: number + artemisMaxDiagramAddressSize: number } export const ARTEMIS_PREFERENCES_DEFAULT_VALUES: ArtemisOptions = { artemisDLQ: "^DLQ$", artemisExpiryQueue: "^ExpiryQueue$", artemisBrowseBytesMessages: 99, - artemisDefaultPageSize: 10 + artemisDefaultPageSize: 10, + artemisMaxDiagramAddressSize: 20 } as const export const STORAGE_KEY_ARTEMIS_PREFERENCES = 'artemis.preferences' diff --git a/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/artemis-service.ts b/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/artemis-service.ts index 85e4ed7..d49dc93 100644 --- a/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/artemis-service.ts +++ b/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/artemis-service.ts @@ -202,7 +202,7 @@ class ArtemisService { return await this.brokerInfo; } - async createBrokerTopology(): Promise { + async createBrokerTopology(maxAddresses: number, addressFilter: string): Promise { return new Promise(async (resolve, reject) => { try { var brokerInfo = await this.getBrokerInfo(); @@ -213,7 +213,10 @@ class ArtemisService { broker: brokerInfo, addresses: [] } - var addresses: string[] = await this.getAllAddresses(); + var addresses: string[] = (await this.getAllAddresses(addressFilter)); + var max: number = maxAddresses < addresses.length ? maxAddresses: addresses.length; + addresses = addresses.slice(0, max); + log.info() for (const address of addresses) { var queuesJson: string = await this.getQueuesForAddress(address); var queues: Queue[] = JSON.parse(queuesJson).data; @@ -395,11 +398,18 @@ class ArtemisService { return await jolokiaService.execute(await this.getBrokerObjectName(), LIST_ADDRESSES_SIG, [JSON.stringify(addressesFilter), page, perPage]) as string; } - async getAllAddresses(): Promise { + async getAllAddresses(addressFilter: string): Promise { return new Promise(async (resolve, reject) => { var addressesString = await jolokiaService.execute(await this.getBrokerObjectName(), LIST_ALL_ADDRESSES_SIG, [',']) as string; if (addressesString) { - resolve(addressesString.split(',')); + + var addressArray = addressesString.split(',') + if (addressFilter && addressFilter.length > 0) { + var filtered = addressArray.filter(function (str) { return str.includes(addressFilter); }); + resolve(filtered); + } else { + resolve(addressArray); + } } reject("invalid response:" + addressesString); }); diff --git a/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/brokers/BrokerDiagram.tsx b/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/brokers/BrokerDiagram.tsx index 7c50ca0..2fe0368 100644 --- a/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/brokers/BrokerDiagram.tsx +++ b/artemis-console-extension/artemis-extension/src/artemis-extension/artemis/brokers/BrokerDiagram.tsx @@ -60,10 +60,11 @@ import { import { useEffect, useState } from 'react'; import { artemisService, BrokerInfo, BrokerTopology } from '../artemis-service'; import { Attributes } from '@hawtio/react'; -import { ToolbarItem, Select, SelectOption, Button, MenuToggleElement, MenuToggle, SelectList } from '@patternfly/react-core'; +import { ToolbarItem, Select, SelectOption, Button, MenuToggleElement, MenuToggle, SelectList, TextInput, Label, SearchInput, Text } from '@patternfly/react-core'; import { createAddressObjectName, createQueueObjectName } from '../util/jmx'; import { ArtemisContext } from '../context'; import { log } from '../globals'; +import { artemisPreferencesService } from '../artemis-preferences-service'; const BadgeColors = [ @@ -302,12 +303,17 @@ export const BrokerDiagram: React.FunctionComponent = () => { const [ showSidebar, setShowSidebar ] = React.useState(false); const [ sidebarTitle, setSidebarTitle ] = React.useState(""); const [ brokerTopology, setBrokerTopology ] = React.useState(); - const[ topologyLoaded, setTopologyLoaded ] = React.useState(false); + const [ topologyLoaded, setTopologyLoaded ] = React.useState(false); + const [ addressFilter, setAddressFilter ] = React.useState(''); + const maxAddresses: number = artemisPreferencesService.loadArtemisPreferences().artemisMaxDiagramAddressSize; const { findAndSelectNode } = React.useContext(ArtemisContext); + const onSearchTextChange = (newValue: string) => { + setAddressFilter(newValue); + }; const selectNode = React.useCallback((data: any) => { if (data.queue != null) { @@ -367,7 +373,7 @@ export const BrokerDiagram: React.FunctionComponent = () => { useEffect(() => { if (!topologyLoaded) { - artemisService.createBrokerTopology().then(brokerTopology => { + artemisService.createBrokerTopology(maxAddresses, addressFilter).then(brokerTopology => { setTopologyLoaded(true); setBrokerTopology(brokerTopology); }); @@ -563,9 +569,21 @@ export const BrokerDiagram: React.FunctionComponent = () => { onClick={() => setViewOptions(prev => ({ ...prev, showConnectors: !prev.showConnectors }))}>Connectors - + + + onSearchTextChange(value)} + value={addressFilter} + onClear={() => { + onSearchTextChange(''); + }} + /> + + + - + ); const topologySideBar = (