This is an automated email from the ASF dual-hosted git repository. brusdev pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/artemis-console.git
commit 1480e8e79aadaaabf3bdfb67a167c990cda46cae Author: Grzegorz Grzybek <[email protected]> AuthorDate: Thu Feb 19 13:52:29 2026 +0100 ARTEMIS-5777 - Use Hawtio version of MBean parsing and quoting --- .../src/artemis-service.test.ts | 4 +- .../artemis-console-plugin/src/artemis-service.ts | 54 +--------------------- .../src/artemis-tree-processor.ts | 14 +++++- .../packages/artemis-console-plugin/src/context.ts | 16 ++++--- .../artemis-console-plugin/src/util/jmx.ts | 43 ++++++++++++++--- .../src/views/ArtemisJMXTabView.tsx | 8 ++-- 6 files changed, 65 insertions(+), 74 deletions(-) diff --git a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/artemis-service.test.ts b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/artemis-service.test.ts index d043919..fbf9d88 100644 --- a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/artemis-service.test.ts +++ b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/artemis-service.test.ts @@ -15,9 +15,9 @@ * limitations under the License. */ import { beforeAll, describe, expect, test } from "@jest/globals" -import { artemisService, parseMBeanName } from "./artemis-service"; +import { artemisService } from "./artemis-service"; import { SortDirection } from './table/ArtemisTable' -import { userService } from '@hawtio/react' +import { userService, parseMBeanName } from '@hawtio/react' beforeAll(async () => { // needed to determine Jolokia URL diff --git a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/artemis-service.ts b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/artemis-service.ts index ea8c665..a268300 100644 --- a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/artemis-service.ts +++ b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/artemis-service.ts @@ -15,7 +15,7 @@ * limitations under the License. */ import { ActiveSort, Filter } from './table/ArtemisTable' -import { eventService, jolokiaService, MBeanNode, workspace } from '@hawtio/react' +import { eventService, jolokiaService, MBeanNode, parseMBeanName, workspace } from '@hawtio/react' import { createAddressObjectName, createQueueObjectName } from './util/jmx' import { log } from './globals' import { Message } from './messages/MessageView' @@ -783,61 +783,11 @@ class ArtemisService { } } -export function parseMBeanName(name: string): { domain: string, properties: Record<string, string> } { - const colon = name.indexOf(":") - if (colon === -1) { - throw new Error("Illegal ObjectName") - } - - const domain = name.substring(0, colon) - const propsString = name.substring(colon + 1) - - let i = 0 - const len = propsString.length - const props: Record<string, string> = {} - - while (i < len) { - let key = "" - while (i < len && propsString[i] !== "=") { - key += propsString[i++] - } - - // skip '=' - i++ - - let value = "" - if (propsString[i] === '"') { - // quoted value - only double quote - i++ - while (i < len) { - const ch = propsString[i++] - if (ch === '"') { - break - } - value += ch - } - } else { - // unquoted value can be empty - while (i < len && propsString[i] !== ",") { - value += propsString[i++] - } - } - - props[key.trim()] = value.trim() - - if (propsString[i] === ",") { - i++ - } - } - - return { domain, properties: props }; -} - export async function findMBeanInfo(brokerObjectName: string): Promise<MBeanNode | null> { const tree = await workspace.getTree() const parsed = parseMBeanName(brokerObjectName) - const matching = tree.findMBeans(parsed.domain, parsed.properties) + const matching = parsed.domain && tree.findMBeans(parsed.domain, parsed.properties) if (!matching) { return null } diff --git a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/artemis-tree-processor.ts b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/artemis-tree-processor.ts index 84b3865..64862b3 100644 --- a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/artemis-tree-processor.ts +++ b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/artemis-tree-processor.ts @@ -92,10 +92,20 @@ function findBrokers(children: MBeanNode[] | undefined): MBeanNode[] { for (const c of children) { if (c.id.endsWith('-folder')) { if (oldBrokers.has(c.name)) { - const newBrokerNode = oldBrokers.get(c.name)!.copyTo(`Broker ${c.name}`) - newBrokerNode.children = c.children + const oldBrokerNode = oldBrokers.get(c.name)! + const newBrokerNode = new MBeanNode(null, `Broker ${c.name}`, true) newBrokerNode.icon = c.icon newBrokerNode.expandedIcon = c.expandedIcon + newBrokerNode.children = [] + // newBrokerNode.metadata = oldBrokerNode.metadata + newBrokerNode.objectName = oldBrokerNode.objectName + newBrokerNode.mbean = oldBrokerNode.mbean + newBrokerNode.propertyList = oldBrokerNode.propertyList + + const children = [...c.children!] + children.forEach(c => { + newBrokerNode.adopt(c) + }) brokers.push(newBrokerNode) } } diff --git a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/context.ts b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/context.ts index ae772a7..1d9c1ae 100644 --- a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/context.ts +++ b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/context.ts @@ -15,8 +15,7 @@ * limitations under the License. */ import { eventService, EVENT_REFRESH,MBeanNode, MBeanTree, PluginNodeSelectionContext, workspace } from "@hawtio/react"; -import { TreeViewDataItem } from "@patternfly/react-core"; -import { createContext, useContext, useEffect, useState } from "react"; +import { createContext, useContext, useEffect, useRef, useState } from "react"; import { useNavigate } from 'react-router-dom' import { artemisPluginName } from "./globals"; import { configManager } from "./config-manager"; @@ -32,6 +31,8 @@ export function useArtemisTree() { const { selectedNode, setSelectedNode } = useContext(PluginNodeSelectionContext) const navigate = useNavigate(); + const refSelectedNode = useRef<MBeanNode | null>() + refSelectedNode.current = selectedNode const populateTree = async () => { const wkspTree: MBeanTree = await workspace.getTree(); @@ -43,11 +44,12 @@ export function useArtemisTree() { setBrokerNode(rootNode.children[0]); } // Expand the nodes to redisplay the path - if (selectedNode) { - rootNode.forEach(selectedNode?.path(), (node: MBeanNode) => { - const tvd = node as TreeViewDataItem - tvd.defaultExpanded = true - }) + if (refSelectedNode.current) { + let curr: MBeanNode | null = refSelectedNode.current + while (curr) { + curr.defaultExpanded = true + curr = curr.parent + } } const subTree: MBeanTree = MBeanTree.createFromNodes(artemisPluginName, [rootNode]) setTree(subTree) diff --git a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/util/jmx.ts b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/util/jmx.ts index 2c215ea..a310c07 100644 --- a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/util/jmx.ts +++ b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/util/jmx.ts @@ -28,16 +28,45 @@ const ADDRESS_COMPONENT = "component=addresses"; * "127.0.0.1",component=addresses,address="q1",subcomponent=queues,routing-type="anycast",queue="q1" */ export function createQueueObjectName(brokerMBean: string, address: string, routingType: string, queue: string): string { - var queueMBeanName = queue; - if(queueMBeanName.includes('\\')){ - //it may have a client id with /. in the name which is delimeted in the mbean name - queueMBeanName = queueMBeanName.replaceAll('\\', '\\\\'); - } - return brokerMBean + ADDRESS_COMPONENT_PART + address + ADDRESS_SUBCOMPONENT_PART + routingType.toLowerCase() + ADDRESS_TYPE_PART + queueMBeanName + STRING_DELIMETER; + let addressMBeanName = mbeanEscape(address); + let queueMBeanName = mbeanEscape(queue); + return brokerMBean + ADDRESS_COMPONENT_PART + addressMBeanName + ADDRESS_SUBCOMPONENT_PART + routingType.toLowerCase() + ADDRESS_TYPE_PART + queueMBeanName + STRING_DELIMETER; } export function createAddressObjectName(brokerMBean: string, address: string) { - return brokerMBean + ADDRESS_COMPONENT_PART + address + STRING_DELIMETER; + return brokerMBean + ADDRESS_COMPONENT_PART + mbeanEscape(address) + STRING_DELIMETER; +} + +/** + * This function is an equivalent of `javax.management.ObjectName.quote()` + * @param value + */ +function mbeanEscape(value: string): string { + let res = value + // it may have a client id with \. in the name which is delimited in the mbean name + // according to javax.management.ObjectName.quote() javadoc, we have to replace: + res = res.replaceAll('\\', '\\\\'); + res = res.replaceAll('*', '\\*'); + res = res.replaceAll('"', '\\"'); + res = res.replaceAll('?', '\\?'); + return res +} + +/** + * This function should behave like `javax.management.ObjectName.unquote()` for quoted values + * and should not change the value when it's not quoted + * @param value + */ +export function mbeanUnescape(value: string): string { + if (!value || !value.startsWith('"') || !value.endsWith('"')) { + return value + } + let res = value.substring(1, value.length - 1); + res = res.replaceAll('\\"', '"'); + res = res.replaceAll('\\*', '*'); + res = res.replaceAll('\\?', '?'); + res = res.replaceAll('\\\\', '\\'); + return res } export function isQueue(node: MBeanNode): boolean { diff --git a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/views/ArtemisJMXTabView.tsx b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/views/ArtemisJMXTabView.tsx index 356f672..ad90951 100644 --- a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/views/ArtemisJMXTabView.tsx +++ b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/views/ArtemisJMXTabView.tsx @@ -19,7 +19,7 @@ import { Tabs, Tab, TabTitleText, Button, Modal, ModalVariant, PageSection } fro import { Attributes, Chart, MBeanNode, Operations } from '@hawtio/react'; import { CreateQueue } from '../queues/CreateQueue'; import { DeleteAddress } from '../addresses/DeleteAddress'; -import { isAddress as isAnAddress, isQueue } from '../util/jmx' +import { isAddress as isAnAddress, isQueue, mbeanUnescape } from '../util/jmx' import { MessagesTable } from '../messages/MessagesTable'; import { SendMessage } from '../messages/SendMessage'; import { Message, MessageView } from '../messages/MessageView'; @@ -58,11 +58,11 @@ export const ArtemisJMXTabs: React.FunctionComponent = () => { const isAQueue = isQueue(selectedNode); let prop = selectedNode.getProperty("routing-type"); - const routingType: string = prop === undefined?'':prop; + const routingType: string = mbeanUnescape(prop === undefined?'':prop); prop = selectedNode.getProperty("address"); - const address: string | undefined = prop === undefined?'':prop; + const address: string | undefined = mbeanUnescape(prop === undefined?'':prop); prop = selectedNode.getProperty("queue"); - const queue: string | undefined = prop === undefined?'':prop; + const queue: string | undefined = mbeanUnescape(prop === undefined?'':prop); const handleTabClick = ( event: React.MouseEvent<any> | React.KeyboardEvent | MouseEvent, tabIndex: string | number ) => { --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
