Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ Available configuration fields are as follows:
| Database (Optional) | Specifies the default database to use once connected. |
| Schema (Optional) | Specifies the default schema to use for the specified database once connected. |
| Extra Options (Optional) | Specifies a series of one or more parameters, in the form of `<param>=<value>`, with each parameter separated by the ampersand character (&), and no spaces anywhere in the connection string. |
| max. open Connections | How many connections to snowflake are opened at a time. If the limit of open connections is exceeded newer queries will be cached in the queue. [default: 100] |
| max. queued Queries | Queue size of the internal query queue. If this limit is exceeded the query will be dropped and and error is thrown. Should always be higher as `max. open Connections`. 0 to disable. [default: 400] |
| Connection lifetime | Time in minutes until unused connections are recycled. [default: 60min] |

**External OAuth authentication**

Expand All @@ -103,6 +106,7 @@ EXTERNAL_OAUTH_RSA_PUBLIC_KEY = 'MIIBIj'
EXTERNAL_OAUTH_ISSUER = 'https://xxxxx';
```


#### Supported Macros

Macros can be used within a query to simplify syntax and allow for dynamic parts.
Expand Down
21 changes: 8 additions & 13 deletions pkg/check_health.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ package main

import (
"context"
"database/sql"
"fmt"

"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/michelin/snowflake-grafana-datasource/pkg/data"
_oauth "github.com/michelin/snowflake-grafana-datasource/pkg/oauth"
"github.com/michelin/snowflake-grafana-datasource/pkg/utils"
_ "github.com/snowflakedb/gosnowflake"
)

Expand All @@ -16,22 +15,18 @@ import (
// datasource configuration page which allows users to verify that
// a datasource is working as expected.
func (td *SnowflakeDatasource) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {

connectionString, result := createAndValidationConnectionString(req)
_, result := createAndValidationConnectionString(req)
if result != nil {
return result, nil
}
// Use the existing db field instead of opening a new connection
if td.db == nil || td.db.Ping() != nil {
var err error
td.db, err = sql.Open("snowflake", connectionString)
if err != nil {
return createHealthError(fmt.Sprintf("Connection issue : %s", err)), nil
}
i, err := td.im.Get(ctx, req.PluginContext)
if err != nil {
return nil, err
}
defer td.db.Close()
instance := i.(*instanceSettings)
db := instance.db

row, err := td.db.QueryContext(utils.AddQueryTagInfos(ctx, &data.QueryConfigStruct{}), "SELECT 1")
row, err := db.QueryContext(ctx, "SELECT 1")
if err != nil {
return createHealthError(fmt.Sprintf("Validation query error : %s", err)), nil
}
Expand Down
41 changes: 32 additions & 9 deletions pkg/check_health_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import (
"context"
"database/sql"
"fmt"
"testing"

"net/http"
"net/http/httptest"

"github.com/DATA-DOG/go-sqlmock"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
"github.com/stretchr/testify/require"
"net/http"
"net/http/httptest"
"testing"
)

func TestCheckHealthWithValidConnection(t *testing.T) {
Expand All @@ -18,7 +21,6 @@ func TestCheckHealthWithValidConnection(t *testing.T) {
defer db.Close()

mock.ExpectQuery("SELECT 1").WillReturnRows(sqlmock.NewRows([]string{"1"}).AddRow(1))

req := &backend.CheckHealthRequest{
PluginContext: backend.PluginContext{
DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{
Expand All @@ -28,8 +30,10 @@ func TestCheckHealthWithValidConnection(t *testing.T) {
},
}
ctx := context.Background()
td := &SnowflakeDatasource{db: db}
result, err := td.CheckHealth(ctx, req)

service := GetMockService(db)
service.im.Get(ctx, backend.PluginContext{})
result, err := service.CheckHealth(ctx, req)
require.NoError(t, err)
require.Equal(t, backend.HealthStatusOk, result.Status)
require.Equal(t, "Data source is working", result.Message)
Expand All @@ -41,7 +45,6 @@ func TestCheckHealthWithInvalidConnection(t *testing.T) {
defer db.Close()

mock.ExpectQuery("SELECT 1").WillReturnError(sql.ErrConnDone)

req := &backend.CheckHealthRequest{
PluginContext: backend.PluginContext{
DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{
Expand All @@ -51,8 +54,9 @@ func TestCheckHealthWithInvalidConnection(t *testing.T) {
},
}
ctx := context.Background()
td := &SnowflakeDatasource{db: db}
result, err := td.CheckHealth(ctx, req)
service := GetMockService(db)
service.im.Get(ctx, backend.PluginContext{})
result, err := service.CheckHealth(ctx, req)
require.NoError(t, err)
require.Equal(t, backend.HealthStatusError, result.Status)
require.Contains(t, result.Message, "Validation query error")
Expand Down Expand Up @@ -316,3 +320,22 @@ func TestErrorResultWithEmptyMessage(t *testing.T) {
require.Equal(t, backend.HealthStatusError, result.Status)
require.Equal(t, "", result.Message)
}

type FakeInstanceManager struct {
db *sql.DB
}

func (fakeInstanceManager *FakeInstanceManager) Get(ctx context.Context, setting backend.PluginContext) (instancemgmt.Instance, error) {
config := pluginConfig{} ///getConfig(&setting)
return &instanceSettings{db: fakeInstanceManager.db, config: &config}, nil
}

func (*FakeInstanceManager) Do(_ context.Context, _ backend.PluginContext, _ instancemgmt.InstanceCallbackFunc) error {
return nil
}

func GetMockService(db *sql.DB) *SnowflakeDatasource {
return &SnowflakeDatasource{
im: &FakeInstanceManager{db: db},
}
}
Loading