mirror of
https://github.com/grafana/grafana.git
synced 2025-08-02 13:32:15 +08:00
Plugins: Migrate Elasticsearch to backend plugin SDK (#36132)
* Migrate Elasticsearch to backend plugin SDK * Fix linting * Move away from Convey! * Rebase commit * Small logger fix * Fixes according to reviewer's comments * Fixes according to reviewer's comments * Fixes according to reviewer's comments * More cleanup * Move things around - small refactoring * Fix typo * Update calculator - add tests * Fixes according to reviewer's comments
This commit is contained in:

committed by
GitHub

parent
75947da527
commit
0df1b33d71
@ -3,158 +3,111 @@ package es
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/httpclient"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/tsdb/interval"
|
||||
"github.com/grafana/grafana/pkg/tsdb"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewClient(t *testing.T) {
|
||||
t.Run("When no version set should return error", func(t *testing.T) {
|
||||
ds := &models.DataSource{
|
||||
JsonData: simplejson.NewFromAny(make(map[string]interface{})),
|
||||
}
|
||||
|
||||
_, err := NewClient(context.Background(), httpclient.NewProvider(), ds, plugins.DataTimeRange{})
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("When no time field name set should return error", func(t *testing.T) {
|
||||
ds := &models.DataSource{
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{
|
||||
"esVersion": 5,
|
||||
}),
|
||||
}
|
||||
|
||||
_, err := NewClient(context.Background(), httpclient.NewProvider(), ds, plugins.DataTimeRange{})
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("When using legacy version numbers", func(t *testing.T) {
|
||||
t.Run("When unsupported version set should return error", func(t *testing.T) {
|
||||
ds := &models.DataSource{
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{
|
||||
"esVersion": 6,
|
||||
"timeField": "@timestamp",
|
||||
}),
|
||||
}
|
||||
|
||||
_, err := NewClient(context.Background(), httpclient.NewProvider(), ds, plugins.DataTimeRange{})
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("When version 2 should return v2 client", func(t *testing.T) {
|
||||
ds := &models.DataSource{
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{
|
||||
"esVersion": 2,
|
||||
"timeField": "@timestamp",
|
||||
}),
|
||||
version, err := semver.NewVersion("2.0.0")
|
||||
require.NoError(t, err)
|
||||
ds := &DatasourceInfo{
|
||||
ESVersion: version,
|
||||
TimeField: "@timestamp",
|
||||
}
|
||||
|
||||
c, err := NewClient(context.Background(), httpclient.NewProvider(), ds, plugins.DataTimeRange{})
|
||||
c, err := NewClient(context.Background(), httpclient.NewProvider(), ds, backend.TimeRange{})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "2.0.0", c.GetVersion().String())
|
||||
})
|
||||
|
||||
t.Run("When version 5 should return v5 client", func(t *testing.T) {
|
||||
ds := &models.DataSource{
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{
|
||||
"esVersion": 5,
|
||||
"timeField": "@timestamp",
|
||||
}),
|
||||
version, err := semver.NewVersion("5.0.0")
|
||||
require.NoError(t, err)
|
||||
ds := &DatasourceInfo{
|
||||
ESVersion: version,
|
||||
TimeField: "@timestamp",
|
||||
}
|
||||
|
||||
c, err := NewClient(context.Background(), httpclient.NewProvider(), ds, plugins.DataTimeRange{})
|
||||
c, err := NewClient(context.Background(), httpclient.NewProvider(), ds, backend.TimeRange{})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "5.0.0", c.GetVersion().String())
|
||||
})
|
||||
|
||||
t.Run("When version 56 should return v5.6 client", func(t *testing.T) {
|
||||
ds := &models.DataSource{
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{
|
||||
"esVersion": 56,
|
||||
"timeField": "@timestamp",
|
||||
}),
|
||||
version, err := semver.NewVersion("5.6.0")
|
||||
require.NoError(t, err)
|
||||
ds := &DatasourceInfo{
|
||||
ESVersion: version,
|
||||
TimeField: "@timestamp",
|
||||
}
|
||||
|
||||
c, err := NewClient(context.Background(), httpclient.NewProvider(), ds, plugins.DataTimeRange{})
|
||||
c, err := NewClient(context.Background(), httpclient.NewProvider(), ds, backend.TimeRange{})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "5.6.0", c.GetVersion().String())
|
||||
})
|
||||
|
||||
t.Run("When version 60 should return v6.0 client", func(t *testing.T) {
|
||||
ds := &models.DataSource{
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{
|
||||
"esVersion": 60,
|
||||
"timeField": "@timestamp",
|
||||
}),
|
||||
version, err := semver.NewVersion("6.0.0")
|
||||
require.NoError(t, err)
|
||||
ds := &DatasourceInfo{
|
||||
ESVersion: version,
|
||||
TimeField: "@timestamp",
|
||||
}
|
||||
|
||||
c, err := NewClient(context.Background(), httpclient.NewProvider(), ds, plugins.DataTimeRange{})
|
||||
c, err := NewClient(context.Background(), httpclient.NewProvider(), ds, backend.TimeRange{})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "6.0.0", c.GetVersion().String())
|
||||
})
|
||||
|
||||
t.Run("When version 70 should return v7.0 client", func(t *testing.T) {
|
||||
ds := &models.DataSource{
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{
|
||||
"esVersion": 70,
|
||||
"timeField": "@timestamp",
|
||||
}),
|
||||
version, err := semver.NewVersion("7.0.0")
|
||||
require.NoError(t, err)
|
||||
ds := &DatasourceInfo{
|
||||
ESVersion: version,
|
||||
TimeField: "@timestamp",
|
||||
}
|
||||
|
||||
c, err := NewClient(context.Background(), httpclient.NewProvider(), ds, plugins.DataTimeRange{})
|
||||
c, err := NewClient(context.Background(), httpclient.NewProvider(), ds, backend.TimeRange{})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "7.0.0", c.GetVersion().String())
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("When version is a valid semver string should create a client", func(t *testing.T) {
|
||||
version := "7.2.4"
|
||||
ds := &models.DataSource{
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{
|
||||
"esVersion": version,
|
||||
"timeField": "@timestamp",
|
||||
}),
|
||||
}
|
||||
|
||||
c, err := NewClient(context.Background(), httpclient.NewProvider(), ds, plugins.DataTimeRange{})
|
||||
version, err := semver.NewVersion("7.2.4")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version, c.GetVersion().String())
|
||||
})
|
||||
|
||||
t.Run("When version is NOT a valid semver string should return error", func(t *testing.T) {
|
||||
version := "7.NOT_VALID.4"
|
||||
ds := &models.DataSource{
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{
|
||||
"esVersion": version,
|
||||
"timeField": "@timestamp",
|
||||
}),
|
||||
ds := &DatasourceInfo{
|
||||
ESVersion: version,
|
||||
TimeField: "@timestamp",
|
||||
}
|
||||
|
||||
_, err := NewClient(context.Background(), httpclient.NewProvider(), ds, plugins.DataTimeRange{})
|
||||
require.Error(t, err)
|
||||
c, err := NewClient(context.Background(), httpclient.NewProvider(), ds, backend.TimeRange{})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.String(), c.GetVersion().String())
|
||||
})
|
||||
}
|
||||
|
||||
func TestClient_ExecuteMultisearch(t *testing.T) {
|
||||
httpClientScenario(t, "Given a fake http client and a v2.x client with response", &models.DataSource{
|
||||
Database: "[metrics-]YYYY.MM.DD",
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{
|
||||
"esVersion": 2,
|
||||
"timeField": "@timestamp",
|
||||
"interval": "Daily",
|
||||
}),
|
||||
version, err := semver.NewVersion("2.0.0")
|
||||
require.NoError(t, err)
|
||||
httpClientScenario(t, "Given a fake http client and a v2.x client with response", &DatasourceInfo{
|
||||
Database: "[metrics-]YYYY.MM.DD",
|
||||
ESVersion: version,
|
||||
TimeField: "@timestamp",
|
||||
Interval: "Daily",
|
||||
}, func(sc *scenarioContext) {
|
||||
sc.responseBody = `{
|
||||
"responses": [
|
||||
@ -198,14 +151,14 @@ func TestClient_ExecuteMultisearch(t *testing.T) {
|
||||
require.Len(t, res.Responses, 1)
|
||||
})
|
||||
|
||||
httpClientScenario(t, "Given a fake http client and a v5.x client with response", &models.DataSource{
|
||||
Database: "[metrics-]YYYY.MM.DD",
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{
|
||||
"esVersion": 5,
|
||||
"maxConcurrentShardRequests": 100,
|
||||
"timeField": "@timestamp",
|
||||
"interval": "Daily",
|
||||
}),
|
||||
version, err = semver.NewVersion("5.0.0")
|
||||
require.NoError(t, err)
|
||||
httpClientScenario(t, "Given a fake http client and a v5.x client with response", &DatasourceInfo{
|
||||
Database: "[metrics-]YYYY.MM.DD",
|
||||
ESVersion: version,
|
||||
TimeField: "@timestamp",
|
||||
Interval: "Daily",
|
||||
MaxConcurrentShardRequests: 100,
|
||||
}, func(sc *scenarioContext) {
|
||||
sc.responseBody = `{
|
||||
"responses": [
|
||||
@ -250,16 +203,16 @@ func TestClient_ExecuteMultisearch(t *testing.T) {
|
||||
require.Len(t, res.Responses, 1)
|
||||
})
|
||||
|
||||
httpClientScenario(t, "Given a fake http client and a v5.6 client with response", &models.DataSource{
|
||||
Database: "[metrics-]YYYY.MM.DD",
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{
|
||||
"esVersion": "5.6.0",
|
||||
"maxConcurrentShardRequests": 100,
|
||||
"timeField": "@timestamp",
|
||||
"interval": "Daily",
|
||||
"includeFrozen": true,
|
||||
"xpack": true,
|
||||
}),
|
||||
version, err = semver.NewVersion("5.6.0")
|
||||
require.NoError(t, err)
|
||||
httpClientScenario(t, "Given a fake http client and a v5.6 client with response", &DatasourceInfo{
|
||||
Database: "[metrics-]YYYY.MM.DD",
|
||||
ESVersion: version,
|
||||
TimeField: "@timestamp",
|
||||
Interval: "Daily",
|
||||
MaxConcurrentShardRequests: 100,
|
||||
IncludeFrozen: true,
|
||||
XPack: true,
|
||||
}, func(sc *scenarioContext) {
|
||||
sc.responseBody = `{
|
||||
"responses": [
|
||||
@ -305,16 +258,16 @@ func TestClient_ExecuteMultisearch(t *testing.T) {
|
||||
require.Len(t, res.Responses, 1)
|
||||
})
|
||||
|
||||
httpClientScenario(t, "Given a fake http client and a v7.0 client with response", &models.DataSource{
|
||||
Database: "[metrics-]YYYY.MM.DD",
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{
|
||||
"esVersion": "7.0.0",
|
||||
"maxConcurrentShardRequests": 6,
|
||||
"timeField": "@timestamp",
|
||||
"interval": "Daily",
|
||||
"includeFrozen": true,
|
||||
"xpack": true,
|
||||
}),
|
||||
version, err = semver.NewVersion("7.0.0")
|
||||
require.NoError(t, err)
|
||||
httpClientScenario(t, "Given a fake http client and a v7.0 client with response", &DatasourceInfo{
|
||||
Database: "[metrics-]YYYY.MM.DD",
|
||||
ESVersion: version,
|
||||
TimeField: "@timestamp",
|
||||
Interval: "Daily",
|
||||
MaxConcurrentShardRequests: 6,
|
||||
IncludeFrozen: true,
|
||||
XPack: true,
|
||||
}, func(sc *scenarioContext) {
|
||||
sc.responseBody = `{
|
||||
"responses": [
|
||||
@ -366,7 +319,7 @@ func createMultisearchForTest(t *testing.T, c Client) (*MultiSearchRequest, erro
|
||||
t.Helper()
|
||||
|
||||
msb := c.MultiSearch()
|
||||
s := msb.Search(interval.Interval{Value: 15 * time.Second, Text: "15s"})
|
||||
s := msb.Search(tsdb.Interval{Value: 15 * time.Second, Text: "15s"})
|
||||
s.Agg().DateHistogram("2", "@timestamp", func(a *DateHistogramAgg, ab AggBuilder) {
|
||||
a.Interval = "$__interval"
|
||||
|
||||
@ -387,7 +340,7 @@ type scenarioContext struct {
|
||||
|
||||
type scenarioFunc func(*scenarioContext)
|
||||
|
||||
func httpClientScenario(t *testing.T, desc string, ds *models.DataSource, fn scenarioFunc) {
|
||||
func httpClientScenario(t *testing.T, desc string, ds *DatasourceInfo, fn scenarioFunc) {
|
||||
t.Helper()
|
||||
|
||||
t.Run(desc, func(t *testing.T) {
|
||||
@ -407,13 +360,14 @@ func httpClientScenario(t *testing.T, desc string, ds *models.DataSource, fn sce
|
||||
require.NoError(t, err)
|
||||
rw.WriteHeader(sc.responseStatus)
|
||||
}))
|
||||
ds.Url = ts.URL
|
||||
ds.URL = ts.URL
|
||||
|
||||
from := time.Date(2018, 5, 15, 17, 50, 0, 0, time.UTC)
|
||||
to := time.Date(2018, 5, 15, 17, 55, 0, 0, time.UTC)
|
||||
fromStr := fmt.Sprintf("%d", from.UnixNano()/int64(time.Millisecond))
|
||||
toStr := fmt.Sprintf("%d", to.UnixNano()/int64(time.Millisecond))
|
||||
timeRange := plugins.NewDataTimeRange(fromStr, toStr)
|
||||
timeRange := backend.TimeRange{
|
||||
From: from,
|
||||
To: to,
|
||||
}
|
||||
|
||||
c, err := NewClient(context.Background(), httpclient.NewProvider(), ds, timeRange)
|
||||
require.NoError(t, err)
|
||||
@ -422,7 +376,7 @@ func httpClientScenario(t *testing.T, desc string, ds *models.DataSource, fn sce
|
||||
|
||||
currentNewDatasourceHTTPClient := newDatasourceHttpClient
|
||||
|
||||
newDatasourceHttpClient = func(httpClientProvider httpclient.Provider, ds *models.DataSource) (*http.Client, error) {
|
||||
newDatasourceHttpClient = func(httpClientProvider httpclient.Provider, ds *DatasourceInfo) (*http.Client, error) {
|
||||
return ts.Client(), nil
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user