This is an automated email from the ASF dual-hosted git repository.

andytaylor pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/artemis-console.git


The following commit(s) were added to refs/heads/main by this push:
     new 4a9d0b5  ARTEMIS-6030 - added status of lock coordinators to console
4a9d0b5 is described below

commit 4a9d0b5b374a23dcc6aa4fb04609f69d8e52a5ec
Author: Andy Taylor <[email protected]>
AuthorDate: Mon Apr 27 10:07:48 2026 +0100

    ARTEMIS-6030 - added status of lock coordinators to console
---
 .../artemis-console-plugin/src/artemis-service.ts  | 54 +++++++++++++++++++++-
 .../src/status/Status.test.tsx                     |  1 +
 .../artemis-console-plugin/src/status/Status.tsx   | 47 ++++++++++++++++++-
 3 files changed, 100 insertions(+), 2 deletions(-)

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 75c5e40..5d1b3dc 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
@@ -97,6 +97,20 @@ export type Acceptors = {
     acceptors: Acceptor[]
 }
 
+export type LockCoordinator = {
+    name: string
+    lockId: string
+    className: string
+    simpleName: string
+    locked: boolean
+    started: boolean
+    status: string
+}
+
+export type LockCoordinators = {
+    lockCoordinators: LockCoordinator[]
+}
+
 export type ClusterConnection = {
     Started: boolean
     Address: string
@@ -164,7 +178,8 @@ const DESTROY_QUEUE_SIG = "destroyQueue(java.lang.String)";
 const REMOVE_ALL_MESSAGES_SIG = "removeAllMessages()";
 const CLOSE_CONNECTION_SIG = "closeConnectionWithID(java.lang.String)";
 const CLOSE_SESSION_SIG = 
"closeSessionWithID(java.lang.String,java.lang.String)";
-const CLOSE_CONSUMER_SIG = 
"closeConsumerWithID(java.lang.String,java.lang.String)"
+const CLOSE_CONSUMER_SIG = 
"closeConsumerWithID(java.lang.String,java.lang.String)";
+const LIST_LOCK_MANAGER_SIG = "listLockCoordinatorsAsJSON()";
 
 const MS_PER_SEC = 1000;
 const MS_PER_MIN = 60 * MS_PER_SEC;
@@ -356,6 +371,36 @@ class ArtemisService {
         });
     }
 
