diff --git a/packages/grafana-data/src/types/config.ts b/packages/grafana-data/src/types/config.ts index 99c645d6d2d..d04d4b0a517 100644 --- a/packages/grafana-data/src/types/config.ts +++ b/packages/grafana-data/src/types/config.ts @@ -44,7 +44,6 @@ export enum GrafanaEdition { export interface FeatureToggles { [name: string]: boolean; - live: boolean; ngalert: boolean; trimDefaults: boolean; panelLibrary: boolean; diff --git a/packages/grafana-runtime/src/config.ts b/packages/grafana-runtime/src/config.ts index cc43e8af5bc..ec792831953 100644 --- a/packages/grafana-runtime/src/config.ts +++ b/packages/grafana-runtime/src/config.ts @@ -53,7 +53,6 @@ export class GrafanaBootConfig implements GrafanaConfig { theme2: GrafanaTheme2; pluginsToPreload: string[] = []; featureToggles: FeatureToggles = { - live: false, meta: false, ngalert: false, panelLibrary: false, diff --git a/pkg/api/api.go b/pkg/api/api.go index b600957d980..524b563d8db 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -413,21 +413,19 @@ func (hs *HTTPServer) registerRoutes() { apiRoute.Post("/frontend-metrics", bind(metrics.PostFrontendMetricsCommand{}), routing.Wrap(hs.PostFrontendMetrics)) - if hs.Live.IsEnabled() { - apiRoute.Group("/live", func(liveRoute routing.RouteRegister) { - // the channel path is in the name - liveRoute.Post("/publish", bind(dtos.LivePublishCmd{}), routing.Wrap(hs.Live.HandleHTTPPublish)) + apiRoute.Group("/live", func(liveRoute routing.RouteRegister) { + // the channel path is in the name + liveRoute.Post("/publish", bind(dtos.LivePublishCmd{}), routing.Wrap(hs.Live.HandleHTTPPublish)) - // POST influx line protocol - liveRoute.Post("/push/:streamId", hs.LivePushGateway.Handle) + // POST influx line protocol + liveRoute.Post("/push/:streamId", hs.LivePushGateway.Handle) - // List available streams and fields - liveRoute.Get("/list", routing.Wrap(hs.Live.HandleListHTTP)) + // List available streams and fields + liveRoute.Get("/list", routing.Wrap(hs.Live.HandleListHTTP)) - // Some channels may have info - liveRoute.Get("/info/*", routing.Wrap(hs.Live.HandleInfoHTTP)) - }) - } + // Some channels may have info + liveRoute.Get("/info/*", routing.Wrap(hs.Live.HandleInfoHTTP)) + }) // short urls apiRoute.Post("/short-urls", bind(dtos.CreateShortURLCmd{}), routing.Wrap(hs.createShortURL)) diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index 334706445ac..a7cedb356b3 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -270,8 +270,8 @@ func (hs *HTTPServer) deleteDashboard(c *models.ReqContext) response.Response { return response.Error(500, "Failed to delete dashboard", err) } - if hs.Live.IsEnabled() { - err := hs.Live.GrafanaScope.Dashboards.DashboardDeleted(c.ToUserDisplayDTO(), dash.Uid) + if hs.Live != nil { + err = hs.Live.GrafanaScope.Dashboards.DashboardDeleted(c.ToUserDisplayDTO(), dash.Uid) if err != nil { hs.log.Error("Failed to broadcast delete info", "dashboard", dash.Uid, "error", err) } @@ -337,8 +337,8 @@ func (hs *HTTPServer) PostDashboard(c *models.ReqContext, cmd models.SaveDashboa dashSvc := dashboards.NewService(hs.SQLStore) dashboard, err := dashSvc.SaveDashboard(dashItem, allowUiUpdate) - // Tell everyone listening that the dashboard changed - if hs.Live.IsEnabled() { + if hs.Live != nil { + // Tell everyone listening that the dashboard changed if dashboard == nil { dashboard = dash // the original request } @@ -360,6 +360,7 @@ func (hs *HTTPServer) PostDashboard(c *models.ReqContext, cmd models.SaveDashboa hs.log.Warn("unable to broadcast save event", "uid", dashboard.Uid, "error", err) } } + if err != nil { return hs.dashboardSaveErrorToApiResponse(err) } diff --git a/pkg/api/dashboard_test.go b/pkg/api/dashboard_test.go index ae4d1a759fc..6966410687f 100644 --- a/pkg/api/dashboard_test.go +++ b/pkg/api/dashboard_test.go @@ -78,6 +78,14 @@ type testState struct { dashQueries []*models.GetDashboardQuery } +func newTestLive(t *testing.T) *live.GrafanaLive { + gLive := live.NewGrafanaLive() + gLive.RouteRegister = routing.NewRouteRegister() + err := gLive.Init() + require.NoError(t, err) + return gLive +} + // This tests three main scenarios. // If a user has access to execute an action on a dashboard: // 1. and the dashboard is in a folder which does not have an acl @@ -263,7 +271,8 @@ func TestDashboardAPIEndpoint(t *testing.T) { t.Run("Given a dashboard with a parent folder which has an ACL", func(t *testing.T) { hs := &HTTPServer{ - Cfg: setting.NewCfg(), + Cfg: setting.NewCfg(), + Live: newTestLive(t), } setUp := func() *testState { @@ -1172,7 +1181,7 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s Bus: bus.GetBus(), Cfg: cfg, ProvisioningService: provisioning.NewProvisioningServiceMock(), - Live: &live.GrafanaLive{Cfg: setting.NewCfg()}, + Live: newTestLive(t), QuotaService: "a.QuotaService{ Cfg: cfg, }, @@ -1236,7 +1245,7 @@ func restoreDashboardVersionScenario(t *testing.T, desc string, url string, rout Cfg: cfg, Bus: bus.GetBus(), ProvisioningService: provisioning.NewProvisioningServiceMock(), - Live: &live.GrafanaLive{Cfg: cfg}, + Live: newTestLive(t), QuotaService: "a.QuotaService{Cfg: cfg}, } diff --git a/pkg/services/live/live.go b/pkg/services/live/live.go index db17a16a840..e8bbfb27b1e 100644 --- a/pkg/services/live/live.go +++ b/pkg/services/live/live.go @@ -115,7 +115,7 @@ func (g *GrafanaLive) getStreamPlugin(pluginID string) (backend.StreamHandler, e // AddMigration defines database migrations. // This is an implementation of registry.DatabaseMigrator. func (g *GrafanaLive) AddMigration(mg *migrator.Migrator) { - if !g.IsEnabled() { + if g == nil || g.Cfg == nil || !g.Cfg.IsLiveConfigEnabled() { return } database.AddLiveChannelMigrations(mg) @@ -136,11 +136,6 @@ var clientConcurrency = 8 func (g *GrafanaLive) Init() error { logger.Debug("GrafanaLive initialization") - if !g.IsEnabled() { - logger.Debug("GrafanaLive feature not enabled, skipping initialization") - return nil - } - // We use default config here as starting point. Default config contains // reasonable values for available options. cfg := centrifuge.DefaultConfig @@ -530,14 +525,6 @@ func (g *GrafanaLive) ClientCount(channel string) (int, error) { return len(p.Presence), nil } -// IsEnabled returns true if the Grafana Live feature is enabled. -func (g *GrafanaLive) IsEnabled() bool { - if g == nil || g.Cfg == nil { - return false - } - return g.Cfg.IsLiveEnabled() -} - func (g *GrafanaLive) HandleHTTPPublish(ctx *models.ReqContext, cmd dtos.LivePublishCmd) response.Response { addr := live.ParseChannel(cmd.Channel) if !addr.IsValid() { diff --git a/pkg/services/live/pushhttp/push.go b/pkg/services/live/pushhttp/push.go index 9e11aeec60b..393dc417207 100644 --- a/pkg/services/live/pushhttp/push.go +++ b/pkg/services/live/pushhttp/push.go @@ -34,30 +34,16 @@ type Gateway struct { func (g *Gateway) Init() error { logger.Info("Telemetry Gateway initialization") - if !g.IsEnabled() { - logger.Debug("Telemetry Gateway not enabled, skipping initialization") - return nil - } - g.converter = convert.NewConverter() return nil } // Run Gateway. func (g *Gateway) Run(ctx context.Context) error { - if !g.IsEnabled() { - logger.Debug("GrafanaLive feature not enabled, skipping initialization of Telemetry Gateway") - return nil - } <-ctx.Done() return ctx.Err() } -// IsEnabled returns true if the Grafana Live feature is enabled. -func (g *Gateway) IsEnabled() bool { - return g.Cfg.IsLiveEnabled() // turn on when Live on for now. -} - func (g *Gateway) Handle(ctx *models.ReqContext) { streamID := ctx.Params(":streamId") diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index 9d0589b55ec..e90dd6d4260 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -374,9 +374,9 @@ type Cfg struct { ImageUploadProvider string } -// IsLiveEnabled returns if grafana live should be enabled -func (cfg Cfg) IsLiveEnabled() bool { - return cfg.FeatureToggles["live"] +// IsLiveConfigEnabled returns true if live should be able to save configs to SQL tables +func (cfg Cfg) IsLiveConfigEnabled() bool { + return cfg.FeatureToggles["live-config"] } // IsNgAlertEnabled returns whether the standalone alerts feature is enabled. diff --git a/public/app/features/live/live.ts b/public/app/features/live/live.ts index aab6a25dac5..e23ed508f3c 100644 --- a/public/app/features/live/live.ts +++ b/public/app/features/live/live.ts @@ -54,7 +54,7 @@ export class CentrifugeSrv implements GrafanaLiveSrv { constructor() { // build live url replacing scheme in appUrl. - const liveUrl = `${config.appUrl}live/ws`.replace(/^(http)(s)?:\/\//, 'ws$2://'); + const liveUrl = `${config.appUrl.replace('http', 'ws')}live/ws`; this.centrifuge = new Centrifuge(liveUrl, { debug: true, }); diff --git a/public/app/plugins/datasource/cloudwatch/datasource.ts b/public/app/plugins/datasource/cloudwatch/datasource.ts index 5d97ab7ba55..1ee2ec6c17d 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.ts +++ b/public/app/plugins/datasource/cloudwatch/datasource.ts @@ -65,7 +65,6 @@ import { CloudWatchLanguageProvider } from './language_provider'; import { VariableWithMultiSupport } from 'app/features/variables/types'; import { AwsUrl, encodeUrl } from './aws_url'; import { increasingInterval } from './utils/rxjs/increasingInterval'; -import config from 'app/core/config'; const DS_QUERY_ENDPOINT = '/api/ds/query'; @@ -128,11 +127,8 @@ export class CloudWatchDatasource extends DataSourceApi> = []; if (logQueries.length > 0) { - if (config.featureToggles.live) { - dataQueryResponses.push(this.handleLiveLogQueries(logQueries, options)); - } else { - dataQueryResponses.push(this.handleLogQueries(logQueries, options)); - } + dataQueryResponses.push(this.handleLiveLogQueries(logQueries, options)); + // dataQueryResponses.push(this.handleLogQueries(logQueries, options)); } if (metricsQueries.length > 0) { diff --git a/public/app/routes/GrafanaCtrl.ts b/public/app/routes/GrafanaCtrl.ts index b27080bb687..7a78a461783 100644 --- a/public/app/routes/GrafanaCtrl.ts +++ b/public/app/routes/GrafanaCtrl.ts @@ -57,10 +57,7 @@ export class GrafanaCtrl { setLocationSrv(locationService); - // Initialize websocket event streaming - if (config.featureToggles.live) { - initGrafanaLive(); - } + initGrafanaLive(); $scope.init = () => { $scope.contextSrv = contextSrv;