@@ -25,7 +25,9 @@ import (
2525// This is a list of interfaces that the Service implements.
2626// Go will not compile if we don't implement all of these interfaces.
2727var (
28- _ backend.StreamHandler = (* OpenSearchDatasource )(nil )
28+ _ backend.QueryDataHandler = (* OpenSearchDatasource )(nil )
29+ _ backend.StreamHandler = (* OpenSearchDatasource )(nil )
30+ _ backend.CallResourceHandler = (* OpenSearchDatasource )(nil )
2931)
3032
3133type datasourceInfo struct {
@@ -51,26 +53,35 @@ func newInstanceSettings(client *http.Client) datasource.InstanceFactoryFunc {
5153// OpenSearchExecutor represents a handler for handling OpenSearch datasource request
5254type OpenSearchExecutor struct {}
5355
56+ // OpenSearchDatasource is an OpenSearch data source.
5457type OpenSearchDatasource struct {
55- HttpClient * http.Client
56- backend.StreamHandler
57- im instancemgmt.InstanceManager
58- logger log.Logger
58+ // instance manager just holds a pointer to the open search client
59+ im instancemgmt.InstanceManager
60+
61+ // httpClient is the general httpClient for the datasource to use for miscellaneous calls
62+ httpClient * http.Client
63+ logger log.Logger
64+
65+ // streamQueries stores active queries for streaming sessions, keyed by a unique ID (e.g., refId)
66+ streamQueries sync.Map
5967}
6068
69+ // NewOpenSearchDatasource creates a new OpenSearchDatasource and sets up its configuration.
6170func NewOpenSearchDatasource (ctx context.Context , settings backend.DataSourceInstanceSettings ) (instancemgmt.Instance , error ) {
6271 log .DefaultLogger .Debug ("Initializing new data source instance" )
6372
73+ // Use a default http client for now
6474 httpClient , err := client .NewDatasourceHttpClient (ctx , & settings )
6575 if err != nil {
6676 return nil , err
6777 }
6878
69- return & OpenSearchDatasource {
70- HttpClient : httpClient ,
79+ ds := & OpenSearchDatasource {
7180 im : datasource .NewInstanceManager (newInstanceSettings (httpClient )),
81+ httpClient : httpClient ,
7282 logger : backend .NewLoggerWith ("logger" , "tsdb.opensearch" ),
73- }, nil
83+ }
84+ return ds , nil
7485}
7586
7687// CheckHealth handles health checks sent from Grafana to the plugin.
@@ -146,7 +157,7 @@ func (ds *OpenSearchDatasource) CheckHealth(ctx context.Context, req *backend.Ch
146157 }
147158 request .Header = req .GetHTTPHeaders ()
148159
149- response , err := ds .HttpClient .Do (request )
160+ response , err := ds .httpClient .Do (request )
150161 if err != nil {
151162 res .Status = backend .HealthStatusError
152163 res .Message = err .Error ()
@@ -213,12 +224,18 @@ func (ds *OpenSearchDatasource) CheckHealth(ctx context.Context, req *backend.Ch
213224// The QueryDataResponse contains a map of RefID to the response for each query, and each response
214225// contains Frames ([]*Frame).
215226func (ds * OpenSearchDatasource ) QueryData (ctx context.Context , req * backend.QueryDataRequest ) (* backend.QueryDataResponse , error ) {
227+ ds .logger .Info ("QueryData called" , "numQueries" , len (req .Queries ))
216228 if len (req .Queries ) == 0 {
217229 return nil , fmt .Errorf ("query contains no queries" )
218230 }
219231
232+ if len (req .Queries ) > 0 {
233+ jsonData , _ := req .Queries [0 ].JSON .MarshalJSON ()
234+ ds .logger .Info ("QueryData - First query JSON" , "refId" , req .Queries [0 ].RefID , "json" , string (jsonData ), "interval" , req .Queries [0 ].Interval .String (), "timeRangeFrom" , req .Queries [0 ].TimeRange .From .String (), "timeRangeTo" , req .Queries [0 ].TimeRange .To .String ())
235+ }
236+
220237 timeRange := req .Queries [0 ].TimeRange
221- osClient , err := client .NewClient (ctx , req .PluginContext .DataSourceInstanceSettings , ds .HttpClient , & timeRange )
238+ osClient , err := client .NewClient (ctx , req .PluginContext .DataSourceInstanceSettings , ds .httpClient , & timeRange )
222239 if err != nil {
223240 return nil , err
224241 }
@@ -229,7 +246,11 @@ func (ds *OpenSearchDatasource) QueryData(ctx context.Context, req *backend.Quer
229246 }
230247
231248 query := newQueryRequest (osClient , req .Queries , req .PluginContext .DataSourceInstanceSettings )
249+ ds .logger .Info ("QueryData - About to execute query" )
232250 response , err = wrapError (query .execute (ctx ))
251+ if err != nil {
252+ ds .logger .Error ("QueryData - Error executing query" , "error" , err .Error ())
253+ }
233254 return response , err
234255}
235256
@@ -335,6 +356,14 @@ func extractParametersFromServiceMapFrames(resp *backend.QueryDataResponse) ([]s
335356}
336357
337358func (ds * OpenSearchDatasource ) CallResource (ctx context.Context , req * backend.CallResourceRequest , sender backend.CallResourceResponseSender ) error {
359+ ds .logger .Info ("CallResource called" , "path" , req .Path , "method" , req .Method )
360+
361+ // Route for registering stream queries
362+ if strings .HasPrefix (req .Path , "_stream_query_register/" ) {
363+ return ds .handleRegisterStreamQuery (ctx , req , sender )
364+ }
365+
366+ // Existing resource call logic
338367 // allowed paths for resource calls:
339368 // - empty string for fetching db version
340369 // - /_mapping for fetching index mapping, e.g. requests going to `index/_mapping`
@@ -355,7 +384,7 @@ func (ds *OpenSearchDatasource) CallResource(ctx context.Context, req *backend.C
355384 }
356385 request .Header = req .GetHTTPHeaders ()
357386
358- response , err := ds .HttpClient .Do (request )
387+ response , err := ds .httpClient .Do (request )
359388 if err != nil {
360389 return err
361390 }
0 commit comments