mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-06-09 16:09:41 +08:00
🐛 fix(jvm): 修正连接表单模式回填与超时同步
- 保留编辑态 JVM 连接的原始 preferredMode,避免旧配置被静默降级 - 将 JVM 可见超时统一同步到 Endpoint 探测配置 - 抽取 JVM 可编辑模式判定与回填逻辑,统一 ConnectionModal 行为 - 补充 JVM 模式与超时纯函数测试,覆盖 unsupported preferredMode 分支 - 更新需求追踪文档,记录 Task 3 实现、复审与验证结果
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { buildDefaultJVMConnectionValues, buildJVMConnectionConfig } from './jvmConnectionConfig';
|
||||
import {
|
||||
buildDefaultJVMConnectionValues,
|
||||
buildJVMConnectionConfig,
|
||||
hasUnsupportedJVMEditableModes,
|
||||
normalizeEditableJVMModes,
|
||||
resolveEditableJVMModeSelection,
|
||||
} from './jvmConnectionConfig';
|
||||
|
||||
describe('jvmConnectionConfig', () => {
|
||||
it('defaults to readonly jmx mode', () => {
|
||||
@@ -58,4 +64,56 @@ describe('jvmConnectionConfig', () => {
|
||||
expect(config.jvm?.environment).toBe('prod');
|
||||
expect(config.jvm?.readOnly).toBe(false);
|
||||
});
|
||||
|
||||
it('keeps the visible timeout as the source of truth for endpoint probing', () => {
|
||||
const config = buildJVMConnectionConfig({
|
||||
host: 'orders.internal',
|
||||
port: 9010,
|
||||
timeout: 45,
|
||||
jvmEndpointTimeoutSeconds: 30,
|
||||
jvmAllowedModes: ['endpoint'],
|
||||
jvmPreferredMode: 'endpoint',
|
||||
jvmEndpointEnabled: true,
|
||||
jvmEndpointBaseUrl: 'https://orders.internal/manage/jvm',
|
||||
});
|
||||
|
||||
expect(config.timeout).toBe(45);
|
||||
expect(config.jvm?.endpoint?.timeoutSeconds).toBe(45);
|
||||
});
|
||||
|
||||
it('normalizes editable JVM modes to the supported form subset', () => {
|
||||
expect(normalizeEditableJVMModes([' endpoint ', 'agent', 'JMX', 'endpoint'])).toEqual(['endpoint', 'jmx']);
|
||||
});
|
||||
|
||||
it('detects unsupported editable JVM modes without downgrading them silently', () => {
|
||||
expect(hasUnsupportedJVMEditableModes({
|
||||
allowedModes: ['agent', 'jmx'],
|
||||
preferredMode: 'agent',
|
||||
})).toBe(true);
|
||||
expect(hasUnsupportedJVMEditableModes({
|
||||
allowedModes: ['endpoint', 'jmx'],
|
||||
preferredMode: 'agent',
|
||||
})).toBe(true);
|
||||
expect(hasUnsupportedJVMEditableModes({
|
||||
allowedModes: ['endpoint', 'jmx'],
|
||||
preferredMode: 'endpoint',
|
||||
})).toBe(false);
|
||||
});
|
||||
|
||||
it('preserves preferred mode when rebuilding editable mode selection from stored config', () => {
|
||||
expect(resolveEditableJVMModeSelection({
|
||||
allowedModes: [],
|
||||
preferredMode: 'agent',
|
||||
})).toEqual({
|
||||
allowedModes: ['agent'],
|
||||
preferredMode: 'agent',
|
||||
});
|
||||
expect(resolveEditableJVMModeSelection({
|
||||
allowedModes: ['endpoint', 'jmx'],
|
||||
preferredMode: 'agent',
|
||||
})).toEqual({
|
||||
allowedModes: ['endpoint', 'jmx'],
|
||||
preferredMode: 'agent',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,12 +4,15 @@ const DEFAULT_JMX_PORT = 9010;
|
||||
const DEFAULT_TIMEOUT_SECONDS = 30;
|
||||
const DEFAULT_ENVIRONMENT = 'dev';
|
||||
const JVM_MODES = ['jmx', 'endpoint', 'agent'] as const;
|
||||
export const JVM_EDITABLE_MODES = ['jmx', 'endpoint'] as const;
|
||||
|
||||
type JVMMode = typeof JVM_MODES[number];
|
||||
type JVMEditableMode = typeof JVM_EDITABLE_MODES[number];
|
||||
type JVMEnvironment = 'dev' | 'uat' | 'prod';
|
||||
type JVMConnectionFormValues = Record<string, unknown>;
|
||||
|
||||
const isJVMMode = (value: string): value is JVMMode => JVM_MODES.includes(value as JVMMode);
|
||||
const isJVMEditableMode = (value: string): value is JVMEditableMode => JVM_EDITABLE_MODES.includes(value as JVMEditableMode);
|
||||
|
||||
const toStringValue = (value: unknown): string => {
|
||||
if (typeof value === 'string') {
|
||||
@@ -51,6 +54,61 @@ const normalizeModes = (value: unknown): JVMMode[] => {
|
||||
return result.length > 0 ? result : ['jmx'];
|
||||
};
|
||||
|
||||
export const normalizeEditableJVMModes = (value: unknown): JVMEditableMode[] => {
|
||||
if (!Array.isArray(value)) {
|
||||
return ['jmx'];
|
||||
}
|
||||
|
||||
const result: JVMEditableMode[] = [];
|
||||
const seen = new Set<JVMEditableMode>();
|
||||
for (const item of value) {
|
||||
const mode = toStringValue(item).toLowerCase();
|
||||
if (!isJVMEditableMode(mode) || seen.has(mode)) {
|
||||
continue;
|
||||
}
|
||||
seen.add(mode);
|
||||
result.push(mode);
|
||||
}
|
||||
return result.length > 0 ? result : ['jmx'];
|
||||
};
|
||||
|
||||
export const hasUnsupportedJVMEditableModes = ({
|
||||
allowedModes,
|
||||
preferredMode,
|
||||
}: {
|
||||
allowedModes: unknown;
|
||||
preferredMode: unknown;
|
||||
}): boolean => {
|
||||
const allowed = Array.isArray(allowedModes)
|
||||
? allowedModes.map((item) => toStringValue(item).toLowerCase()).filter((item) => item !== '')
|
||||
: [];
|
||||
const preferred = toStringValue(preferredMode).toLowerCase();
|
||||
|
||||
return allowed.some((mode) => !isJVMEditableMode(mode))
|
||||
|| (preferred !== '' && !isJVMEditableMode(preferred));
|
||||
};
|
||||
|
||||
export const resolveEditableJVMModeSelection = ({
|
||||
allowedModes,
|
||||
preferredMode,
|
||||
}: {
|
||||
allowedModes: unknown;
|
||||
preferredMode: unknown;
|
||||
}): { allowedModes: string[]; preferredMode: string } => {
|
||||
const normalizedAllowedModes = Array.isArray(allowedModes)
|
||||
? allowedModes.map((item) => toStringValue(item).toLowerCase()).filter((item) => item !== '')
|
||||
: [];
|
||||
const normalizedPreferredMode = toStringValue(preferredMode).toLowerCase();
|
||||
const resolvedAllowedModes = normalizedAllowedModes.length > 0
|
||||
? Array.from(new Set(normalizedAllowedModes))
|
||||
: (normalizedPreferredMode ? [normalizedPreferredMode] : ['jmx']);
|
||||
|
||||
return {
|
||||
allowedModes: resolvedAllowedModes,
|
||||
preferredMode: normalizedPreferredMode || resolvedAllowedModes[0],
|
||||
};
|
||||
};
|
||||
|
||||
const normalizePreferredMode = (value: unknown, allowedModes: JVMMode[]): JVMMode => {
|
||||
const preferred = toStringValue(value).toLowerCase();
|
||||
if (isJVMMode(preferred) && allowedModes.includes(preferred)) {
|
||||
@@ -91,7 +149,9 @@ export const buildJVMConnectionConfig = (values: JVMConnectionFormValues): Conne
|
||||
const allowedModes = normalizeModes(values.jvmAllowedModes);
|
||||
const preferredMode = normalizePreferredMode(values.jvmPreferredMode, allowedModes);
|
||||
const port = toInteger(values.port, DEFAULT_JMX_PORT);
|
||||
const timeout = toInteger(values.timeout, DEFAULT_TIMEOUT_SECONDS);
|
||||
const timeout = values.timeout === undefined || values.timeout === null || values.timeout === ''
|
||||
? toInteger(values.jvmEndpointTimeoutSeconds, DEFAULT_TIMEOUT_SECONDS)
|
||||
: toInteger(values.timeout, DEFAULT_TIMEOUT_SECONDS);
|
||||
|
||||
return {
|
||||
type: 'jvm',
|
||||
@@ -116,7 +176,7 @@ export const buildJVMConnectionConfig = (values: JVMConnectionFormValues): Conne
|
||||
enabled: values.jvmEndpointEnabled === true,
|
||||
baseUrl: toStringValue(values.jvmEndpointBaseUrl),
|
||||
apiKey: toStringValue(values.jvmEndpointApiKey),
|
||||
timeoutSeconds: toInteger(values.jvmEndpointTimeoutSeconds, timeout),
|
||||
timeoutSeconds: timeout,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user