diff --git a/packages/hawtio/package.json b/packages/hawtio/package.json index 0b2f1aac..a6397556 100644 --- a/packages/hawtio/package.json +++ b/packages/hawtio/package.json @@ -45,13 +45,14 @@ "@types/dagre": "^0.7.50", "@types/dagre-layout": "^0.8.3", "@types/jest": "^29.5.5", + "@types/jquery": "^3.5.19", "@types/node": "^18.18.0", "@types/react": "^18.2.21", "@types/react-dom": "^18.2.7", "@types/react-router-dom": "^5.3.3", "dagre": "^0.8.5", "eventemitter3": "^5.0.1", - "jolokia.js": "^1.7.3-2", + "jolokia.js": "^2.0.0-dev.9", "jquery": "^3.7.1", "js-logger": "^1.6.1", "keycloak-js": "^22.0.3", diff --git a/packages/hawtio/src/plugins/camel/CamelContent.tsx b/packages/hawtio/src/plugins/camel/CamelContent.tsx index a7c30ec3..04682a3a 100644 --- a/packages/hawtio/src/plugins/camel/CamelContent.tsx +++ b/packages/hawtio/src/plugins/camel/CamelContent.tsx @@ -15,7 +15,7 @@ import { Title, } from '@patternfly/react-core' import { CubesIcon } from '@patternfly/react-icons' -import { IResponse } from 'jolokia.js' +import { Response } from 'jolokia.js' import React, { useContext, useEffect, useState } from 'react' import { NavLink, Navigate, Route, Routes, useLocation, useNavigate } from 'react-router-dom' import './CamelContent.css' @@ -198,7 +198,7 @@ const CamelContentContextToolbar: React.FunctionComponent = () => { const attr = await contextsService.getContext(selectedNode) if (attr) setContextState(attr) - contextsService.register({ type: 'read', mbean: objectName }, (response: IResponse) => { + contextsService.register({ type: 'read', mbean: objectName }, (response: Response) => { log.debug('Scheduler - Contexts:', response.value) // Replace the context in the existing set with the new one diff --git a/packages/hawtio/src/plugins/camel/contexts/Contexts.tsx b/packages/hawtio/src/plugins/camel/contexts/Contexts.tsx index f3e95f48..bd23fd22 100644 --- a/packages/hawtio/src/plugins/camel/contexts/Contexts.tsx +++ b/packages/hawtio/src/plugins/camel/contexts/Contexts.tsx @@ -1,11 +1,11 @@ import { eventService } from '@hawtiosrc/core' import { CamelContext } from '@hawtiosrc/plugins/camel/context' -import { AttributeValues } from '@hawtiosrc/plugins/shared/jolokia-service' import { HawtioLoadingCard } from '@hawtiosrc/plugins/shared' +import { AttributeValues } from '@hawtiosrc/plugins/shared/jolokia-service' import { Card, CardBody, Text } from '@patternfly/react-core' import { InfoCircleIcon } from '@patternfly/react-icons' import { Table, TableBody, TableHeader, TableProps, wrappable } from '@patternfly/react-table' -import { IResponse } from 'jolokia.js' +import { Response } from 'jolokia.js' import React, { useContext, useEffect, useState } from 'react' import { log } from '../globals' import { ContextToolbar } from './ContextToolbar' @@ -56,12 +56,12 @@ export const Contexts: React.FunctionComponent = () => { // TODO: we should not invoke setContexts separately from multiple scheduler. // It should cause a bug of overwriting the other updates when we have multiple contexts. - for (const [idx, ctx] of contexts.entries()) { + contexts.forEach((ctx, idx) => { const { objectName } = ctx.node if (!objectName) { - continue + return } - contextsService.register({ type: 'read', mbean: objectName }, (response: IResponse) => { + contextsService.register({ type: 'read', mbean: objectName }, (response: Response) => { log.debug('Scheduler - Contexts:', response.value) // Replace the context in the existing set with the new one @@ -73,7 +73,7 @@ export const Contexts: React.FunctionComponent = () => { newContexts.splice(idx, 1, newCtx) setContexts(newContexts) }) - } + }) return () => contextsService.unregisterAll() }, [selectedNode, contexts]) diff --git a/packages/hawtio/src/plugins/camel/contexts/contexts-service.ts b/packages/hawtio/src/plugins/camel/contexts/contexts-service.ts index 7c75c973..1ac64c9c 100644 --- a/packages/hawtio/src/plugins/camel/contexts/contexts-service.ts +++ b/packages/hawtio/src/plugins/camel/contexts/contexts-service.ts @@ -1,6 +1,6 @@ import { MBeanNode } from '@hawtiosrc/plugins/shared' import { AttributeValues, jolokiaService } from '@hawtiosrc/plugins/shared/jolokia-service' -import { IRequest, IResponseFn } from 'jolokia.js' +import { Request, Response } from 'jolokia.js' import { log } from '../globals' export const CONTEXT_STATE_STARTED = 'Started' @@ -49,7 +49,7 @@ class ContextsService { return ctxAttributes } - async register(request: IRequest, callback: IResponseFn) { + async register(request: Request, callback: (response: Response) => void) { const handle = await jolokiaService.register(request, callback) log.debug('Register handle:', handle) this.handles.push(handle) diff --git a/packages/hawtio/src/plugins/camel/debug/Debug.tsx b/packages/hawtio/src/plugins/camel/debug/Debug.tsx index 6d97e062..bfe068f8 100644 --- a/packages/hawtio/src/plugins/camel/debug/Debug.tsx +++ b/packages/hawtio/src/plugins/camel/debug/Debug.tsx @@ -25,7 +25,7 @@ import { TimesCircleIcon, } from '@patternfly/react-icons' import { TableComposable, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table' -import { IResponse } from 'jolokia.js' +import { Response } from 'jolokia.js' import React, { useCallback, useContext, useEffect, useRef, useState } from 'react' import * as camelService from '../camel-service' import { CamelContext } from '../context' @@ -230,7 +230,7 @@ export const Debug: React.FunctionComponent = () => { mbean: debugNode.objectName, operation: 'getDebugCounter', }, - (response: IResponse) => { + (response: Response) => { log.debug('Scheduler - Debug:', response.value) applyBreakpointCounter(response?.value as number, contextNode) }, diff --git a/packages/hawtio/src/plugins/camel/debug/debug-service.ts b/packages/hawtio/src/plugins/camel/debug/debug-service.ts index 9b77f37f..53cf43e3 100644 --- a/packages/hawtio/src/plugins/camel/debug/debug-service.ts +++ b/packages/hawtio/src/plugins/camel/debug/debug-service.ts @@ -1,7 +1,7 @@ import { MBeanNode, jolokiaService } from '@hawtiosrc/plugins/shared' import { isBlank } from '@hawtiosrc/util/strings' import { childText, xmlText } from '@hawtiosrc/util/xml' -import { IRequest, IResponseFn } from 'jolokia.js' +import { Request, Response } from 'jolokia.js' import { camelPreferencesService } from '../camel-preferences-service' import * as camelService from '../camel-service' import { log } from '../globals' @@ -27,7 +27,7 @@ export interface MessageData { class DebugService { private handles: number[] = [] - async register(request: IRequest, callback: IResponseFn) { + async register(request: Request, callback: (response: Response) => void) { const handle = await jolokiaService.register(request, callback) log.debug('Register handle:', handle) this.handles.push(handle) diff --git a/packages/hawtio/src/plugins/camel/profile/Profile.tsx b/packages/hawtio/src/plugins/camel/profile/Profile.tsx index 21673619..94528f5d 100644 --- a/packages/hawtio/src/plugins/camel/profile/Profile.tsx +++ b/packages/hawtio/src/plugins/camel/profile/Profile.tsx @@ -1,7 +1,7 @@ import { HawtioEmptyCard, HawtioLoadingCard } from '@hawtiosrc/plugins/shared' import { Card, CardBody, CardHeader, CardTitle } from '@patternfly/react-core' import { TableComposable, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table' -import { IResponse } from 'jolokia.js' +import { Response } from 'jolokia.js' import React, { useContext, useEffect, useState } from 'react' import { CamelContext } from '../context' import { log } from '../globals' @@ -33,7 +33,7 @@ export const Profile: React.FunctionComponent = () => { mbean: selectedNode.objectName as string, operation: 'dumpRouteStatsAsXml()', }, - (response: IResponse) => { + (response: Response) => { log.debug('Scheduler - Debug:', response.value) profile() }, diff --git a/packages/hawtio/src/plugins/camel/profile/profile-service.ts b/packages/hawtio/src/plugins/camel/profile/profile-service.ts index 3ea371e9..dc8c8895 100644 --- a/packages/hawtio/src/plugins/camel/profile/profile-service.ts +++ b/packages/hawtio/src/plugins/camel/profile/profile-service.ts @@ -1,5 +1,5 @@ import { MBeanNode, jolokiaService } from '@hawtiosrc/plugins/shared' -import { IRequest, IResponseFn } from 'jolokia.js' +import { Request, Response } from 'jolokia.js' import { log } from '../globals' import { routesService } from '../routes-service' @@ -18,7 +18,7 @@ export type ProfileData = { class ProfileService { private handles: number[] = [] - async register(request: IRequest, callback: IResponseFn) { + async register(request: Request, callback: (response: Response) => void) { const handle = await jolokiaService.register(request, callback) log.debug('Register handle:', handle) this.handles.push(handle) diff --git a/packages/hawtio/src/plugins/camel/rest-services/RestServices.tsx b/packages/hawtio/src/plugins/camel/rest-services/RestServices.tsx index 43fe45dc..39d62d15 100644 --- a/packages/hawtio/src/plugins/camel/rest-services/RestServices.tsx +++ b/packages/hawtio/src/plugins/camel/rest-services/RestServices.tsx @@ -17,7 +17,7 @@ import { ToolbarItem, } from '@patternfly/react-core' import { TableComposable, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table' -import { IResponse } from 'jolokia.js' +import { Response } from 'jolokia.js' import React, { ChangeEvent, MouseEvent, useCallback, useContext, useEffect, useRef, useState } from 'react' import { CamelContext } from '../context' import { log } from '../globals' @@ -75,7 +75,7 @@ export const RestServices: React.FunctionComponent = () => { mbean: selectedNode.objectName as string, operation: 'listRestServices()', }, - (response: IResponse) => { + (response: Response) => { log.debug('Scheduler - Debug:', response.value) fetchRest() }, diff --git a/packages/hawtio/src/plugins/camel/rest-services/rest-services-service.ts b/packages/hawtio/src/plugins/camel/rest-services/rest-services-service.ts index 70f57608..7519e9ed 100644 --- a/packages/hawtio/src/plugins/camel/rest-services/rest-services-service.ts +++ b/packages/hawtio/src/plugins/camel/rest-services/rest-services-service.ts @@ -1,6 +1,6 @@ import { MBeanNode, jolokiaService } from '@hawtiosrc/plugins/shared' import { isObject } from '@hawtiosrc/util/objects' -import { IRequest, IResponseFn } from 'jolokia.js' +import { Request, Response } from 'jolokia.js' import * as camelService from '../camel-service' import { log } from '../globals' @@ -15,7 +15,7 @@ export interface RestService { class RestServicesService { private handles: number[] = [] - async register(request: IRequest, callback: IResponseFn) { + async register(request: Request, callback: (response: Response) => void) { const handle = await jolokiaService.register(request, callback) log.debug('Register handle:', handle) this.handles.push(handle) diff --git a/packages/hawtio/src/plugins/camel/trace/Trace.tsx b/packages/hawtio/src/plugins/camel/trace/Trace.tsx index 5c9f2fdf..3f61d516 100644 --- a/packages/hawtio/src/plugins/camel/trace/Trace.tsx +++ b/packages/hawtio/src/plugins/camel/trace/Trace.tsx @@ -16,7 +16,7 @@ import { } from '@patternfly/react-core' import { BanIcon, PlayIcon } from '@patternfly/react-icons' import { TableComposable, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table' -import { IResponse } from 'jolokia.js' +import { Response } from 'jolokia.js' import React, { useCallback, useContext, useEffect, useRef, useState } from 'react' import * as camelService from '../camel-service' import { CamelContext } from '../context' @@ -123,7 +123,7 @@ export const Trace: React.FunctionComponent = () => { mbean: tracingNode.objectName as string, operation: 'dumpAllTracedMessagesAsXml()', }, - (response: IResponse) => { + (response: Response) => { log.debug('Scheduler - Debug:', response.value) populateRouteMessages(response?.value as string, selectedNode) }, diff --git a/packages/hawtio/src/plugins/camel/trace/tracing-service.ts b/packages/hawtio/src/plugins/camel/trace/tracing-service.ts index d10608d4..5712f877 100644 --- a/packages/hawtio/src/plugins/camel/trace/tracing-service.ts +++ b/packages/hawtio/src/plugins/camel/trace/tracing-service.ts @@ -1,5 +1,5 @@ import { MBeanNode, jolokiaService } from '@hawtiosrc/plugins/shared' -import { IRequest, IResponseFn } from 'jolokia.js' +import { Request, Response } from 'jolokia.js' import { camelPreferencesService } from '../camel-preferences-service' import * as camelService from '../camel-service' import { log } from '../globals' @@ -7,7 +7,7 @@ import { log } from '../globals' class TracingService { private handles: number[] = [] - async register(request: IRequest, callback: IResponseFn) { + async register(request: Request, callback: (response: Response) => void) { const handle = await jolokiaService.register(request, callback) log.debug('Register handle:', handle) this.handles.push(handle) diff --git a/packages/hawtio/src/plugins/quartz/quartz-service.ts b/packages/hawtio/src/plugins/quartz/quartz-service.ts index 4a5428be..b989511b 100644 --- a/packages/hawtio/src/plugins/quartz/quartz-service.ts +++ b/packages/hawtio/src/plugins/quartz/quartz-service.ts @@ -1,9 +1,9 @@ -import { AttributeValues, MBeanNode, jolokiaService, workspace } from '@hawtiosrc/plugins/shared' -import { jmxDomain, log } from './globals' import { eventService } from '@hawtiosrc/core' -import { IRequest } from 'jolokia.js' +import { AttributeValues, MBeanNode, jolokiaService, workspace } from '@hawtiosrc/plugins/shared' import { getQueryParameterValue } from '@hawtiosrc/util/urls' +import { Request } from 'jolokia.js' import { attributeService } from '../shared/attributes/attribute-service' +import { jmxDomain, log } from './globals' export type Trigger = { group: string @@ -159,7 +159,7 @@ class QuartzService { return } - const requests: IRequest[] = triggers.map(trigger => ({ + const requests: Request[] = triggers.map(trigger => ({ type: 'exec', mbean: schedulerMBean, operation: QUARTZ_OPERATIONS.getTriggerState, diff --git a/packages/hawtio/src/plugins/rbac/tree-processor.ts b/packages/hawtio/src/plugins/rbac/tree-processor.ts index bfde4062..6d078d65 100644 --- a/packages/hawtio/src/plugins/rbac/tree-processor.ts +++ b/packages/hawtio/src/plugins/rbac/tree-processor.ts @@ -1,8 +1,15 @@ -import { JolokiaListMethod, MBeanNode, MBeanTree, TreeProcessor, jolokiaService } from '@hawtiosrc/plugins/shared' +import { + JolokiaListMethod, + MBeanNode, + MBeanTree, + OptimisedMBeanOperation, + TreeProcessor, + jolokiaService, +} from '@hawtiosrc/plugins/shared' import { operationToString } from '@hawtiosrc/util/jolokia' import { isString } from '@hawtiosrc/util/objects' import { isBlank } from '@hawtiosrc/util/strings' -import { IJmxOperation, IRequest, IResponse } from 'jolokia.js' +import { Request, Response } from 'jolokia.js' import { log } from './globals' import { rbacService } from './rbac-service' @@ -67,7 +74,7 @@ export const rbacTreeProcessor: TreeProcessor = async (tree: MBeanTree) => { type BulkRequest = { [name: string]: string[] } async function processRBAC(aclMBean: string, mbeans: Record) { - const requests: IRequest[] = [] + const requests: Request[] = [] const bulkRequest: BulkRequest = {} // register canInvoke requests for each MBean and accumulate bulkRequest for all ops Object.entries(mbeans).forEach(([mbeanName, node]) => { @@ -91,7 +98,7 @@ function addCanInvokeRequests( aclMBean: string, mbeanName: string, node: MBeanNode, - requests: IRequest[], + requests: Request[], bulkRequest: BulkRequest, ) { // request for MBean @@ -119,7 +126,7 @@ function addCanInvokeRequests( } } -function addOperation(node: MBeanNode, opList: string[], opName: string, op: IJmxOperation) { +function addOperation(node: MBeanNode, opList: string[], opName: string, op: OptimisedMBeanOperation) { if (!node.mbean) { return } @@ -139,7 +146,7 @@ type BulkResponse = { [name: string]: Operations } type Operations = { [name: string]: Operation } type Operation = { ObjectName: string; Method: string; CanInvoke: boolean } -function applyCanInvoke(mbeans: Record, response: IResponse) { +function applyCanInvoke(mbeans: Record, response: Response) { if (response.request.type !== 'exec') { return } diff --git a/packages/hawtio/src/plugins/runtime/runtime-service.ts b/packages/hawtio/src/plugins/runtime/runtime-service.ts index 3c956d72..78c64333 100644 --- a/packages/hawtio/src/plugins/runtime/runtime-service.ts +++ b/packages/hawtio/src/plugins/runtime/runtime-service.ts @@ -1,6 +1,6 @@ import { jolokiaService } from '@hawtiosrc/plugins/shared' +import { Request, Response } from 'jolokia.js' import { Metric, SystemProperty, Thread } from './types' -import { IRequest, IResponse } from 'jolokia.js' class RuntimeService { handlers: number[] = [] @@ -76,15 +76,15 @@ class RuntimeService { return dumpedThreads } - getRegisterRequest(mbean: string, attribute?: string, args?: string[]): IRequest { - const request: IRequest = { type: 'read', mbean: mbean } + getRegisterRequest(mbean: string, attribute?: string, args?: string[]): Request { + const request: Request = { type: 'read', mbean: mbean } if (attribute) { request.attribute = attribute } return request } - responseCallback(response: IResponse, callback: (metric: Metric) => void) { + responseCallback(response: Response, callback: (metric: Metric) => void) { const req = response.request as { type: 'read'; mbean: string; attribute?: string | string[]; path?: string } switch (req.mbean) { case 'java.lang:type=Threading': { @@ -154,8 +154,8 @@ class RuntimeService { } } - getJolokiaRequests(): IRequest[] { - const requests: IRequest[] = [] + getJolokiaRequests(): Request[] { + const requests: Request[] = [] requests.push(this.getRegisterRequest('java.lang:type=Threading', 'ThreadCount')) requests.push(this.getRegisterRequest('java.lang:type=Memory', 'HeapMemoryUsage')) requests.push(this.getRegisterRequest('java.lang:type=Runtime')) @@ -188,11 +188,11 @@ class RuntimeService { if (bytes === 0) { return [0, 'Bytes'] } - const killobyte = 1024 + const kilobytes = 1024 const decimalPlaces = 2 const units = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] - const i = Math.floor(Math.log(bytes) / Math.log(killobyte)) - const value = parseFloat((bytes / Math.pow(killobyte, i)).toFixed(decimalPlaces)) + const i = Math.floor(Math.log(bytes) / Math.log(kilobytes)) + const value = parseFloat((bytes / Math.pow(kilobytes, i)).toFixed(decimalPlaces)) const unit = units[i] return [value, unit ?? ''] } diff --git a/packages/hawtio/src/plugins/shared/__mocks__/jolokia-service.ts b/packages/hawtio/src/plugins/shared/__mocks__/jolokia-service.ts index 53e41911..fb234f20 100644 --- a/packages/hawtio/src/plugins/shared/__mocks__/jolokia-service.ts +++ b/packages/hawtio/src/plugins/shared/__mocks__/jolokia-service.ts @@ -1,5 +1,5 @@ -import { IRequest, IResponse, IResponseFn, ISimpleOptions } from 'jolokia.js' -import { AttributeValues, IJolokiaService, JolokiaStoredOptions, JolokiaListMethod } from '../jolokia-service' +import { ListRequestOptions, Request, Response } from 'jolokia.js' +import { AttributeValues, IJolokiaService, JolokiaListMethod, JolokiaStoredOptions } from '../jolokia-service' import jmxCamelResponse from './jmx-camel-tree.json' class MockJolokiaService implements IJolokiaService { @@ -15,7 +15,7 @@ class MockJolokiaService implements IJolokiaService { return 0 } - async list(options: ISimpleOptions): Promise { + async list(options: ListRequestOptions): Promise { return jmxCamelResponse } @@ -35,11 +35,11 @@ class MockJolokiaService implements IJolokiaService { return [] } - async bulkRequest(requests: IRequest[]): Promise { + async bulkRequest(requests: Request[]): Promise { return [] } - async register(request: IRequest, callback: IResponseFn): Promise { + async register(request: Request, callback: (response: Response) => void): Promise { return 0 } diff --git a/packages/hawtio/src/plugins/shared/attributes/AttributeTable.tsx b/packages/hawtio/src/plugins/shared/attributes/AttributeTable.tsx index 44949d96..00a08bd8 100644 --- a/packages/hawtio/src/plugins/shared/attributes/AttributeTable.tsx +++ b/packages/hawtio/src/plugins/shared/attributes/AttributeTable.tsx @@ -4,7 +4,7 @@ import { AttributeValues } from '@hawtiosrc/plugins/shared/jolokia-service' import { humanizeLabels } from '@hawtiosrc/util/strings' import { Card } from '@patternfly/react-core' import { Table, TableBody, TableHeader, TableProps } from '@patternfly/react-table' -import { IResponse } from 'jolokia.js' +import { Response } from 'jolokia.js' import { useContext, useEffect, useState } from 'react' import { HawtioEmptyCard } from '../HawtioEmptyCard' import { HawtioLoadingCard } from '../HawtioLoadingCard' @@ -65,7 +65,7 @@ export const AttributeTable: React.FunctionComponent = () => { if (!node || !node?.objectName) return const mbean = node.objectName - attributeService.register({ type: 'read', mbean }, (response: IResponse) => { + attributeService.register({ type: 'read', mbean }, (response: Response) => { setAttributesList(attributesList => { attributesList[mbean] = response.value as AttributeValues return { ...attributesList } diff --git a/packages/hawtio/src/plugins/shared/attributes/Attributes.tsx b/packages/hawtio/src/plugins/shared/attributes/Attributes.tsx index 6be21672..00034b03 100644 --- a/packages/hawtio/src/plugins/shared/attributes/Attributes.tsx +++ b/packages/hawtio/src/plugins/shared/attributes/Attributes.tsx @@ -3,7 +3,7 @@ import { AttributeValues } from '@hawtiosrc/plugins/shared/jolokia-service' import { isObject } from '@hawtiosrc/util/objects' import { Card } from '@patternfly/react-core' import { OnRowClick, Table, TableBody, TableHeader, TableProps } from '@patternfly/react-table' -import { IResponse } from 'jolokia.js' +import { Response } from 'jolokia.js' import { useContext, useEffect, useState } from 'react' import { HawtioEmptyCard } from '../HawtioEmptyCard' import { HawtioLoadingCard } from '../HawtioLoadingCard' @@ -39,7 +39,7 @@ export const Attributes: React.FunctionComponent = () => { } const mbean = selectedNode.objectName - attributeService.register({ type: 'read', mbean }, (response: IResponse) => { + attributeService.register({ type: 'read', mbean }, (response: Response) => { log.debug('Scheduler - Attributes:', response.value) setAttributes(response.value as AttributeValues) }) diff --git a/packages/hawtio/src/plugins/shared/attributes/attribute-service.ts b/packages/hawtio/src/plugins/shared/attributes/attribute-service.ts index a354eb0f..7382b153 100644 --- a/packages/hawtio/src/plugins/shared/attributes/attribute-service.ts +++ b/packages/hawtio/src/plugins/shared/attributes/attribute-service.ts @@ -1,6 +1,6 @@ import { AttributeValues, jolokiaService } from '@hawtiosrc/plugins/shared/jolokia-service' import { escapeMBean } from '@hawtiosrc/util/jolokia' -import { IRequest, IResponseFn } from 'jolokia.js' +import { Request, Response } from 'jolokia.js' import { log } from '../globals' class AttributeService { @@ -10,7 +10,7 @@ class AttributeService { return await jolokiaService.readAttributes(mbean) } - async register(request: IRequest, callback: IResponseFn) { + async register(request: Request, callback: (response: Response) => void) { const handle = await jolokiaService.register(request, callback) log.debug('Register handle:', handle) this.handles.push(handle) diff --git a/packages/hawtio/src/plugins/shared/chart/Chart.tsx b/packages/hawtio/src/plugins/shared/chart/Chart.tsx index c98db627..2f7ff4da 100644 --- a/packages/hawtio/src/plugins/shared/chart/Chart.tsx +++ b/packages/hawtio/src/plugins/shared/chart/Chart.tsx @@ -14,7 +14,7 @@ import { Text, } from '@patternfly/react-core' import { InfoCircleIcon } from '@patternfly/react-icons' -import { IResponse } from 'jolokia.js' +import { Response } from 'jolokia.js' import React, { useContext, useEffect, useRef, useState } from 'react' import { HawtioEmptyCard } from '../HawtioEmptyCard' import { HawtioLoadingCard } from '../HawtioLoadingCard' @@ -97,7 +97,7 @@ export const Chart: React.FunctionComponent = () => { ): Promise { if (!node || !node?.objectName) return - attributeService.register({ type: 'read', mbean: node.objectName }, (response: IResponse) => { + attributeService.register({ type: 'read', mbean: node.objectName }, (response: Response) => { updateCallback(node.name, { name: node.name, time: response.timestamp, diff --git a/packages/hawtio/src/plugins/shared/connect-service.ts b/packages/hawtio/src/plugins/shared/connect-service.ts index 94e8d756..670bc4a5 100644 --- a/packages/hawtio/src/plugins/shared/connect-service.ts +++ b/packages/hawtio/src/plugins/shared/connect-service.ts @@ -1,7 +1,7 @@ import { hawtio } from '@hawtiosrc/core' import { toString } from '@hawtiosrc/util/strings' import { joinPaths } from '@hawtiosrc/util/urls' -import Jolokia, { IJolokia } from 'jolokia.js' +import Jolokia from 'jolokia.js' import { log } from './globals' export type Connections = { @@ -152,7 +152,7 @@ class ConnectService implements IConnectService { /** * Create a Jolokia instance with the given connection. */ - private createJolokia(connection: Connection, checkCredentials = false): IJolokia { + private createJolokia(connection: Connection, checkCredentials = false): Jolokia { if (checkCredentials) { return new Jolokia({ url: this.getJolokiaUrl(connection), diff --git a/packages/hawtio/src/plugins/shared/jolokia-service.test.ts b/packages/hawtio/src/plugins/shared/jolokia-service.test.ts index 3f42abe6..de9b6934 100644 --- a/packages/hawtio/src/plugins/shared/jolokia-service.test.ts +++ b/packages/hawtio/src/plugins/shared/jolokia-service.test.ts @@ -1,11 +1,11 @@ +import Jolokia, { ErrorResponse, ListRequestOptions } from 'jolokia.js' import { DEFAULT_MAX_COLLECTION_SIZE, DEFAULT_MAX_DEPTH, JolokiaListMethod, - jolokiaService, __testing_jolokia_service__, + jolokiaService, } from './jolokia-service' -import { IJolokia, IListOptions, IErrorResponse } from 'jolokia.js' const { JolokiaService, DummyJolokia } = __testing_jolokia_service__ @@ -17,7 +17,8 @@ class ListJolokiaTest extends DummyJolokia { this.fireSuccess = fireSuccess } - list(path: string, opts?: IListOptions) { + list(path?: string | string[] | ListRequestOptions, opts?: ListRequestOptions) { + if (typeof path !== 'string') throw new Error('String is expected for path') if (!opts) throw new Error('No options set') if (this.fireSuccess) { @@ -33,7 +34,7 @@ class ListJolokiaTest extends DummyJolokia { } else { if (!opts.error) throw new Error('No error option set') - const response: IErrorResponse = { + const response: ErrorResponse = { status: -1, timestamp: 123456789, request: { type: 'list', path: path }, @@ -51,7 +52,7 @@ class ListJolokiaTest extends DummyJolokia { } class JolokiaServiceTest extends JolokiaService { - checkListOptimisationTest(jolokia: IJolokia): Promise { + checkListOptimisationTest(jolokia: Jolokia): Promise { return this.checkListOptimisation(jolokia) } } diff --git a/packages/hawtio/src/plugins/shared/jolokia-service.ts b/packages/hawtio/src/plugins/shared/jolokia-service.ts index 97d0c0b9..78b853d5 100644 --- a/packages/hawtio/src/plugins/shared/jolokia-service.ts +++ b/packages/hawtio/src/plugins/shared/jolokia-service.ts @@ -4,32 +4,30 @@ import { basicAuthHeaderValue, getCookie } from '@hawtiosrc/util/https' import { escapeMBeanPath, onBulkSuccessAndError, + onExecuteSuccessAndError, onListSuccessAndError, - onSimpleSuccessAndError, + onSearchSuccessAndError, onSuccessAndError, + onVersionSuccessAndError, } from '@hawtiosrc/util/jolokia' import { isObject } from '@hawtiosrc/util/objects' import { parseBoolean } from '@hawtiosrc/util/strings' import Jolokia, { - IAjaxErrorFn, - IErrorResponse, - IErrorResponseFn, - IJmxDomain, - IJmxDomains, - IJmxMBean, - IJolokia, - IListOptions, - IListResponseFn, - IOptions, - IRequest, - IResponse, - IResponseFn, - ISearchOptions, - ISimpleOptions, - IVersion, - IVersionOptions, + AttributeRequestOptions, + BaseRequestOptions, + ErrorResponse, + ListRequestOptions, + ListResponse, + NotificationMode, + NotificationOptions, + Request, + RequestOptions, + Response, + SearchRequestOptions, + VersionRequestOptions, + VersionResponse, } from 'jolokia.js' -import 'jolokia.js/jolokia-simple' +import 'jolokia.js/simple' import $ from 'jquery' import { func, is, object } from 'superstruct' import { PARAM_KEY_CONNECTION, connectService } from '../shared/connect-service' @@ -37,13 +35,12 @@ import { log } from './globals' export const DEFAULT_MAX_DEPTH = 7 export const DEFAULT_MAX_COLLECTION_SIZE = 50000 -const DEFAULT_JOLOKIA_OPTIONS: IOptions = { - method: 'POST', +const DEFAULT_JOLOKIA_OPTIONS: RequestOptions = { + method: 'post', mimeType: 'application/json', maxCollectionSize: DEFAULT_MAX_COLLECTION_SIZE, maxDepth: DEFAULT_MAX_DEPTH, canonicalNaming: false, - canonicalProperties: false, ignoreErrors: true, } as const @@ -86,13 +83,13 @@ export const STORAGE_KEY_AUTO_REFRESH = 'connect.jolokia.autoRefresh' export interface IJolokiaService { getJolokiaUrl(): Promise getListMethod(): Promise - list(options: ISimpleOptions): Promise + list(options: ListRequestOptions): Promise readAttributes(mbean: string): Promise readAttribute(mbean: string, attribute: string): Promise execute(mbean: string, operation: string, args?: unknown[]): Promise search(mbeanPattern: string): Promise - bulkRequest(requests: IRequest[]): Promise - register(request: IRequest, callback: IResponseFn): Promise + bulkRequest(requests: Request[]): Promise + register(request: Request, callback: (response: Response | ErrorResponse) => void): Promise unregister(handle: number): void loadUpdateRate(): number saveUpdateRate(value: number): void @@ -104,7 +101,7 @@ export interface IJolokiaService { class JolokiaService implements IJolokiaService { private jolokiaUrl: Promise - private jolokia: Promise + private jolokia: Promise private config: JolokiaConfig = { method: JolokiaListMethod.DEFAULT, mbean: OPTIMISED_JOLOKIA_LIST_MBEAN, @@ -116,6 +113,15 @@ class JolokiaService implements IJolokiaService { // Start Jolokia this.jolokia.then(jolokia => { + // Checking versions first + jolokia.version( + onVersionSuccessAndError( + version => { + log.info('Jolokia version:', { client: jolokia.CLIENT_VERSION, agent: version.agent }) + }, + error => log.error('Failed to fetch Jolokia version:', error), + ), + ) const updateRate = this.loadUpdateRate() jolokia.start(updateRate) log.info('Jolokia started with update rate =', updateRate) @@ -181,7 +187,7 @@ class JolokiaService implements IJolokiaService { }) } - private async createJolokia(): Promise { + private async createJolokia(): Promise { const jolokiaUrl = await this.jolokiaUrl if (!jolokiaUrl) { log.debug('Use dummy Jolokia') @@ -242,7 +248,7 @@ class JolokiaService implements IJolokiaService { } } - private ajaxError(): IAjaxErrorFn { + private ajaxError(): JQueryAjaxError { const errorThreshold = 2 let errorCount = 0 return (xhr: JQueryXHR) => { @@ -293,10 +299,10 @@ class JolokiaService implements IJolokiaService { * * @param jolokia Jolokia instance to use */ - protected async checkListOptimisation(jolokia: IJolokia): Promise { + protected async checkListOptimisation(jolokia: Jolokia): Promise { log.debug('Check if we can call optimised jolokia.list() operation') return new Promise(resolve => { - const successFn: IListResponseFn = (value: IJmxDomains | IJmxDomain | IJmxMBean) => { + const successFn: NonNullable = (value: ListResponse) => { // check if the MBean exists by testing whether the returned value has // the 'op' property if (isObject(value?.op)) { @@ -310,7 +316,7 @@ class JolokiaService implements IJolokiaService { resolve() } - const errorFn: IErrorResponseFn = (response: IErrorResponse) => { + const errorFn: NonNullable = (response: ErrorResponse) => { log.debug('Operation "list" failed due to:', response.error) log.debug('Optimisation on jolokia.list() not available') resolve() // optimisation not happening @@ -320,7 +326,7 @@ class JolokiaService implements IJolokiaService { }) } - private async loadJolokiaOptions(): Promise { + private async loadJolokiaOptions(): Promise { const opts = { ...DEFAULT_JOLOKIA_OPTIONS, ...this.loadJolokiaStoredOptions() } const jolokiaUrl = await this.jolokiaUrl @@ -338,7 +344,7 @@ class JolokiaService implements IJolokiaService { return this.config.method } - async list(options: ISimpleOptions): Promise { + async list(options: ListRequestOptions): Promise { const jolokia = await this.jolokia const { method, mbean } = this.config @@ -351,7 +357,7 @@ class JolokiaService implements IJolokiaService { jolokia.execute( mbean, 'list()', - onSimpleSuccessAndError( + onListSuccessAndError( value => resolve(value), error => reject(error), options, @@ -363,7 +369,6 @@ class JolokiaService implements IJolokiaService { default: log.debug('Invoke Jolokia list MBean in default mode') jolokia.list( - null, onListSuccessAndError( value => resolve(value), error => reject(error), @@ -429,7 +434,7 @@ class JolokiaService implements IJolokiaService { mbean, operation, ...args, - onSimpleSuccessAndError( + onExecuteSuccessAndError( response => resolve(response), error => reject(error.stacktrace || error.error), ), @@ -442,7 +447,7 @@ class JolokiaService implements IJolokiaService { return new Promise(resolve => { jolokia.search( mbeanPattern, - onSimpleSuccessAndError( + onSearchSuccessAndError( response => resolve(response as string[]), error => { log.error('Error during search:', error) @@ -453,10 +458,10 @@ class JolokiaService implements IJolokiaService { }) } - async bulkRequest(requests: IRequest[]): Promise { + async bulkRequest(requests: Request[]): Promise { const jolokia = await this.jolokia return new Promise(resolve => { - const bulkResponse: IResponse[] = [] + const bulkResponse: Response[] = [] jolokia.request( requests, onBulkSuccessAndError( @@ -476,7 +481,7 @@ class JolokiaService implements IJolokiaService { }) } - async register(request: IRequest, callback: IResponseFn): Promise { + async register(request: Request, callback: (response: Response) => void): Promise { const jolokia = await this.jolokia return jolokia.register(callback, request) } @@ -518,14 +523,16 @@ class JolokiaService implements IJolokiaService { } type JQueryBeforeSend = (this: unknown, jqXHR: JQueryXHR, settings: unknown) => false | void +type JQueryAjaxError = (xhr: JQueryXHR, text: string, error: string) => void -export type AttributeValues = { [name: string]: unknown } +export type AttributeValues = Record +/* eslint-disable @typescript-eslint/no-unused-vars */ /** * Dummy Jolokia implementation that does nothing. */ -/* eslint-disable @typescript-eslint/no-unused-vars */ -class DummyJolokia implements IJolokia { +class DummyJolokia implements Jolokia { + CLIENT_VERSION = 'DUMMY' isDummy = true private running = false @@ -533,7 +540,15 @@ class DummyJolokia implements IJolokia { return null } - getAttribute(mbean: string, attribute: string, path?: string | ISimpleOptions, opts?: ISimpleOptions) { + getAttribute( + mbean: string, + attribute: string, + path?: string | AttributeRequestOptions, + opts?: AttributeRequestOptions, + ) { + if (typeof path !== 'string') { + path?.success?.({}) + } opts?.success?.({}) return null } @@ -541,9 +556,12 @@ class DummyJolokia implements IJolokia { mbean: string, attribute: string, value: unknown, - path?: string | ISimpleOptions, - opts?: ISimpleOptions, + path?: string | AttributeRequestOptions, + opts?: AttributeRequestOptions, ) { + if (typeof path !== 'string') { + path?.success?.({}) + } opts?.success?.({}) } @@ -551,24 +569,27 @@ class DummyJolokia implements IJolokia { args?.forEach(arg => is(arg, object({ success: func() })) && arg.success?.(null)) return null } - search(mBeanPattern: string, opts?: ISearchOptions) { + search(mbeanPattern: string, opts?: SearchRequestOptions) { opts?.success?.([]) return null } - list(path: string, opts?: IListOptions) { + list(path?: string | string[] | ListRequestOptions, opts?: ListRequestOptions) { + if (typeof path !== 'string' && !Array.isArray(path)) { + path?.success?.({}) + } opts?.success?.({}) return null } - version(opts?: IVersionOptions) { - opts?.success?.({} as IVersion) - return {} as IVersion + version(opts?: VersionRequestOptions) { + opts?.success?.({} as VersionResponse) + return {} as VersionResponse } register(params: unknown, ...request: unknown[]) { return 0 } unregister(handle: number) { - /* no-op */ + // no-op } jobs() { return [] @@ -582,6 +603,16 @@ class DummyJolokia implements IJolokia { isRunning() { return this.running } + + addNotificationListener(opts: NotificationOptions) { + // no-op + } + removeNotificationListener(handle: { id: string; mode: NotificationMode }) { + // no-op + } + unregisterNotificationClient() { + // no-op + } } /* eslint-enable @typescript-eslint/no-unused-vars */ diff --git a/packages/hawtio/src/plugins/shared/operations/operation.ts b/packages/hawtio/src/plugins/shared/operations/operation.ts index 61dda6f2..d522eb35 100644 --- a/packages/hawtio/src/plugins/shared/operations/operation.ts +++ b/packages/hawtio/src/plugins/shared/operations/operation.ts @@ -1,10 +1,10 @@ import { stringSorter, trimEnd } from '@hawtiosrc/util/strings' -import { IJmxOperation, IJmxOperations } from 'jolokia.js' +import { OptimisedMBeanOperation, OptimisedMBeanOperations } from '../tree' /** * Factory function for Operation objects. */ -export function createOperations(objectName: string, jmxOperations: IJmxOperations): Operation[] { +export function createOperations(objectName: string, jmxOperations: OptimisedMBeanOperations): Operation[] { const operations: Operation[] = [] const operationMap: Record = {} Object.entries(jmxOperations).forEach(([name, op]) => { @@ -21,7 +21,7 @@ function addOperation( operations: Operation[], operationMap: Record, name: string, - op: IJmxOperation, + op: OptimisedMBeanOperation, ): void { const operation = new Operation( name, diff --git a/packages/hawtio/src/plugins/shared/tree/node.ts b/packages/hawtio/src/plugins/shared/tree/node.ts index d45dbf72..78420f8f 100644 --- a/packages/hawtio/src/plugins/shared/tree/node.ts +++ b/packages/hawtio/src/plugins/shared/tree/node.ts @@ -3,7 +3,7 @@ import { isEmpty } from '@hawtiosrc/util/objects' import { matchWithWildcard, stringSorter, trimQuotes } from '@hawtiosrc/util/strings' import { TreeViewDataItem } from '@patternfly/react-core' import { CubeIcon, FolderIcon, FolderOpenIcon, LockIcon } from '@patternfly/react-icons' -import { IJmxMBean, IJmxOperation, IJmxOperations } from 'jolokia.js' +import { MBeanAttribute, MBeanInfo, MBeanOperation } from 'jolokia.js' import React from 'react' import { log } from './globals' @@ -14,16 +14,25 @@ export const Icons = { locked: React.createElement(LockIcon), } as const -export type OptimisedJmxDomains = { - [domainName: string]: OptimisedJmxDomain +export type OptimisedJmxDomains = Record + +export type OptimisedJmxDomain = Record + +export interface OptimisedMBeanInfo extends Omit { + attr?: Record + op?: OptimisedMBeanOperations + opByString?: Record + canInvoke?: boolean } -export type OptimisedJmxDomain = { - [propertyList: string]: OptimisedJmxMBean +export interface OptimisedMBeanAttribute extends MBeanAttribute { + canInvoke?: boolean } -export interface OptimisedJmxMBean extends IJmxMBean { - opByString?: { [name: string]: IJmxOperation } +export type OptimisedMBeanOperations = Record + +export interface OptimisedMBeanOperation extends MBeanOperation { + canInvoke?: boolean } export type MBeanNodeFilterFn = (node: MBeanNode) => boolean @@ -47,7 +56,7 @@ export class MBeanNode implements TreeViewDataItem { // MBean info objectName?: string - mbean?: OptimisedJmxMBean + mbean?: OptimisedMBeanInfo propertyList?: PropertyList // TreeViewDataItem properties @@ -104,13 +113,13 @@ export class MBeanNode implements TreeViewDataItem { } } - populateMBean(propList: string, mbean: OptimisedJmxMBean) { + populateMBean(propList: string, mbean: OptimisedMBeanInfo) { log.debug(' JMX tree mbean:', propList) const props = new PropertyList(this, propList) this.createMBeanNode(props.getPaths(), props, mbean) } - private createMBeanNode(paths: string[], props: PropertyList, mbean: OptimisedJmxMBean) { + private createMBeanNode(paths: string[], props: PropertyList, mbean: OptimisedMBeanInfo) { log.debug(' JMX tree property:', paths[0]) if (paths.length === 1) { // final mbean node @@ -131,7 +140,7 @@ export class MBeanNode implements TreeViewDataItem { child.createMBeanNode(paths, props, mbean) } - private configureMBean(propList: PropertyList, mbean: OptimisedJmxMBean) { + private configureMBean(propList: PropertyList, mbean: OptimisedMBeanInfo) { this.objectName = propList.objectName() this.mbean = mbean this.propertyList = propList @@ -512,8 +521,8 @@ export class MBeanNode implements TreeViewDataItem { * Returns true only if all relevant operations can be invoked. */ private resolveCanInvokeInOps( - ops: IJmxOperations, - opsByString: Record, + ops: OptimisedMBeanOperations, + opsByString: Record, methods: string[], ): boolean { let canInvoke = true @@ -536,7 +545,7 @@ export class MBeanNode implements TreeViewDataItem { return canInvoke } - private resolveCanInvoke(op: IJmxOperation | IJmxOperation[]): boolean { + private resolveCanInvoke(op: OptimisedMBeanOperation | OptimisedMBeanOperation[]): boolean { // for single method if (!Array.isArray(op)) { return op.canInvoke ?? true diff --git a/packages/hawtio/src/plugins/shared/workspace.ts b/packages/hawtio/src/plugins/shared/workspace.ts index 35797ea2..9b8db2c2 100644 --- a/packages/hawtio/src/plugins/shared/workspace.ts +++ b/packages/hawtio/src/plugins/shared/workspace.ts @@ -1,10 +1,10 @@ import { eventService, Logger } from '@hawtiosrc/core' import { jolokiaService } from '@hawtiosrc/plugins/shared/jolokia-service' import { isString } from '@hawtiosrc/util/objects' -import { IErrorResponse, IResponse, ISimpleOptions } from 'jolokia.js' +import { ErrorResponse, ListRequestOptions, Response } from 'jolokia.js' import { is, object } from 'superstruct' import { pluginName } from './globals' -import { MBeanNode, MBeanTree, OptimisedJmxDomain, OptimisedJmxDomains, OptimisedJmxMBean } from './tree' +import { MBeanNode, MBeanTree, OptimisedJmxDomain, OptimisedJmxDomains, OptimisedMBeanInfo } from './tree' const log = Logger.get(`${pluginName}-workspace`) @@ -34,9 +34,9 @@ class Workspace implements IWorkspace { private async loadTree(): Promise { log.debug('Load JMX MBean tree') - const options: ISimpleOptions = { + const options: ListRequestOptions = { ignoreErrors: true, - error: (response: IErrorResponse) => { + error: (response: ErrorResponse) => { log.debug('Error fetching JMX tree:', response) }, ajaxError: (xhr: JQueryXHR) => { @@ -75,7 +75,7 @@ class Workspace implements IWorkspace { for (const mbeanName in domain) { const mbeanOrCache = domain[mbeanName] if (isString(mbeanOrCache)) { - domain[mbeanName] = value.cache[mbeanOrCache] as OptimisedJmxMBean + domain[mbeanName] = value.cache[mbeanOrCache] as OptimisedMBeanInfo } } } @@ -99,7 +99,7 @@ class Workspace implements IWorkspace { mbean: HAWTIO_REGISTRY_MBEAN, attribute: 'UpdateCounter', }, - (response: IResponse) => this.maybeUpdatePlugins(response), + (response: Response) => this.maybeUpdatePlugins(response), ) } } else { @@ -128,7 +128,7 @@ class Workspace implements IWorkspace { mbean: HAWTIO_TREE_WATCHER_MBEAN, attribute: 'Counter', }, - (response: IResponse) => this.maybeReloadTree(response), + (response: Response) => this.maybeReloadTree(response), ) } } else { @@ -141,7 +141,7 @@ class Workspace implements IWorkspace { } } - private maybeUpdatePlugins(response: IResponse) { + private maybeUpdatePlugins(response: Response) { const counter = response.value as number if (!this.pluginUpdateCounter) { // Initial counter setting @@ -160,7 +160,7 @@ class Workspace implements IWorkspace { } } - private maybeReloadTree(response: IResponse) { + private maybeReloadTree(response: Response) { const counter = response.value as number if (!this.treeWatcherCounter) { // Initial counter setting diff --git a/packages/hawtio/src/util/jolokia.ts b/packages/hawtio/src/util/jolokia.ts index 39188bbe..3f63a314 100644 --- a/packages/hawtio/src/util/jolokia.ts +++ b/packages/hawtio/src/util/jolokia.ts @@ -1,95 +1,85 @@ import { Logger } from '@hawtiosrc/core' import { - IBulkOptions, - IErrorResponse, - IErrorResponseFn, - IJmxOperationArgument, - IListOptions, - IListResponseFn, - IOptions, - IOptionsBase, - IResponseFn, - ISearchOptions, - ISearchResponseFn, - ISimpleOptions, - ISimpleResponseFn, - IVersionOptions, - IVersionResponseFn, + AttributeRequestOptions, + BaseRequestOptions, + BulkRequestOptions, + ErrorResponse, + ExecuteRequestOptions, + ListRequestOptions, + MBeanOperationArgument, + RequestOptions, + SearchRequestOptions, + VersionRequestOptions, } from 'jolokia.js' const log = Logger.get('hawtio-util') -export function onSuccess(successFn: IResponseFn, options: IOptions = {}): IOptions { - return onGenericSuccess(successFn, options) -} - -export function onSuccessAndError(successFn: IResponseFn, errorFn: IErrorResponseFn, options: IOptions = {}): IOptions { +export function onSuccessAndError( + successFn: NonNullable, + errorFn: NonNullable, + options: BaseRequestOptions = {}, +): RequestOptions { return onGenericSuccessAndError(successFn, errorFn, options) } -export function onSimpleSuccess(successFn: ISimpleResponseFn, options: ISimpleOptions = {}): ISimpleOptions { - return onGenericSuccess(successFn, options) +export function onAttributeSuccessAndError( + successFn: NonNullable, + errorFn: NonNullable, + options: AttributeRequestOptions = {}, +): AttributeRequestOptions { + return onGenericSuccessAndError(successFn, errorFn, options) } -export function onSimpleSuccessAndError( - successFn: ISimpleResponseFn, - errorFn: IErrorResponseFn, - options: ISimpleOptions = {}, -): ISimpleOptions { +export function onExecuteSuccessAndError( + successFn: NonNullable, + errorFn: NonNullable, + options: ExecuteRequestOptions = {}, +): ExecuteRequestOptions { return onGenericSuccessAndError(successFn, errorFn, options) } -export function onSearchSuccess(successFn: ISearchResponseFn, options: ISearchOptions = {}): ISearchOptions { - return onGenericSuccess(successFn, options) +export function onSearchSuccessAndError( + successFn: NonNullable, + errorFn: NonNullable, + options: SearchRequestOptions = {}, +): SearchRequestOptions { + return onGenericSuccessAndError(successFn, errorFn, options) } export function onListSuccessAndError( - successFn: IListResponseFn, - errorFn: IErrorResponseFn, - options: IListOptions = {}, -): IListOptions { + successFn: NonNullable, + errorFn: NonNullable, + options: ListRequestOptions = {}, +): ListRequestOptions { return onGenericSuccessAndError(successFn, errorFn, options) } -export function onVersionSuccess(successFn: IVersionResponseFn, options: IVersionOptions = {}): IVersionOptions { - return onGenericSuccess(successFn, options) -} - export function onVersionSuccessAndError( - successFn: IVersionResponseFn, - errorFn: IErrorResponseFn, - options: IVersionOptions = {}, -): IVersionOptions { + successFn: NonNullable, + errorFn: NonNullable, + options: VersionRequestOptions = {}, +): VersionRequestOptions { return onGenericSuccessAndError(successFn, errorFn, options) } -export function onBulkSuccess(successFn: IResponseFn | IResponseFn[], options: IBulkOptions = {}): IBulkOptions { - return onGenericSuccess(successFn, options) -} - export function onBulkSuccessAndError( - successFn: IResponseFn | IResponseFn[], - errorFn: IErrorResponseFn, - options: IBulkOptions = {}, -): IBulkOptions { + successFn: NonNullable, + errorFn: NonNullable, + options: BulkRequestOptions = {}, +): BulkRequestOptions { return onGenericSuccessAndError(successFn, errorFn, options) } -export function onGenericSuccess(successFn: R, options?: O): O { - return onGenericSuccessAndError(successFn, defaultErrorHandler(options), options) +export function onGenericSuccess(successFn: S, options?: O): O { + return onGenericSuccessAndError(successFn, defaultErrorHandler(), options) } -export function onGenericSuccessAndError( - successFn: R, - errorFn: IErrorResponseFn, - options?: O, -): O { - const defaultOptions: IOptionsBase = { - method: 'POST', +export function onGenericSuccessAndError(successFn: S, errorFn: E, options?: O): O { + const defaultOptions: BaseRequestOptions = { + method: 'post', mimeType: 'application/json', // the default (unsorted) order is important for Karaf runtime canonicalNaming: false, - canonicalProperties: false, } return Object.assign({}, defaultOptions, options, { success: successFn, @@ -101,17 +91,15 @@ export function onGenericSuccessAndError( * The default error handler which logs errors either using debug or log level logging * based on the silent setting. */ -function defaultErrorHandler(options?: IOptionsBase): IErrorResponseFn { - return (response: IErrorResponse) => { +function defaultErrorHandler(): NonNullable { + return (response: ErrorResponse) => { if (!response.error) { return } const req = response.request const operation = req?.type === 'exec' ? req.operation : 'unknown' - // 'silent' is a custom option only defined in Hawtio - const silent = options?.silent - if (silent || isIgnorableException(response)) { + if (isIgnorableException(response)) { log.debug('Operation', operation, 'failed due to:', response.error) } else { log.warn('Operation', operation, 'failed due to:', response.error) @@ -125,7 +113,7 @@ function defaultErrorHandler(options?: IOptionsBase): IErrorResponseFn { * * @param response the error response from a Jolokia request */ -function isIgnorableException(response: IErrorResponse): boolean { +function isIgnorableException(response: ErrorResponse): boolean { const ignorables = [ 'InstanceNotFoundException', 'AttributeNotFoundException', @@ -164,7 +152,7 @@ function applyJolokiaEscapeRules(mbean: string): string { return mbean.replace(/!/g, '!!').replace(/\//g, '!/').replace(/"/g, '!"') } -export function operationToString(operation: string, args: IJmxOperationArgument[]): string { +export function operationToString(operation: string, args: MBeanOperationArgument[]): string { const argsStr = args.map(arg => arg.type).join(',') return `${operation}(${argsStr})` } diff --git a/yarn.lock b/yarn.lock index 77d4c0f7..c78b4fb6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2447,6 +2447,7 @@ __metadata: "@types/dagre": ^0.7.50 "@types/dagre-layout": ^0.8.3 "@types/jest": ^29.5.5 + "@types/jquery": ^3.5.19 "@types/node": ^18.18.0 "@types/react": ^18.2.21 "@types/react-dom": ^18.2.7 @@ -2458,7 +2459,7 @@ __metadata: jest-environment-jsdom: ^29.7.0 jest-fetch-mock: ^3.0.3 jest-watch-typeahead: ^2.2.2 - jolokia.js: ^1.7.3-2 + jolokia.js: ^2.0.0-dev.9 jquery: ^3.7.1 js-logger: ^1.6.1 keycloak-js: ^22.0.3 @@ -4517,12 +4518,12 @@ __metadata: languageName: node linkType: hard -"@types/jquery@npm:^3.5.14": - version: 3.5.14 - resolution: "@types/jquery@npm:3.5.14" +"@types/jquery@npm:^3.5.19": + version: 3.5.19 + resolution: "@types/jquery@npm:3.5.19" dependencies: "@types/sizzle": "*" - checksum: 159d6f804ed1a204b3f79f2d591a271d82e866bd45bd49fb6ef40561a25dbe0f47ec7815681b44cc2db5598425f72811e7e80ab0e983d980470998ac56feb375 + checksum: 0298e53a353089e2abae4be2f660b5f2bfb4797464623701c5c2f2c911317b554f1887c2c3d587d0f724d70a3fb5e31907bf7fa5d96df33af07e2842660ef52a languageName: node linkType: hard @@ -12405,12 +12406,20 @@ __metadata: languageName: node linkType: hard -"jolokia.js@npm:^1.7.3-2": - version: 1.7.3-2 - resolution: "jolokia.js@npm:1.7.3-2" +"jolokia.js@npm:^2.0.0-dev.9": + version: 2.0.0-dev.9 + resolution: "jolokia.js@npm:2.0.0-dev.9" dependencies: - "@types/jquery": ^3.5.14 - checksum: e5f69db02ede1ef1e775f6b22a0bf071bd98f9f0485cf2c1d81e5bd15f68cbf915db71c44493219440f62f65aae941a11235af106a02a7c678b129fa6bdaf255 + jquery: ^3.7.1 + peerDependencies: + cubism: ^1.6.0 + jsdom: ^22.1.0 + peerDependenciesMeta: + cubism: + optional: true + jsdom: + optional: true + checksum: e1c9344228c7d38eeb17524e17e4e855c1fce509839ccca81945c176af22943422ad258f95de1b80b3732517b6c02b03ebcb45e132efe10b95b7f0e7dee7dedc languageName: node linkType: hard