InfluxDB: metricFindQuery migration to backend (#44546)

* Send metricFindQuery to backend

* Added feature toggle

* Changed flag name

* metricFindQuery backend

* Added test for metricFindQuery backend parse

* Added test for show tag values

* Test for metricFindQueries

* Updated tests

* Put back comment

* Case insensitive in transformRows

* Check length ov value pair

* Sep tests

* Updated valuePair index
This commit is contained in:
Joey Tawadrous 2022-02-16 09:16:22 +00:00 committed by GitHub
parent 6a38ce2307
commit b4dd3138ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 132 additions and 20 deletions

View File

@ -56,32 +56,59 @@ func parseJSON(buf io.ReadCloser) (Response, error) {
func transformRows(rows []Row, query Query) data.Frames {
frames := data.Frames{}
for _, row := range rows {
for columnIndex, column := range row.Columns {
if column == "time" {
continue
}
var hasTimeCol = false
var timeArray []time.Time
var valueArray []*float64
for _, column := range row.Columns {
if column == "time" {
hasTimeCol = true
}
}
if !hasTimeCol {
var values []string
for _, valuePair := range row.Values {
timestamp, timestampErr := parseTimestamp(valuePair[0])
// we only add this row if the timestamp is valid
if timestampErr == nil {
value := parseValue(valuePair[columnIndex])
timeArray = append(timeArray, timestamp)
valueArray = append(valueArray, value)
if strings.Contains(strings.ToLower(query.RawQuery), strings.ToLower("SHOW TAG VALUES")) {
if len(valuePair) >= 2 {
values = append(values, valuePair[1].(string))
}
} else {
if len(valuePair) >= 1 {
values = append(values, valuePair[0].(string))
}
}
}
name := formatFrameName(row, column, query)
timeField := data.NewField("time", nil, timeArray)
valueField := data.NewField("value", row.Tags, valueArray)
field := data.NewField("value", nil, values)
frames = append(frames, data.NewFrame(row.Name, field))
} else {
for columnIndex, column := range row.Columns {
if column == "time" {
continue
}
// set a nice name on the value-field
valueField.SetConfig(&data.FieldConfig{DisplayNameFromDS: name})
var timeArray []time.Time
var valueArray []*float64
frames = append(frames, newDataFrame(name, query.RawQuery, timeField, valueField))
for _, valuePair := range row.Values {
timestamp, timestampErr := parseTimestamp(valuePair[0])
// we only add this row if the timestamp is valid
if timestampErr == nil {
value := parseValue(valuePair[columnIndex])
timeArray = append(timeArray, timestamp)
valueArray = append(valueArray, value)
}
}
name := formatFrameName(row, column, query)
timeField := data.NewField("time", nil, timeArray)
valueField := data.NewField("value", row.Tags, valueArray)
// set a nice name on the value-field
valueField.SetConfig(&data.FieldConfig{DisplayNameFromDS: name})
frames = append(frames, newDataFrame(name, query.RawQuery, timeField, valueField))
}
}
}

View File

@ -91,6 +91,85 @@ func TestInfluxdbResponseParser(t *testing.T) {
}
})
t.Run("Influxdb response parser should parse metricFindQueries normally", func(t *testing.T) {
parser := &ResponseParser{}
response := `
{
"results": [
{
"series": [
{
"refId": "metricFindQuery",
"name": "cpu",
"values": [
["cpu"],
["disk"],
["logs"]
]
}
]
}
]
}
`
var queries []Query
queries = append(queries, Query{RefID: "metricFindQuery"})
newField := data.NewField("value", nil, []string{
"cpu", "disk", "logs",
})
testFrame := data.NewFrame("cpu",
newField,
)
result := parser.Parse(prepare(response), queries)
frame := result.Responses["metricFindQuery"]
if diff := cmp.Diff(testFrame, frame.Frames[0], data.FrameTestCompareOptions()...); diff != "" {
t.Errorf("Result mismatch (-want +got):\n%s", diff)
}
})
t.Run("Influxdb response parser should parse metricFindQueries->SHOW TAG VALUES normally", func(t *testing.T) {
parser := &ResponseParser{}
response := `
{
"results": [
{
"series": [
{
"name": "cpu",
"values": [
["values", "cpu-total"],
["values", "cpu0"],
["values", "cpu1"]
]
}
]
}
]
}
`
var queries []Query
queries = append(queries, Query{RawQuery: "SHOW TAG VALUES", RefID: "metricFindQuery"})
newField := data.NewField("value", nil, []string{
"cpu-total", "cpu0", "cpu1",
})
testFrame := data.NewFrame("cpu",
newField,
)
result := parser.Parse(prepare(response), queries)
frame := result.Responses["metricFindQuery"]
if diff := cmp.Diff(testFrame, frame.Frames[0], data.FrameTestCompareOptions()...); diff != "" {
t.Errorf("Result mismatch (-want +got):\n%s", diff)
}
})
t.Run("Influxdb response parser should parse two responses with different refIDs", func(t *testing.T) {
parser := &ResponseParser{}
@ -130,7 +209,12 @@ func TestInfluxdbResponseParser(t *testing.T) {
"series": [
{
"name": "cpu",
"columns": ["time","mean"]
"columns": ["time","cpu"],
"values": [
["values", "cpu-total"],
["values", "cpu0"],
["values", "cpu1"]
]
}
]
}

View File

@ -445,10 +445,11 @@ export default class InfluxDatasource extends DataSourceWithBackend<InfluxQuery,
}
async metricFindQuery(query: string, options?: any): Promise<MetricFindValue[]> {
if (this.isFlux) {
if (this.isFlux || (config.featureToggles.influxdbBackendMigration && this.access === 'proxy')) {
const target: InfluxQuery = {
refId: 'metricFindQuery',
query,
rawQuery: true,
};
return lastValueFrom(
super.query({