From f65dc4804afe90e8aa459f61bbd6ab0c12d4b218 Mon Sep 17 00:00:00 2001 From: Howard Gao Date: Tue, 5 Nov 2024 11:31:34 +0800 Subject: [PATCH] [#28] refactor to reduce code repetition Currently in ArtemisJolokia code there are many common codes among fetching methods for different components. For example readBrokerAttributes, readAddressAttributes and readClusterConnectionAttributes are all sending 'POST' requests with similar pattern but only different parameters. It can be abstracted to a common method shared by those methods and also will be reused when we add new components like Bridges. --- src/api/apiutil/artemis_jolokia.ts | 495 ++++++----------------------- src/api/controllers/api_impl.ts | 256 ++++++++------- 2 files changed, 237 insertions(+), 514 deletions(-) diff --git a/src/api/apiutil/artemis_jolokia.ts b/src/api/apiutil/artemis_jolokia.ts index ce9c425..bc66077 100644 --- a/src/api/apiutil/artemis_jolokia.ts +++ b/src/api/apiutil/artemis_jolokia.ts @@ -40,6 +40,16 @@ const queueComponentPattern = 'org.apache.activemq.artemis:address="ADDRESS_NAME",broker="BROKER_NAME",component=addresses,queue="QUEUE_NAME",routing-type="ROUTING_TYPE",subcomponent=queues'; const clusterConnectionComponentPattern = 'org.apache.activemq.artemis:broker="BROKER_NAME",component=cluster-connections,name="CLUSTER_CONNECTION_NAME"'; + +export enum ComponentType { + ALL = 'broker-components', + BROKER = 'broker', + ADDRESS = 'address', + QUEUE = 'queue', + ACCEPTOR = 'acceptor', + CLUSTER_CONNECTION = 'cluster-connection', +} + export class ArtemisJolokia { readonly username: string; readonly password: string; @@ -49,47 +59,35 @@ export class ArtemisJolokia { brokerName: string; readonly baseUrl: string; - static readonly BROKER = 'broker'; - static readonly BROKER_DETAILS = 'broker-details'; - static readonly BROKER_COMPONENTS = 'broker-components'; - static readonly ADDRESS = 'address'; - static readonly QUEUE = 'queue'; - static readonly ACCEPTOR = 'acceptor'; - static readonly QUEUE_DETAILS = 'queue-details'; - static readonly ADDRESS_DETAILS = 'address-details'; - static readonly ACCEPTOR_DETAILS = 'acceptor-details'; - static readonly CLUSTER_CONNECTION_DETAILS = 'cluster-connection-details'; - static readonly CLUSTER_CONNECTION = 'cluster-connection'; - - componentMap = new Map([ - [ArtemisJolokia.BROKER, brokerSearchPattern], - [ArtemisJolokia.BROKER_COMPONENTS, brokerComponentsSearchPattern], - [ArtemisJolokia.ADDRESS, addressComponentsSearchPattern], - [ArtemisJolokia.QUEUE, queueComponentsSearchPattern], - [ArtemisJolokia.ACCEPTOR, acceptorComponentsSearchPattern], + static readonly KEY_COMPONENT_TYPE = 'component-type'; + static readonly KEY_COMPONENT_NAME = 'component-name'; + + componentMap = new Map([ + [ComponentType.BROKER, brokerSearchPattern], + [ComponentType.ALL, brokerComponentsSearchPattern], + [ComponentType.ADDRESS, addressComponentsSearchPattern], + [ComponentType.QUEUE, queueComponentsSearchPattern], + [ComponentType.ACCEPTOR, acceptorComponentsSearchPattern], [ - ArtemisJolokia.CLUSTER_CONNECTION, + ComponentType.CLUSTER_CONNECTION, clusterConnectionComponentsSearchPattern, ], ]); - componentDetailsMap = new Map([ - [ArtemisJolokia.BROKER_DETAILS, brokerDetailsListPattern], - [ArtemisJolokia.QUEUE_DETAILS, queueDetailsListPattern], - [ArtemisJolokia.ADDRESS_DETAILS, addressDetailsListPattern], - [ArtemisJolokia.ACCEPTOR_DETAILS, acceptorDetailsListPattern], - [ - ArtemisJolokia.CLUSTER_CONNECTION_DETAILS, - clusterConnectionDetailsListPattern, - ], + componentDetailsMap = new Map([ + [ComponentType.BROKER, brokerDetailsListPattern], + [ComponentType.QUEUE, queueDetailsListPattern], + [ComponentType.ADDRESS, addressDetailsListPattern], + [ComponentType.ACCEPTOR, acceptorDetailsListPattern], + [ComponentType.CLUSTER_CONNECTION, clusterConnectionDetailsListPattern], ]); - componentNameMap = new Map([ - [ArtemisJolokia.BROKER, brokerComponentPattern], - [ArtemisJolokia.ADDRESS, addressComponentPattern], - [ArtemisJolokia.ACCEPTOR, acceptorComponentPattern], - [ArtemisJolokia.QUEUE, queueComponentPattern], - [ArtemisJolokia.CLUSTER_CONNECTION, clusterConnectionComponentPattern], + componentNameMap = new Map([ + [ComponentType.BROKER, brokerComponentPattern], + [ComponentType.ADDRESS, addressComponentPattern], + [ComponentType.ACCEPTOR, acceptorComponentPattern], + [ComponentType.QUEUE, queueComponentPattern], + [ComponentType.CLUSTER_CONNECTION, clusterConnectionComponentPattern], ]); constructor( @@ -126,12 +124,12 @@ export class ArtemisJolokia { }; getComponents = async ( - name: string, + compType: ComponentType, params?: Map, ): Promise> => { const headers = this.getAuthHeaders(); - let searchPattern = this.componentMap.get(name); + let searchPattern = this.componentMap.get(compType); if (typeof params !== 'undefined') { for (const [key, value] of params) { @@ -156,136 +154,16 @@ export class ArtemisJolokia { return reply; }; - getBrokerDetails = async (): Promise => { - const headers = this.getAuthHeaders(); - - let searchPattern = this.componentDetailsMap.get( - ArtemisJolokia.BROKER_DETAILS, - ); - - searchPattern = searchPattern?.replace('BROKER_NAME', this.brokerName); - - const url = this.baseUrl + 'list/' + searchPattern; - - const reply = await fetch(url, { - method: 'GET', - headers: headers, - }) - .then((response) => { - if (response.ok) { - return response.text(); - } - throw response; - }) - .then((message) => { - const resp: JolokiaListResponseType = JSON.parse(message); - if (resp.status !== 200) { - throw resp.error; - } - return resp.value; - }) - .catch((err) => { - throw err; - }); - - return reply; - }; - - getAcceptorDetails = async ( - params?: Map, - ): Promise => { - const headers = this.getAuthHeaders(); - - let searchPattern = this.componentDetailsMap.get( - ArtemisJolokia.ACCEPTOR_DETAILS, - ); - - if (typeof params !== 'undefined') { - for (const [key, value] of params) { - searchPattern = searchPattern?.replace(key, value); - } - } - searchPattern = searchPattern?.replace('BROKER_NAME', this.brokerName); - - const url = this.baseUrl + 'list/' + searchPattern; - - const reply = await fetch(url, { - method: 'GET', - headers: headers, - }) - .then((response) => { - if (response.ok) { - return response.text(); - } - throw response; - }) - .then((message) => { - const resp: JolokiaListResponseType = JSON.parse(message); - if (resp.status !== 200) { - throw resp.error; - } - return resp.value; - }) - .catch((err) => { - throw err; - }); - - return reply; - }; - - getAddressDetails = async ( - params?: Map, - ): Promise => { - const headers = this.getAuthHeaders(); - - let searchPattern = this.componentDetailsMap.get( - ArtemisJolokia.ADDRESS_DETAILS, - ); - - if (typeof params !== 'undefined') { - for (const [key, value] of params) { - searchPattern = searchPattern?.replace(key, value); - } - } - searchPattern = searchPattern?.replace('BROKER_NAME', this.brokerName); - - const url = this.baseUrl + 'list/' + searchPattern; - - const reply = await fetch(url, { - method: 'GET', - headers: headers, - }) - .then((response) => { - if (response.ok) { - return response.text(); - } - throw response; - }) - .then((message) => { - const resp: JolokiaListResponseType = JSON.parse(message); - if (resp.status !== 200) { - throw resp.error; - } - return resp.value; - }) - .catch((err) => { - throw err; - }); - - return reply; - }; - - getClusterConnectionDetails = async ( - params?: Map, + readComponentDetails = async ( + compType: ComponentType, + param?: Map, ): Promise => { const headers = this.getAuthHeaders(); - let searchPattern = this.componentDetailsMap.get( - ArtemisJolokia.CLUSTER_CONNECTION_DETAILS, - ); + let searchPattern = this.componentDetailsMap.get(compType); - if (typeof params !== 'undefined') { - for (const [key, value] of params) { + if (param) { + for (const [key, value] of param) { searchPattern = searchPattern?.replace(key, value); } } @@ -317,111 +195,9 @@ export class ArtemisJolokia { return reply; }; - readBrokerAttributes = async ( - brokerAttrNames: string[], - ): Promise => { - const headers = this.getAuthHeaders(); - headers.set('Content-Type', 'application/json'); - - const reply = await fetch(this.baseUrl, { - method: 'POST', - headers: headers, - body: this.getPostBodyForAttributes( - ArtemisJolokia.BROKER, - new Map(), - brokerAttrNames, - ), - }) - .then((response) => { - if (response.ok) { - return response.text(); - } - throw response; - }) //directly use json()? - .then((message) => { - const resp: JolokiaReadResponse[] = JSON.parse(message); - return resp; - }) - .catch((err) => { - throw err; - }); - - return reply; - }; - - readAddressAttributes = async ( - addressName: string, - addressAttrNames: string[], - ): Promise => { - const headers = this.getAuthHeaders(); - headers.set('Content-Type', 'application/json'); - - const param = new Map(); - param.set('ADDRESS_NAME', addressName); - - const reply = await fetch(this.baseUrl, { - method: 'POST', - headers: headers, - body: this.getPostBodyForAttributes( - ArtemisJolokia.ADDRESS, - param, - addressAttrNames, - ), - }) - .then((response) => { - if (response.ok) { - return response.text(); - } - throw response; - }) //directly use json()? - .then((message) => { - const resp: JolokiaReadResponse[] = JSON.parse(message); - return resp; - }) - .catch((err) => { - throw err; - }); - - return reply; - }; - - readClusterConnectionAttributes = async ( - clusterConnectionName: string, - clusterConnectionAttrNames: string[], - ): Promise => { - const headers = this.getAuthHeaders(); - headers.set('Content-Type', 'application/json'); - - const param = new Map(); - param.set('CLUSTER_CONNECTION_NAME', clusterConnectionName); - - const reply = await fetch(this.baseUrl, { - method: 'POST', - headers: headers, - body: this.getPostBodyForAttributes( - ArtemisJolokia.CLUSTER_CONNECTION, - param, - clusterConnectionAttrNames, - ), - }) - .then((response) => { - if (response.ok) { - return response.text(); - } - throw response; - }) //directly use json()? - .then((message) => { - const resp: JolokiaReadResponse[] = JSON.parse(message); - return resp; - }) - .catch((err) => { - throw err; - }); - - return reply; - }; - - execClusterConnectionOperation = async ( + execComponentOperation = async ( + compType: ComponentType, + compName: string, param: Map, signature: string, args: string[], @@ -433,7 +209,8 @@ export class ArtemisJolokia { method: 'POST', headers: headers, body: this.getPostBodyForOperation( - ArtemisJolokia.CLUSTER_CONNECTION, + compType, + compName, param, signature, args, @@ -456,139 +233,17 @@ export class ArtemisJolokia { return reply; }; - execBrokerOperation = async ( - signature: string, - args: string[], - ): Promise => { - const headers = this.getAuthHeaders(); - headers.set('Content-Type', 'application/json'); - - const reply = await fetch(this.baseUrl, { - method: 'POST', - headers: headers, - body: this.getPostBodyForOperation( - ArtemisJolokia.BROKER, - new Map(), - signature, - args, - ), - }) - .then((response) => { - if (response.ok) { - return response.json(); - } else { - throw response; - } - }) - .then((jsonObj) => { - return jsonObj as JolokiaExecResponse; - }) - .catch((err) => { - throw err; - }); - - return reply; - }; - - getQueueDetails = async ( - params?: Map, - ): Promise => { - const headers = this.getAuthHeaders(); - - let searchPattern = this.componentDetailsMap.get( - ArtemisJolokia.QUEUE_DETAILS, - ); - - if (typeof params !== 'undefined') { - for (const [key, value] of params) { - searchPattern = searchPattern?.replace(key, value); - } - } - searchPattern = searchPattern?.replace('BROKER_NAME', this.brokerName); - - const url = this.baseUrl + 'list/' + searchPattern; - - const reply = await fetch(url, { - method: 'GET', - headers: headers, - }) - .then((response) => { - if (response.ok) { - return response.text(); - } - throw response; - }) //directly use json()? - .then((message) => { - const resp: JolokiaListResponseType = JSON.parse(message); - if (resp.status !== 200) { - throw resp.error; - } - return resp.value; - }) - .catch((err) => { - throw err; - }); - - return reply; - }; - - readQueueAttributes = async ( - queueName: string, - routingType: string, - addressName: string, - queueAttrNames: string[], - ): Promise => { - const headers = this.getAuthHeaders(); - headers.set('Content-Type', 'application/json'); - - const param = new Map(); - param.set('QUEUE_NAME', queueName); - param.set('ROUTING_TYPE', routingType); - param.set('ADDRESS_NAME', addressName); - - const reply = await fetch(this.baseUrl, { - method: 'POST', - headers: headers, - body: this.getPostBodyForAttributes( - ArtemisJolokia.QUEUE, - param, - queueAttrNames, - ), - }) - .then((response) => { - if (response.ok) { - return response.text(); - } - throw response; - }) //directly use json()? - .then((message) => { - const resp: JolokiaReadResponse[] = JSON.parse(message); - return resp; - }) - .catch((err) => { - throw err; - }); - return reply; - }; - - readAcceptorAttributes = async ( - acceptorName: string, - acceptorAttrNames: string[], + readComponentAttributes = async ( + compType: ComponentType, + param: Map, + attrNames: string[], ): Promise => { const headers = this.getAuthHeaders(); headers.set('Content-Type', 'application/json'); - - const param = new Map(); - param.set('ACCEPTOR_NAME', acceptorName); - const reply = await fetch(this.baseUrl, { method: 'POST', headers: headers, - body: this.getPostBodyForAttributes( - ArtemisJolokia.ACCEPTOR, - param, - acceptorAttrNames, - ), + body: this.getPostBodyForAttributes(compType, param, attrNames), }) .then((response) => { if (response.ok) { @@ -607,7 +262,7 @@ export class ArtemisJolokia { }; validateUser = async (): Promise => { - const result = await this.getComponents(ArtemisJolokia.BROKER); + const result = await this.getComponents(ComponentType.BROKER); if (result.length === 1) { //org.apache.activemq.artemis:broker="amq-broker" this.brokerName = result[0].split('=', 2)[1]; @@ -620,16 +275,16 @@ export class ArtemisJolokia { }; getPostBodyForAttributes = ( - component: string, + compType: ComponentType, params?: Map, attrs?: string[], ): string => { const bodyItems: JolokiaPostReadBodyItem[] = []; - let bean = this.componentNameMap.get(component) as string; + let bean = this.componentNameMap.get(compType) as string; if (!bean) { throw 'undefined bean'; } - if (params !== undefined) { + if (params) { for (const [key, value] of params) { bean = bean.replace(key, value); } @@ -648,21 +303,53 @@ export class ArtemisJolokia { return JSON.stringify([{ type: 'read', mbean: bean }]); }; + getComponentNameKey(compType: ComponentType): string { + switch (compType) { + case ComponentType.ACCEPTOR: { + return 'ACCEPTOR_NAME'; + } + case ComponentType.ADDRESS: { + return 'ADDRESS_NAME'; + } + case ComponentType.BROKER: { + return ''; + } + case ComponentType.CLUSTER_CONNECTION: { + return 'CLUSTER_CONNECTION_NAME'; + } + case ComponentType.QUEUE: { + return 'QUEUE_NAME'; + } + default: + return ''; + } + } + getPostBodyForOperation = ( - component: string, + compType: ComponentType, + compName: string, params: Map, signature: string, args?: string[], ): string => { const bodyItems: JolokiaPostExecBodyItem[] = []; - let bean = this.componentNameMap.get(component) as string; + let bean = this.componentNameMap.get(compType) as string; if (!bean) { throw 'undefined bean'; } + bean = bean.replace('BROKER_NAME', this.brokerName); - params.forEach((value, key) => { - bean = bean.replace(key, value); - }); + const nameKey = this.getComponentNameKey(compType); + // nameKey is empty when compType is BROKER + if (nameKey) { + bean = bean.replace(nameKey, compName); + } + + if (params) { + params.forEach((value, key) => { + bean = bean.replace(key, value); + }); + } bodyItems.push({ type: 'exec', diff --git a/src/api/controllers/api_impl.ts b/src/api/controllers/api_impl.ts index d2091fa..d76b93d 100644 --- a/src/api/controllers/api_impl.ts +++ b/src/api/controllers/api_impl.ts @@ -1,6 +1,7 @@ import * as express from 'express'; import { ArtemisJolokia, + ComponentType, JolokiaExecResponse, JolokiaObjectDetailsType, JolokiaReadResponse, @@ -25,9 +26,9 @@ const parseProps = (rawProps: string): Map => { export const getBrokers = (_: express.Request, res: express.Response): void => { try { - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; - const comps = jolokia.getComponents(ArtemisJolokia.BROKER); + const comps = jolokia.getComponents(ComponentType.BROKER); comps .then((result: any[]) => { @@ -57,9 +58,9 @@ export const getClusterConnections = ( res: express.Response, ): void => { try { - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; - const comps = jolokia.getComponents(ArtemisJolokia.CLUSTER_CONNECTION); + const comps = jolokia.getComponents(ComponentType.CLUSTER_CONNECTION); comps .then((result: any[]) => { @@ -93,14 +94,19 @@ export const readClusterConnectionAttributes = ( res: express.Response, ): void => { try { - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; const clusterConnectionName = req.query.name as string; const clusterConnectionAttrNames = req.query.attrs as string[]; - const attributes = jolokia.readClusterConnectionAttributes( - clusterConnectionName, + const param = new Map(); + param.set('CLUSTER_CONNECTION_NAME', clusterConnectionName); + + const attributes = jolokia.readComponentAttributes( + ComponentType.CLUSTER_CONNECTION, + param, clusterConnectionAttrNames, ); + attributes .then((result: JolokiaReadResponse[]) => { res.json(result); @@ -123,14 +129,17 @@ export const getClusterConnectionDetails = ( res: express.Response, ): void => { try { - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; const clusterConnectionName = req.query.name; const param = new Map(); param.set('CLUSTER_CONNECTION_NAME', clusterConnectionName); - const compDetails = jolokia.getClusterConnectionDetails(param); + const compDetails = jolokia.readComponentDetails( + ComponentType.CLUSTER_CONNECTION, + param, + ); compDetails .then((result: JolokiaObjectDetailsType) => { @@ -158,46 +167,8 @@ export const execClusterConnectionOperation = ( req: express.Request, res: express.Response, ): void => { - try { - const jolokia = res.locals.jolokia; - - const operationRef = req.body as OperationRef; - const strArgs: string[] = []; - let strSignature = operationRef.signature.name + '('; - operationRef.signature.args.forEach((arg, item, array) => { - strSignature = strSignature + arg.type; - if (item < array.length - 1) { - strSignature = strSignature + ','; - } - strArgs.push(arg.value); - }); - strSignature = strSignature + ')'; - - const clusterConnectionName = req.query.name; - - const param = new Map(); - param.set('CLUSTER_CONNECTION_NAME', clusterConnectionName); - - const resp = jolokia.execClusterConnectionOperation( - param, - strSignature, - strArgs, - ); - resp - .then((result: JolokiaExecResponse) => { - res.json(result); - }) - .catch((error: any) => { - logger.error(error); - res.status(500).json({ status: 'error', message: 'server error' }); - }); - } catch (err) { - logger.error(err); - res.status(500).json({ - status: 'error', - message: 'server error: ' + JSON.stringify(err), - }); - } + req.query.type = ComponentType.CLUSTER_CONNECTION; + execMBeanOperation(req, res); }; export const getAcceptors = ( @@ -205,9 +176,9 @@ export const getAcceptors = ( res: express.Response, ): void => { try { - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; - const comps = jolokia.getComponents(ArtemisJolokia.ACCEPTOR); + const comps = jolokia.getComponents(ComponentType.ACCEPTOR); comps .then((result: any[]) => { @@ -241,14 +212,19 @@ export const readAcceptorAttributes = ( res: express.Response, ): void => { try { - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; const acceptorName = req.query.name as string; const acceptorAttrNames = req.query.attrs as string[]; - const attributes = jolokia.readAcceptorAttributes( - acceptorName, + const param = new Map(); + param.set('ACCEPTOR_NAME', acceptorName); + + const attributes = jolokia.readComponentAttributes( + ComponentType.ACCEPTOR, + param, acceptorAttrNames, ); + attributes .then((result: JolokiaReadResponse[]) => { res.json(result); @@ -271,9 +247,9 @@ export const getBrokerComponents = ( res: express.Response, ): void => { try { - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; - const comps = jolokia.getComponents(ArtemisJolokia.BROKER_COMPONENTS); + const comps = jolokia.getComponents(ComponentType.ALL); comps .then((result: any[]) => { @@ -296,9 +272,9 @@ export const getAddresses = ( res: express.Response, ): void => { try { - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; - const comps = jolokia.getComponents(ArtemisJolokia.ADDRESS); + const comps = jolokia.getComponents(ComponentType.ADDRESS); comps .then((result: any[]) => { res.json( @@ -331,14 +307,19 @@ export const readAddressAttributes = ( res: express.Response, ): void => { try { - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; const addressName = req.query.name as string; const addressAttrNames = req.query.attrs as string[]; - const attributes = jolokia.readAddressAttributes( - addressName, + const param = new Map(); + param.set('ADDRESS_NAME', addressName); + + const attributes = jolokia.readComponentAttributes( + ComponentType.ADDRESS, + param, addressAttrNames, ); + attributes .then((result: JolokiaReadResponse[]) => { res.json(result); @@ -363,12 +344,12 @@ export const getQueues = ( try { const addressName = req.query.address || '*'; - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; const param = new Map(); const name = addressName; param.set('ADDRESS_NAME', name); - const comps = jolokia.getComponents(ArtemisJolokia.QUEUE, param); + const comps = jolokia.getComponents(ComponentType.QUEUE, param); comps .then((result: any[]) => { @@ -409,18 +390,23 @@ export const readQueueAttributes = ( res: express.Response, ): void => { try { - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; const queueName = req.query.name as string; const routingType = req.query['routing-type'] as string; const addressName = req.query.address as string; const queueAttrNames = req.query.attrs as string[]; - const attributes = jolokia.readQueueAttributes( - queueName, - routingType, - addressName, + const param = new Map(); + param.set('QUEUE_NAME', queueName); + param.set('ROUTING_TYPE', routingType); + param.set('ADDRESS_NAME', addressName); + + const attributes = jolokia.readComponentAttributes( + ComponentType.QUEUE, + param, queueAttrNames, ); + attributes .then((result: JolokiaReadResponse[]) => { res.json(result); @@ -443,13 +429,15 @@ export const getBrokerDetails = ( res: express.Response, ): void => { try { - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; - const compDetails = jolokia.getBrokerDetails(); + const compDetails = jolokia.readComponentDetails( + ComponentType.BROKER, + null, + ); compDetails .then((result: JolokiaObjectDetailsType) => { - // Update the op to conform to the openapi output format Object.entries(result.op).forEach(([key, value]) => { if (!Array.isArray(value)) { result.op[key] = [value]; @@ -493,37 +481,10 @@ export const execBrokerOperation = ( req: express.Request, res: express.Response, ): void => { - try { - const jolokia = res.locals.jolokia; - - const operationRef = req.body as OperationRef; - const strArgs: string[] = []; - let strSignature = operationRef.signature.name + '('; - operationRef.signature.args.forEach((arg, item, array) => { - strSignature = strSignature + arg.type; - if (item < array.length - 1) { - strSignature = strSignature + ','; - } - strArgs.push(arg.value); - }); - strSignature = strSignature + ')'; - - const resp = jolokia.execBrokerOperation(strSignature, strArgs); - resp - .then((result: JolokiaExecResponse) => { - res.json(result); - }) - .catch((error: any) => { - logger.error(error); - res.status(500).json({ status: 'error', message: 'server error' }); - }); - } catch (err) { - logger.error(err); - res.status(500).json({ - status: 'error', - message: 'server error: ' + JSON.stringify(err), - }); - } + const jolokia = res.locals.jolokia as ArtemisJolokia; + req.query.type = ComponentType.BROKER; + req.query.name = jolokia.brokerName; + execMBeanOperation(req, res); }; export const readBrokerAttributes = ( @@ -531,10 +492,15 @@ export const readBrokerAttributes = ( res: express.Response, ): void => { try { - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; const brokerAttrNames = req.query.names as string[]; - const attributes = jolokia.readBrokerAttributes(brokerAttrNames); + const attributes = jolokia.readComponentAttributes( + ComponentType.BROKER, + null, + brokerAttrNames, + ); + attributes .then((result: JolokiaReadResponse[]) => { res.json(result); @@ -557,14 +523,17 @@ export const getAddressDetails = ( res: express.Response, ): void => { try { - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; const addressName = req.query.name; const param = new Map(); param.set('ADDRESS_NAME', addressName); - const compDetails = jolokia.getAddressDetails(param); + const compDetails = jolokia.readComponentDetails( + ComponentType.ADDRESS, + param, + ); compDetails .then((result: JolokiaObjectDetailsType) => { @@ -593,14 +562,17 @@ export const getAcceptorDetails = ( res: express.Response, ): void => { try { - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; const acceptorName = req.query.name; const param = new Map(); param.set('ACCEPTOR_NAME', acceptorName); - const compDetails = jolokia.getAcceptorDetails(param); + const compDetails = jolokia.readComponentDetails( + ComponentType.ACCEPTOR, + param, + ); compDetails .then((result: JolokiaObjectDetailsType) => { @@ -629,7 +601,7 @@ export const getQueueDetails = ( res: express.Response, ): void => { try { - const jolokia = res.locals.jolokia; + const jolokia = res.locals.jolokia as ArtemisJolokia; const queueName = req.query.name; const addressName = req.query.addressName @@ -642,7 +614,10 @@ export const getQueueDetails = ( param.set('QUEUE_NAME', queueName); param.set('ROUTING_TYPE', routingType); - const compDetails = jolokia.getQueueDetails(param); + const compDetails = jolokia.readComponentDetails( + ComponentType.QUEUE, + param, + ); compDetails .then((result: JolokiaObjectDetailsType) => { @@ -666,6 +641,67 @@ export const getQueueDetails = ( } }; +export const execMBeanOperation = ( + req: express.Request, + res: express.Response, +): void => { + try { + const jolokia = res.locals.jolokia as ArtemisJolokia; + + const operationRef = req.body as OperationRef; + const strArgs: string[] = []; + let strSignature = operationRef.signature.name + '('; + operationRef.signature.args.forEach((arg, item, array) => { + strSignature = strSignature + arg.type; + if (item < array.length - 1) { + strSignature = strSignature + ','; + } + strArgs.push(arg.value); + }); + strSignature = strSignature + ')'; + + const compType = req.query.type as ComponentType; + const compName = req.query.name as string; + + //name1=value,name2=value... + const extrArgs = req.query.extrArgs as string; + const param = new Map(); + if (extrArgs) { + const valueKeyPairs = extrArgs.split(','); + valueKeyPairs.forEach((value) => { + const pair = value.split('='); + if (pair.length === 2) { + param.set(pair[0], pair[1]); + } else { + throw Error('invalid extra arg: ' + value); + } + }); + } + + const resp = jolokia.execComponentOperation( + compType, + compName, + param, + strSignature, + strArgs, + ); + resp + .then((result: JolokiaExecResponse) => { + res.json(result); + }) + .catch((error: any) => { + logger.error(error); + res.status(500).json({ status: 'error', message: 'server error' }); + }); + } catch (err) { + logger.error(err); + res.status(500).json({ + status: 'error', + message: 'server error: ' + JSON.stringify(err), + }); + } +}; + export const apiInfo = (_: express.Request, res: express.Response): void => { res.json({ message: API_SUMMARY,