Skip to content

Commit

Permalink
fix(jmx): Handle MBeanInfo in Jolokia list() when there was error fet…
Browse files Browse the repository at this point in the history
…ching the info (fixes #902)

Signed-off-by: Grzegorz Grzybek <gr.grzybek@gmail.com>
  • Loading branch information
grgrzybek committed Apr 24, 2024
1 parent 9e25ff4 commit 72a5c2a
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 4 deletions.
23 changes: 22 additions & 1 deletion packages/hawtio/src/plugins/shared/jolokia-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { userService } from '@hawtiosrc/auth'
import Jolokia, { ListRequestOptions } from 'jolokia.js'
import { DEFAULT_MAX_COLLECTION_SIZE, DEFAULT_MAX_DEPTH, JolokiaListMethod, jolokiaService } from './jolokia-service'
import { hawtio } from '@hawtiosrc/core'

// import { readFile } from 'node:fs/promises'
describe('JolokiaService', () => {
beforeEach(() => {
jest.resetModules()
Expand Down Expand Up @@ -94,4 +94,25 @@ describe('JolokiaService', () => {
expect(options.maxDepth).toEqual(3)
expect(options.maxCollectionSize).toEqual(10000)
})

test('problematic JSON response from case hawtio/hawtio#3401', async () => {
// const content = await readFile("/data/sources/_testing/grgr-test-many-mbeans/src/test/resources/responses/004-formatted.json").then(v => v.toString())
// jolokiaService.unwindListResponse(JSON.parse(content).value)
const response = {
value: {
'java.util.logging': {
'type=Logging': {
class: 'sun.management.ManagementFactoryHelper$PlatformLoggingImpl',
desc: 'Information on the management interface of the MBean',
},
},
'my-domain-with-vanishing-mbeans': {
'type=Bean1': {
error: 'javax.management.InstanceNotFoundException: Bean1',
},
},
},
}
jolokiaService.unwindListResponse(response.value)
})
})
10 changes: 7 additions & 3 deletions packages/hawtio/src/plugins/shared/jolokia-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import $ from 'jquery'
import { define, func, is, object, optional, record, string, type } from 'superstruct'
import { PARAM_KEY_CONNECTION, PARAM_KEY_REDIRECT, connectService } from '../shared/connect-service'
import { log } from './globals'
import { OptimisedJmxDomain, OptimisedJmxDomains, OptimisedMBeanInfo } from './tree'
import { ErrorMBeanInfo, OptimisedJmxDomain, OptimisedJmxDomains, OptimisedMBeanInfo } from './tree'

export const DEFAULT_MAX_DEPTH = 7
export const DEFAULT_MAX_COLLECTION_SIZE = 50000
Expand Down Expand Up @@ -540,9 +540,12 @@ class JolokiaService implements IJolokiaService {
* @param response response value from Jolokia LIST
* @param path optional path information to restore the response to {@link OptimisedJmxDomains}
*/
private unwindListResponse(response: unknown, path?: string[]): OptimisedJmxDomains {
unwindListResponse(response: unknown, path?: string[]): OptimisedJmxDomains {
const isOptimisedListResponse = (value: unknown): value is OptimisedListResponse =>
is(value, object({ cache: object(), domains: object() }))
const isMBeanInfoOrError = (value: unknown): boolean => {
return isMBeanInfo(value) || isMBeanInfoError(value)
}
const isMBeanInfo = (value: unknown): value is OptimisedMBeanInfo =>
is(
value,
Expand All @@ -554,8 +557,9 @@ class JolokiaService implements IJolokiaService {
notif: optional(record(string(), object())),
}),
)
const isMBeanInfoError = (value: unknown): value is ErrorMBeanInfo => is(value, type({ error: string() }))
const isJmxDomain = (value: unknown): value is OptimisedJmxDomain =>
is(value, record(string(), define('MBeanInfo', isMBeanInfo)))
is(value, record(string(), define('MBeanInfo', isMBeanInfoOrError)))
const isJmxDomains = (value: unknown): value is OptimisedJmxDomains =>
is(value, record(string(), define('JmxDomain', isJmxDomain)))

Expand Down
4 changes: 4 additions & 0 deletions packages/hawtio/src/plugins/shared/tree/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export interface OptimisedMBeanInfo extends Omit<MBeanInfo, 'attr' | 'op'> {
canInvoke?: boolean
}

export interface ErrorMBeanInfo {
error: string
}

export interface OptimisedMBeanAttribute extends MBeanAttribute {
canInvoke?: boolean
}
Expand Down

0 comments on commit 72a5c2a

Please sign in to comment.