open queries that have utf8 labels in explore properly

This commit is contained in:
ismail simsek
2025-01-16 20:30:35 +01:00
parent f6194931f5
commit 85b81c9621
4 changed files with 10 additions and 130 deletions

View File

@@ -71,7 +71,7 @@ import {
RawRecordingRules,
RuleQueryMapping,
} from './types';
import { utf8Support, wrapUtf8Filters } from './utf8_support';
import { utf8Support } from './utf8_support';
import { PrometheusVariableSupport } from './variables';
const ANNOTATION_QUERY_STEP_DEFAULT = '60s';
@@ -931,9 +931,6 @@ export class PrometheusDatasource
variables,
(value: string | string[] = [], variable: QueryVariableModel | CustomVariableModel) => {
if (typeof value === 'string' && target.fromExploreMetrics) {
if (variable.name === 'filters') {
return wrapUtf8Filters(value);
}
if (variable.name === 'groupby') {
return utf8Support(value);
}

View File

@@ -1,4 +1,4 @@
import { escapeForUtf8Support, utf8Support, wrapUtf8Filters } from './utf8_support';
import { escapeForUtf8Support, utf8Support } from './utf8_support';
describe('utf8 support', () => {
it('should return utf8 labels wrapped in quotes', () => {
@@ -33,95 +33,3 @@ describe('applyValueEncodingEscaping', () => {
expect(excapedLabels).toEqual(expected);
});
});
describe('wrapUtf8Filters', () => {
it('should correctly wrap UTF-8 labels and values for multiple key-value pairs', () => {
const result = wrapUtf8Filters('label.with.spaß="this_is_fun",instance="localhost:9112"');
const expected = '"label.with.spaß"="this_is_fun",instance="localhost:9112"';
expect(result).toEqual(expected);
});
it('should correctly wrap UTF-8 labels and values for a single key-value pair', () => {
const result = wrapUtf8Filters('label.with.spaß="this_is_fun"');
const expected = '"label.with.spaß"="this_is_fun"';
expect(result).toEqual(expected);
});
it('should correctly handle commas within values', () => {
const result = wrapUtf8Filters('label.with.spaß="this,is,fun",instance="localhost:9112"');
const expected = '"label.with.spaß"="this,is,fun",instance="localhost:9112"';
expect(result).toEqual(expected);
});
it('should correctly handle escaped quotes within values', () => {
const result = wrapUtf8Filters(`label.with.spaß="this_is_\\"fun\\"",instance="localhost:9112"`);
const expected = `"label.with.spaß"="this_is_\\"fun\\"",instance="localhost:9112"`;
expect(result).toEqual(expected);
});
it('should correctly handle spaces within keys', () => {
const result = wrapUtf8Filters('label with space="value with space",instance="localhost:9112"');
const expected = '"label with space"="value with space",instance="localhost:9112"';
expect(result).toEqual(expected);
});
it('should correctly process mixed inputs with various formats', () => {
const result = wrapUtf8Filters('key1="value1",key2="value,with,comma",key3="val3"');
const expected = 'key1="value1",key2="value,with,comma",key3="val3"';
expect(result).toEqual(expected);
});
it('should correctly handle empty values', () => {
const result = wrapUtf8Filters('key1="",key2="value2"');
const expected = 'key1="",key2="value2"';
expect(result).toEqual(expected);
});
it('should handle an empty input string', () => {
const result = wrapUtf8Filters('');
const expected = '';
expect(result).toEqual(expected);
});
it('should handle a single key with an empty value', () => {
const result = wrapUtf8Filters('key1=""');
const expected = 'key1=""';
expect(result).toEqual(expected);
});
it('should handle multiple consecutive commas in a value', () => {
const result = wrapUtf8Filters('key1="value1,,value2",key2="value3"');
const expected = 'key1="value1,,value2",key2="value3"';
expect(result).toEqual(expected);
});
it('should handle a key-value pair with special characters in the key', () => {
const result = wrapUtf8Filters('special@key#="value1",key2="value2"');
const expected = '"special@key#"="value1",key2="value2"';
expect(result).toEqual(expected);
});
it('should handle a key-value pair with special characters in the value', () => {
const result = wrapUtf8Filters('key1="value@#&*",key2="value2"');
const expected = 'key1="value@#&*",key2="value2"';
expect(result).toEqual(expected);
});
it('should correctly process keys without special characters', () => {
const result = wrapUtf8Filters('key1="value1",key2="value2"');
const expected = 'key1="value1",key2="value2"';
expect(result).toEqual(expected);
});
it('should handle nested escaped quotes correctly', () => {
const result = wrapUtf8Filters('key1="nested \\"escaped\\" quotes",key2="value2"');
const expected = 'key1="nested \\"escaped\\" quotes",key2="value2"';
expect(result).toEqual(expected);
});
it('should handle escaped quotes correctly', () => {
const result = wrapUtf8Filters('key1="nested \\"escaped\\" quotes",key2="value with \\"escaped\\" quotes"');
const expected = 'key1="nested \\"escaped\\" quotes",key2="value with \\"escaped\\" quotes"';
expect(result).toEqual(expected);
});
});

View File

@@ -79,35 +79,3 @@ const isValidCodePoint = (codePoint: number): boolean => {
// Validate the code point for UTF-8 compliance if needed.
return codePoint >= 0 && codePoint <= 0x10ffff;
};
export const wrapUtf8Filters = (filterStr: string): string => {
const resultArray: string[] = [];
let currentKey = '';
let currentValue = '';
let inQuotes = false;
let temp = '';
for (const char of filterStr) {
if (char === '"' && temp[temp.length - 1] !== '\\') {
// Toggle inQuotes when an unescaped quote is found
inQuotes = !inQuotes;
temp += char;
} else if (char === ',' && !inQuotes) {
// When outside quotes and encountering ',', finalize the current pair
[currentKey, currentValue] = temp.split('=');
resultArray.push(`${utf8Support(currentKey.trim())}="${currentValue.slice(1, -1)}"`);
temp = ''; // Reset for the next pair
} else {
// Collect characters
temp += char;
}
}
// Handle the last key-value pair
if (temp) {
[currentKey, currentValue] = temp.split('=');
resultArray.push(`${utf8Support(currentKey.trim())}="${currentValue.slice(1, -1)}"`);
}
return resultArray.join(',');
};

View File

@@ -6,6 +6,7 @@ import {
} from '@grafana/data';
import { PrometheusDatasource, PromMetricsMetadata, PromMetricsMetadataItem, PromQuery } from '@grafana/prometheus';
import PromQlLanguageProvider from '@grafana/prometheus/src/language_provider';
import { utf8Support } from '@grafana/prometheus/src/utf8_support';
import { getDataSourceSrv } from '@grafana/runtime';
import { DataTrail } from '../DataTrail';
@@ -134,7 +135,13 @@ export class MetricDatasourceHelper {
if (ds instanceof PrometheusDatasource) {
const keys = await ds.getTagKeys(options);
return keys;
return keys.map((key) => {
if (typeof key.value === 'string') {
key.value = utf8Support(key.value);
key.text = utf8Support(key.text);
}
return key;
});
}
return [];