Skip to content

Commit

Permalink
fix(jmx,camel): make Operations more robust on potential Jolokia max …
Browse files Browse the repository at this point in the history
…depth shortage error
  • Loading branch information
tadayosi committed Nov 17, 2023
1 parent 00c01f0 commit 3ff43cc
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 25 deletions.
9 changes: 6 additions & 3 deletions packages/hawtio/src/plugins/shared/jolokia-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,10 @@ class JolokiaService implements IJolokiaService {
}
// Overwrite max depth as listing MBeans requires some constant depth to work
// See: https://github.com/hawtio/hawtio-next/issues/670
options.maxDepth = JOLOKIA_LIST_MAX_DEPTH
const { maxDepth } = this.loadJolokiaStoredOptions()
if (maxDepth < JOLOKIA_LIST_MAX_DEPTH) {
options.maxDepth = JOLOKIA_LIST_MAX_DEPTH
}
switch (method) {
case JolokiaListMethod.OPTIMISED: {
log.debug('Invoke Jolokia list MBean in optimised mode:', paths)
Expand Down Expand Up @@ -799,8 +802,8 @@ class JolokiaService implements IJolokiaService {
loadJolokiaStoredOptions(): JolokiaStoredOptions {
const item = localStorage.getItem(STORAGE_KEY_JOLOKIA_OPTIONS)
const options: JolokiaStoredOptions = item ? JSON.parse(item) : {}
const maxDepth = options.maxDepth || DEFAULT_MAX_DEPTH
const maxCollectionSize = options.maxCollectionSize || DEFAULT_MAX_COLLECTION_SIZE
const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH
const maxCollectionSize = options.maxCollectionSize ?? DEFAULT_MAX_COLLECTION_SIZE
return { maxDepth, maxCollectionSize }
}

Expand Down
6 changes: 3 additions & 3 deletions packages/hawtio/src/plugins/shared/operations/Operations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ import { createOperations } from './operation'
export const Operations: React.FunctionComponent = () => {
const { selectedNode } = useContext(PluginNodeSelectionContext)

if (!selectedNode || !selectedNode.objectName || !selectedNode.mbean) {
if (!selectedNode || !selectedNode.mbean) {
return null
}

const { objectName, mbean } = selectedNode
const { mbean } = selectedNode

if (!mbean.op || isEmpty(mbean.op)) {
return <HawtioEmptyCard message='This MBean has no JMX operations.' />
}

const operations = createOperations(objectName, mbean.op)
const operations = createOperations(mbean.op)

const OperationList = () => (
<DataList id='jmx-operation-list' aria-label='operation list' isCompact>
Expand Down
51 changes: 32 additions & 19 deletions packages/hawtio/src/plugins/shared/operations/operation.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,50 @@
import { eventService } from '@hawtiosrc/core'
import { stringSorter, trimEnd } from '@hawtiosrc/util/strings'
import { log } from '../globals'
import { OptimisedMBeanOperation, OptimisedMBeanOperations } from '../tree'

/**
* Factory function for Operation objects.
*/
export function createOperations(objectName: string, jmxOperations: OptimisedMBeanOperations): Operation[] {
export function createOperations(jmxOperations: OptimisedMBeanOperations): Operation[] {
const operations: Operation[] = []
const operationMap: Record<string, Operation> = {}
const errors: string[] = []
Object.entries(jmxOperations).forEach(([name, op]) => {
if (Array.isArray(op)) {
op.forEach(op => addOperation(operations, operationMap, name, op))
op.forEach(op => addOperation(operations, name, op, errors))
} else {
addOperation(operations, operationMap, name, op)
addOperation(operations, name, op, errors)
}
})
if (errors.length > 0) {
eventService.notify({
type: 'danger',
message: `Please try increasing max depth for Jolokia in the Connect preferences. Failed to load operations: ${errors.join(
', ',
)}.`,
duration: 30 * 1000, // 30 sec.
})
}
return operations.sort((a, b) => stringSorter(a.readableName, b.readableName))
}

function addOperation(
operations: Operation[],
operationMap: Record<string, Operation>,
name: string,
op: OptimisedMBeanOperation,
): void {
const operation = new Operation(
name,
op.args.map(arg => new OperationArgument(arg.name, arg.type, arg.desc)),
op.desc,
op.ret,
op.canInvoke,
)
operations.push(operation)
operationMap[operation.name] = operation
function addOperation(operations: Operation[], name: string, op: OptimisedMBeanOperation, errors: string[]) {
try {
const operation = new Operation(
name,
op.args.map(arg => new OperationArgument(arg.name, arg.type, arg.desc)),
op.desc,
op.ret,
op.canInvoke,
)
operations.push(operation)
} catch (error) {
// Error can happen when max depth for Jolokia LIST is too small and part of
// the returned MBeans are compressed in a string form. In that case, the user
// needs to increase max depth for Jolokia requests in Connect preferences.
log.error('Operations - Error creating operation:', name, error)
errors.push(name)
}
}

export class Operation {
Expand Down

0 comments on commit 3ff43cc

Please sign in to comment.