Skip to content

Commit

Permalink
Merge branch 'main' of github.com:HadesArchitect/GrafanaCassandraData…
Browse files Browse the repository at this point in the history
…source
  • Loading branch information
HadesArchitect committed Apr 28, 2022
2 parents 23238e4 + 285f480 commit e2645ad
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 45 deletions.
84 changes: 51 additions & 33 deletions backend/datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net/http"
"strings"

"strconv"
"time"
Expand All @@ -23,7 +24,6 @@ type CassandraDatasource struct {
resourceHandler backend.CallResourceHandler
builder *QueryBuilder
processor *QueryProcessor
sessions map[int]*gocql.Session
session *gocql.Session
}

Expand All @@ -43,7 +43,7 @@ func NewDataSource() *CassandraDatasource {
}

func (ds *CassandraDatasource) handleKeyspaces(rw http.ResponseWriter, req *http.Request) {
ds.logger.Info("Process 'keyspaces' request")
ds.logger.Debug("Process 'keyspaces' request")

ctx := httpadapter.PluginConfigFromContext(req.Context())

Expand All @@ -59,7 +59,7 @@ func (ds *CassandraDatasource) handleKeyspaces(rw http.ResponseWriter, req *http
}

func (ds *CassandraDatasource) handleTables(rw http.ResponseWriter, req *http.Request) {
ds.logger.Info("Process 'tables' request")
ds.logger.Debug("Process 'tables' request")

ctx := httpadapter.PluginConfigFromContext(req.Context())

Expand Down Expand Up @@ -127,10 +127,10 @@ func (ds *CassandraDatasource) HandleMetricQueries(ctx context.Context, req *bac
}

func (ds *CassandraDatasource) handleMetricQuery(ctx *backend.PluginContext, query backend.DataQuery) backend.DataResponse {
_, err := ds.connect(ctx)
err := ds.connectIfNeeded(ctx)
if err != nil {
ds.logger.Warn("Failed to connect", "Message", err)
return dataResponse(data.Frames{}, fmt.Errorf("Failed to connect to server, please inspect Grafana server log for details"))
return dataResponse(data.Frames{}, errors.New("Failed to connect to server, please inspect Grafana server log for details"))
}

frames, err := ds.metricQuery(&query)
Expand All @@ -139,7 +139,7 @@ func (ds *CassandraDatasource) handleMetricQuery(ctx *backend.PluginContext, que
}

func (ds *CassandraDatasource) getConnected(ctx *backend.PluginContext, getData func() ([]string, error)) ([]string, error) {
_, err := ds.connect(ctx)
err := ds.connectIfNeeded(ctx)
if err != nil {
ds.logger.Warn("Failed to connect", "Message", err)

Expand Down Expand Up @@ -223,14 +223,21 @@ func (ds *CassandraDatasource) getKeyspaces(ctx *backend.PluginContext) ([]strin
return ds.getConnected(ctx, getKeyspaces)
}

func (ds *CassandraDatasource) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) error {
_, err := ds.connect(&req.PluginContext)
func (ds *CassandraDatasource) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
err := ds.connect(&req.PluginContext)
if err != nil {
ds.logger.Warn("Failed to connect", "Message", err)
return fmt.Errorf("Failed to connect to server, please inspect Grafana server log for details")

return &backend.CheckHealthResult{
Status: backend.HealthStatusError,
Message: "Failed to connect to server, please inspect Grafana server log for details",
}, nil
}

return nil
return &backend.CheckHealthResult{
Status: backend.HealthStatusOk,
Message: "Database connected",
}, nil
}

func processQueries(req *backend.QueryDataRequest, handler func(*backend.PluginContext, backend.DataQuery) backend.DataResponse) backend.Responses {
Expand All @@ -247,7 +254,8 @@ func (ds *CassandraDatasource) metricQuery(query *backend.DataQuery) (data.Frame
err := json.Unmarshal(query.JSON, &cassQuery)
if err != nil {
ds.logger.Error("Failed to parse queries", "Message", err)
return nil, fmt.Errorf("Failed to parse queries, please inspect Grafana server log for details")

return nil, errors.New("Failed to parse queries, please inspect Grafana server log for details")
}

if cassQuery.RawQuery {
Expand All @@ -267,35 +275,44 @@ func (ds *CassandraDatasource) getRequestOptions(jsonData []byte) (DataSourceOpt
err := json.Unmarshal(jsonData, &options)
if err != nil {
ds.logger.Error("Failed to parse request", "Message", err)
return options, fmt.Errorf("Failed to parse request, please inspect Grafana server log for details")

return options, errors.New("Failed to parse request, please inspect Grafana server log for details")
}
return options, nil
}

func (ds *CassandraDatasource) connect(context *backend.PluginContext) (bool, error) {
options, err := ds.getRequestOptions(context.DataSourceInstanceSettings.JSONData)
if err != nil {
ds.logger.Error("Failed to parse connection parameters", "Message", err)
return false, fmt.Errorf("Failed to parse connection parameters, please inspect Grafana server log for details")
func (ds *CassandraDatasource) connectIfNeeded(context *backend.PluginContext) error {
if ds.session != nil {
return nil
}

datasourceID := int(context.DataSourceInstanceSettings.ID)
return ds.connect(context)
}

if ds.sessions == nil {
ds.sessions = make(map[int]*gocql.Session)
}
func (ds *CassandraDatasource) connect(context *backend.PluginContext) error {
hosts := strings.Split(context.DataSourceInstanceSettings.URL, ";")

if ds.sessions[datasourceID] != nil {
ds.session = ds.sessions[datasourceID]
err := ds.tryToConnect(hosts, context)
if err != nil {
ds.logger.Error("Failed to connect", "Message", err)

return true, nil
return errors.New("Failed to connect, please inspect Grafana server log for details")
}

host := context.DataSourceInstanceSettings.URL
return nil
}

func (ds *CassandraDatasource) tryToConnect(hosts []string, context *backend.PluginContext) error {
options, err := ds.getRequestOptions(context.DataSourceInstanceSettings.JSONData)
if err != nil {
ds.logger.Error("Failed to parse connection parameters", "Message", err)

ds.logger.Debug(fmt.Sprintf("Connecting to %s...\n", host))
return errors.New("Failed to parse connection parameters, please inspect Grafana server log for details")
}

cluster := gocql.NewCluster(host)
ds.logger.Debug("Connecting", "Hosts", hosts)

cluster := gocql.NewCluster(hosts...)

if options.Timeout != nil {
cluster.Timeout = time.Duration(*options.Timeout) * time.Second
Expand All @@ -304,7 +321,8 @@ func (ds *CassandraDatasource) connect(context *backend.PluginContext) (bool, er
consistency, err := parseConsistency(options.Consistency)
if err != nil {
ds.logger.Error("Failed to parse consistency", "Message", err, "Consistency", options.Consistency)
return false, fmt.Errorf("Failed to parse consistency, please inspect Grafana server log for details")

return errors.New("Failed to parse consistency, please inspect Grafana server log for details")
}

cluster.Consistency = consistency
Expand All @@ -321,7 +339,8 @@ func (ds *CassandraDatasource) connect(context *backend.PluginContext) (bool, er
tlsConfig, err := PrepareTLSCfg(options.CertPath, options.RootPath, options.CaPath, options.AllowInsecureTLS)
if err != nil {
ds.logger.Error("Failed to create TLS config", "Message", err)
return false, fmt.Errorf("Failed to create TLS config, please inspect Grafana server log for details")

return errors.New("Failed to create TLS config, please inspect Grafana server log for details")
}

cluster.SslOpts = &gocql.SslOptions{Config: tlsConfig}
Expand All @@ -330,14 +349,13 @@ func (ds *CassandraDatasource) connect(context *backend.PluginContext) (bool, er
session, err := cluster.CreateSession()
if err != nil {
ds.logger.Warn("Failed to create session", "Message", err)
return false, fmt.Errorf("Failed to create Cassandra session, please inspect Grafana server log for details")

return errors.New("Failed to create Cassandra session, please inspect Grafana server log for details")
}

ds.sessions[datasourceID] = session
ds.session = session

ds.logger.Debug("Connection successful")
return true, nil
return nil
}

func parseConsistency(consistencyStr string) (consistency gocql.Consistency, err error) {
Expand Down
13 changes: 1 addition & 12 deletions backend/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,7 @@ func (handler *Handler) CheckHealth(ctx context.Context, req *backend.CheckHealt
}, nil
}

err = datasource.CheckHealth(ctx, req)
if err != nil {
return &backend.CheckHealthResult{
Status: backend.HealthStatusError,
Message: fmt.Sprintf("Connection test failed, error = %v", err),
}, nil
}

return &backend.CheckHealthResult{
Status: backend.HealthStatusOk,
Message: "Database connected",
}, nil
return datasource.CheckHealth(ctx, req)
}

func NewHandler() *Handler {
Expand Down

0 comments on commit e2645ad

Please sign in to comment.