+    async createLockCoordinators(): Promise<LockCoordinators> {
+        return new Promise<LockCoordinators>(async (resolve, reject) => {
+            const lockCoordinators: LockCoordinators = {
+                lockCoordinators: []
+            };
+            const brokerObjectName = await this.getBrokerObjectName();
+            const brokerMBean = await findMBeanInfo(brokerObjectName);
+            const doesListLockCoordinatorMethodExist = 
this.doesListLockCoordinatorMethodExist(brokerMBean as MBeanNode)
+            if (!doesListLockCoordinatorMethodExist) {
+                console.log("Lock Coordinators not available in this broker 
version");
+                resolve(lockCoordinators);
+            } else if(this.canListLockCoordinators(brokerMBean as MBeanNode)) {
+                const lockCoordinatorString = await 
jolokiaService.execute(brokerObjectName, LIST_LOCK_MANAGER_SIG).catch(error => {
+                    eventService.notify({ type: "warning", message: 
jolokiaService.errorMessage(error) })
+                    return "[]"
+                }) as string;
+                if (lockCoordinatorString) {
+                    lockCoordinators.lockCoordinators = 
JSON.parse(lockCoordinatorString);
+                    console.info("resolved " + lockCoordinators);
+                    console.info("from " + lockCoordinatorString);
+                    resolve(lockCoordinators);
+                }
+
+            } else {
+                console.info("oops")
+                resolve(lockCoordinators);
+            }
+            reject("invalid response:")
+        });
+    }
     async createAcceptors(): Promise<Acceptors> {
         return new Promise<Acceptors>(async (resolve, reject) => {
             const brokerObjectName = await this.brokerObjectName;
@@ -755,6 +800,9 @@ class ArtemisService {
         return (this.DEBUG_PRIVS && 
queueMBean?.hasInvokeRights(SEND_MESSAGE_SIG)) ?? false;
     }
 
+    canListLockCoordinators = (brokerMBean: MBeanNode | undefined): boolean => 
{
+        return (this.DEBUG_PRIVS && 
brokerMBean?.hasInvokeRights(LIST_LOCK_MANAGER_SIG)) ?? false;
+    }
     canBrowseQueue = (broker: MBeanNode | undefined, queue: string): boolean 
=> {
         if(broker) {
             const queueMBean = broker.parent?.find(node => { 
@@ -810,6 +858,10 @@ class ArtemisService {
         return false;
     }
 
+    doesListLockCoordinatorMethodExist = (broker: MBeanNode | undefined): 
boolean => {
+        return broker?broker.hasOperations("listLockCoordinatorsAsJSON"): 
false;
+    }
+
     canListConnections = (broker: MBeanNode | undefined): boolean => {
         return (this.DEBUG_PRIVS && 
broker?.hasInvokeRights(LIST_CONNECTIONS_SIG)) ?? false
     }
diff --git 
a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/status/Status.test.tsx
 
b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/status/Status.test.tsx
index 135b99b..3c15901 100644
--- 
a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/status/Status.test.tsx
+++ 
b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/status/Status.test.tsx
@@ -80,6 +80,7 @@ describe('Status', () => {
       ...mockBrokerState
     })
     ;(artemisService.createAcceptors as jest.Mock).mockResolvedValue({ 
acceptors: [] })
+    ;(artemisService.createLockCoordinators as jest.Mock).mockResolvedValue({ 
lockCoordinators: [] })
     ;(artemisService.createClusterConnections as 
jest.Mock).mockResolvedValue({ clusterConnections: [] })
     ;(artemisService.getBrokerObjectName as 
jest.Mock).mockResolvedValue('org.apache.activemq.artemis:broker=127.0.0.1')
   })
diff --git 
a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/status/Status.tsx
 
b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/status/Status.tsx
index eea1a01..b8e2ec7 100644
--- 
a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/status/Status.tsx
+++ 
b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/status/Status.tsx
@@ -46,7 +46,7 @@ import { ExclamationCircleIcon } from 
'@patternfly/react-icons/dist/esm/icons/ex
 import { OkIcon } from '@patternfly/react-icons/dist/esm/icons/ok-icon'
 import { Attributes, eventService, jolokiaService, Operations } from 
'@hawtio/react';
 import React, { ReactNode, useContext, useEffect, useState } from "react";
-import { Acceptors, artemisService, BrokerInfo, BrokerState, 
ClusterConnections } from "../artemis-service";
+import { Acceptors, artemisService, BrokerInfo, BrokerState, 
ClusterConnections, LockCoordinators } from "../artemis-service";
 import { ArtemisContext } from "../context";
 import { Table, Tbody, Td, Th, Thead, Tr } from "@patternfly/react-table";
 import { LockedIcon } from '@patternfly/react-icons'
@@ -56,6 +56,7 @@ export const Status: React.FunctionComponent = () => {
     const [brokerState, setBrokerState] = useState<BrokerState>({ loaded: 
false, accessible: false, message: "Loading..." })
     const [brokerInfo, setBrokerInfo] = useState<BrokerInfo>()
     const [acceptors, setAcceptors] = useState<Acceptors>();
+    const [lockCoordinators, setLockCoordinators] = 
useState<LockCoordinators>();
     const [clusterConnections, setClusterConnections] = 
useState<ClusterConnections>()
     const { findAndSelectNode } = useContext(ArtemisContext)
 
@@ -86,6 +87,16 @@ export const Status: React.FunctionComponent = () => {
             });
     }
 
+    const getLockCoordinators = async () => {
+        artemisService.createLockCoordinators()
+            .then((lockCoordinators) => {
+                setLockCoordinators(lockCoordinators)
+            })
+            .catch((error) => {
+                eventService.notify({type: 'warning', message: 
jolokiaService.errorMessage(error) })
+            });
+    }
+
     const getClusterConnections = async () => {
         artemisService.createClusterConnections()
             .then((clusterConnections) => {
@@ -102,6 +113,8 @@ export const Status: React.FunctionComponent = () => {
 
         getAcceptors();
 
+        getLockCoordinators();
+
         getClusterConnections();
 
         // Pause auto-refresh when Operations dialog is open to prevent 
collapsing expanded operations
@@ -271,6 +284,38 @@ export const Status: React.FunctionComponent = () => {
                     </Card>
                 </GridItem>
             </Grid>
+            {lockCoordinators && lockCoordinators.lockCoordinators.length > 0 
&&
+            <ExpandableSection toggleTextExpanded="Lock Coordinators" 
toggleTextCollapsed="Lock Coordinators">
+                <Grid hasGutter span={4}>
+                    <GridItem span={6} rowSpan={3}>
+                        <Card isFullHeight={true} >
+                            <CardBody>
+                                <Divider />
+                                <Table>
+                                    <Thead>
+                                        <Tr>
+                                            <Th>Name</Th>
+                                            <Th>ID</Th>
+                                            <Th>Status</Th>
+                                        </Tr>
+                                    </Thead>
+                                    <Tbody>
+                                        {
+                                            
lockCoordinators?.lockCoordinators.map((coordinator, index) => {
+                                                return <Tr>
+                                                    <Td>{coordinator.name}</Td>
+                                                    
<Td>{coordinator.lockId}</Td>
+                                                    
<Td>{coordinator.status}</Td>
+                                                </Tr>
+                                            })
+                                        }
+                                    </Tbody>
+                                </Table>
+                            </CardBody>
+                        </Card>
+                    </GridItem>
+                </Grid>
+            </ExpandableSection>}
             <ExpandableSection toggleTextExpanded="Acceptors" 
toggleTextCollapsed="Acceptors">
                 <Grid hasGutter span={4}>
                     {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to