From 13373edd2788bc883d020211d3517f32ed41a7f5 Mon Sep 17 00:00:00 2001 From: Tadayoshi Sato Date: Tue, 24 Oct 2023 14:23:07 +0900 Subject: [PATCH] fix(jmx): provide full URL including origin for Jolokia URL in Attribute modal --- .../shared/__mocks__/jolokia-service.ts | 4 ++ .../shared/attributes/attribute-service.ts | 2 +- .../plugins/shared/jolokia-service.test.ts | 20 ++++++++++ .../src/plugins/shared/jolokia-service.ts | 37 ++++++++++++++++++- .../shared/operations/operation-service.ts | 8 +--- 5 files changed, 63 insertions(+), 8 deletions(-) diff --git a/packages/hawtio/src/plugins/shared/__mocks__/jolokia-service.ts b/packages/hawtio/src/plugins/shared/__mocks__/jolokia-service.ts index a3610e4a..af1c44ae 100644 --- a/packages/hawtio/src/plugins/shared/__mocks__/jolokia-service.ts +++ b/packages/hawtio/src/plugins/shared/__mocks__/jolokia-service.ts @@ -23,6 +23,10 @@ class MockJolokiaService implements IJolokiaService { return 0 } + async getFullJolokiaUrl(): Promise { + return '' + } + async list(options: ListRequestOptions): Promise { return jmxCamelResponse } diff --git a/packages/hawtio/src/plugins/shared/attributes/attribute-service.ts b/packages/hawtio/src/plugins/shared/attributes/attribute-service.ts index 7382b153..0fd88c56 100644 --- a/packages/hawtio/src/plugins/shared/attributes/attribute-service.ts +++ b/packages/hawtio/src/plugins/shared/attributes/attribute-service.ts @@ -23,7 +23,7 @@ class AttributeService { } async buildUrl(mbean: string, attribute: string): Promise { - const jolokiaUrl = await jolokiaService.getJolokiaUrl() + const jolokiaUrl = await jolokiaService.getFullJolokiaUrl() return `${jolokiaUrl}/read/${escapeMBean(mbean)}/${attribute}` } } diff --git a/packages/hawtio/src/plugins/shared/jolokia-service.test.ts b/packages/hawtio/src/plugins/shared/jolokia-service.test.ts index 0cad3d2a..3d1769b4 100644 --- a/packages/hawtio/src/plugins/shared/jolokia-service.test.ts +++ b/packages/hawtio/src/plugins/shared/jolokia-service.test.ts @@ -1,6 +1,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' describe('JolokiaService', () => { beforeEach(() => { @@ -64,6 +65,25 @@ describe('JolokiaService', () => { await expect(jolokiaService.getListMethod()).resolves.toEqual(JolokiaListMethod.DEFAULT) }) + test('getFullJolokiaUrl', async () => { + hawtio.getBasePath = jest.fn(() => '/hawtio') + + jolokiaService.getJolokiaUrl = jest.fn(async () => '/hawtio/jolokia') + await expect(jolokiaService.getFullJolokiaUrl()).resolves.toEqual('http://localhost/hawtio/jolokia') + + jolokiaService.getJolokiaUrl = jest.fn(async () => 'jolokia') + await expect(jolokiaService.getFullJolokiaUrl()).resolves.toEqual('http://localhost/hawtio/jolokia') + + jolokiaService.getJolokiaUrl = jest.fn(async () => 'http://test:12345/test/jolokia') + await expect(jolokiaService.getFullJolokiaUrl()).resolves.toEqual('http://test:12345/test/jolokia') + + jolokiaService.getJolokiaUrl = jest.fn(async () => 'https://test:12345/test/jolokia') + await expect(jolokiaService.getFullJolokiaUrl()).resolves.toEqual('https://test:12345/test/jolokia') + + jolokiaService.getJolokiaUrl = jest.fn(async () => 'http/jolokia') + await expect(jolokiaService.getFullJolokiaUrl()).resolves.toEqual('http://localhost/hawtio/http/jolokia') + }) + test('load and save Jolokia options', () => { let options = jolokiaService.loadJolokiaStoredOptions() expect(options.maxDepth).toEqual(DEFAULT_MAX_DEPTH) diff --git a/packages/hawtio/src/plugins/shared/jolokia-service.ts b/packages/hawtio/src/plugins/shared/jolokia-service.ts index 34c17781..dc6c69b7 100644 --- a/packages/hawtio/src/plugins/shared/jolokia-service.ts +++ b/packages/hawtio/src/plugins/shared/jolokia-service.ts @@ -1,5 +1,5 @@ import { userService } from '@hawtiosrc/auth' -import { eventService } from '@hawtiosrc/core' +import { eventService, hawtio } from '@hawtiosrc/core' import { basicAuthHeaderValue, getCookie } from '@hawtiosrc/util/https' import { escapeMBeanPath, @@ -85,6 +85,7 @@ export interface IJolokiaService { getJolokiaUrl(): Promise getJolokia(): Promise getListMethod(): Promise + getFullJolokiaUrl(): Promise list(options: ListRequestOptions): Promise readAttributes(mbean: string): Promise readAttribute(mbean: string, attribute: string): Promise @@ -118,6 +119,15 @@ class JolokiaService implements IJolokiaService { } } + /** + * Get the Jolokia URL that the service is connected to. + * + * The URL may not be a full URL including origin (`http(s)://host:port`). + * It can be a path relative to the root (`/hawtio/jolokia`) or to the current + * path (`jolokia`). + * + * @see Use {@link getFullJolokiaUrl} for getting the full URL. + */ getJolokiaUrl(): Promise { if (this.jolokiaUrl) { return this.jolokiaUrl @@ -365,6 +375,31 @@ class JolokiaService implements IJolokiaService { return opts } + /** + * Get the full Jolokia URL that the service is connected to. + * + * The origin part (`http(s)://host:port`) is resolved based on `window.location`. + * + * @see {@link getJolokiaUrl} + */ + async getFullJolokiaUrl(): Promise { + const jolokiaUrl = (await this.getJolokiaUrl()) ?? '' + if (jolokiaUrl.match(/^https?:\/\//)) { + return jolokiaUrl + } + + const { origin } = window.location + if (jolokiaUrl.startsWith('/')) { + return `${origin}${jolokiaUrl}` + } + + let basePath = hawtio.getBasePath() ?? '' + if (!basePath.endsWith('/')) { + basePath += '/' + } + return `${origin}${basePath + jolokiaUrl}` + } + async getListMethod(): Promise { // Need to wait for Jolokia instance as it might update the list method await this.getJolokia() diff --git a/packages/hawtio/src/plugins/shared/operations/operation-service.ts b/packages/hawtio/src/plugins/shared/operations/operation-service.ts index 0f59f5e0..2e145a38 100644 --- a/packages/hawtio/src/plugins/shared/operations/operation-service.ts +++ b/packages/hawtio/src/plugins/shared/operations/operation-service.ts @@ -1,4 +1,3 @@ -import { hawtio } from '@hawtiosrc/core' import { jolokiaService } from '@hawtiosrc/plugins/shared/jolokia-service' import { escapeMBean } from '@hawtiosrc/util/jolokia' import { log } from '../globals' @@ -11,11 +10,8 @@ class OperationService { async getJolokiaUrl(mbean: string, operation: string): Promise { const mbeanName = escapeMBean(mbean) - const basePath = hawtio.getBasePath() ?? '' - const origin = window.location.origin - const jolokiaUrl = (await jolokiaService.getJolokiaUrl()) ?? '' - const jolokiaPath = jolokiaUrl.startsWith('/') ? jolokiaUrl : basePath + jolokiaUrl - return `${origin}${jolokiaPath}/exec/${mbeanName}/${operation}` + const jolokiaUrl = await jolokiaService.getFullJolokiaUrl() + return `${jolokiaUrl}/exec/${mbeanName}/${operation}` } }