| 
									
										
										
										
											2018-10-26 16:40:33 +08:00
										 |  |  | package datasources | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2021-10-18 23:06:19 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2018-10-26 16:40:33 +08:00
										 |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-13 16:55:38 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/infra/localcache" | 
					
						
							| 
									
										
										
										
											2020-02-29 20:35:15 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/models" | 
					
						
							| 
									
										
										
										
											2020-08-21 15:30:06 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/sqlstore" | 
					
						
							| 
									
										
										
										
											2018-10-26 16:40:33 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 21:11:22 +08:00
										 |  |  | func ProvideCacheService(cacheService *localcache.CacheService, sqlStore *sqlstore.SQLStore) *CacheServiceImpl { | 
					
						
							|  |  |  | 	return &CacheServiceImpl{ | 
					
						
							|  |  |  | 		CacheService: cacheService, | 
					
						
							|  |  |  | 		SQLStore:     sqlStore, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-26 16:40:33 +08:00
										 |  |  | type CacheService interface { | 
					
						
							| 
									
										
										
										
											2020-02-29 20:35:15 +08:00
										 |  |  | 	GetDatasource(datasourceID int64, user *models.SignedInUser, skipCache bool) (*models.DataSource, error) | 
					
						
							| 
									
										
										
										
											2021-01-14 02:16:27 +08:00
										 |  |  | 	GetDatasourceByUID(datasourceUID string, user *models.SignedInUser, skipCache bool) (*models.DataSource, error) | 
					
						
							| 
									
										
										
										
											2018-10-26 16:40:33 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type CacheServiceImpl struct { | 
					
						
							| 
									
										
										
										
											2021-08-25 21:11:22 +08:00
										 |  |  | 	CacheService *localcache.CacheService | 
					
						
							|  |  |  | 	SQLStore     *sqlstore.SQLStore | 
					
						
							| 
									
										
										
										
											2018-10-26 16:40:33 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-21 15:30:06 +08:00
										 |  |  | func (dc *CacheServiceImpl) GetDatasource( | 
					
						
							|  |  |  | 	datasourceID int64, | 
					
						
							|  |  |  | 	user *models.SignedInUser, | 
					
						
							|  |  |  | 	skipCache bool, | 
					
						
							|  |  |  | ) (*models.DataSource, error) { | 
					
						
							| 
									
										
										
										
											2021-01-14 02:16:27 +08:00
										 |  |  | 	cacheKey := idKey(datasourceID) | 
					
						
							| 
									
										
										
										
											2018-10-26 16:40:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if !skipCache { | 
					
						
							|  |  |  | 		if cached, found := dc.CacheService.Get(cacheKey); found { | 
					
						
							| 
									
										
										
										
											2020-02-29 20:35:15 +08:00
										 |  |  | 			ds := cached.(*models.DataSource) | 
					
						
							| 
									
										
										
										
											2018-10-26 16:40:33 +08:00
										 |  |  | 			if ds.OrgId == user.OrgId { | 
					
						
							|  |  |  | 				return ds, nil | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-21 15:30:06 +08:00
										 |  |  | 	plog.Debug("Querying for data source via SQL store", "id", datasourceID, "orgId", user.OrgId) | 
					
						
							| 
									
										
										
										
											2021-10-07 22:33:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	query := &models.GetDataSourceQuery{Id: datasourceID, OrgId: user.OrgId} | 
					
						
							| 
									
										
										
										
											2021-10-18 23:06:19 +08:00
										 |  |  | 	err := dc.SQLStore.GetDataSource(context.TODO(), query) | 
					
						
							| 
									
										
										
										
											2020-08-21 15:30:06 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2018-10-26 16:40:33 +08:00
										 |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-07 22:33:50 +08:00
										 |  |  | 	ds := query.Result | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-14 02:16:27 +08:00
										 |  |  | 	if ds.Uid != "" { | 
					
						
							|  |  |  | 		dc.CacheService.Set(uidKey(ds.OrgId, ds.Uid), ds, time.Second*5) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-08-21 15:30:06 +08:00
										 |  |  | 	dc.CacheService.Set(cacheKey, ds, time.Second*5) | 
					
						
							|  |  |  | 	return ds, nil | 
					
						
							| 
									
										
										
										
											2018-10-26 16:40:33 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2021-01-14 02:16:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func (dc *CacheServiceImpl) GetDatasourceByUID( | 
					
						
							|  |  |  | 	datasourceUID string, | 
					
						
							|  |  |  | 	user *models.SignedInUser, | 
					
						
							|  |  |  | 	skipCache bool, | 
					
						
							|  |  |  | ) (*models.DataSource, error) { | 
					
						
							|  |  |  | 	if datasourceUID == "" { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("can not get data source by uid, uid is empty") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if user.OrgId == 0 { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("can not get data source by uid, orgId is missing") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	uidCacheKey := uidKey(user.OrgId, datasourceUID) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !skipCache { | 
					
						
							|  |  |  | 		if cached, found := dc.CacheService.Get(uidCacheKey); found { | 
					
						
							|  |  |  | 			ds := cached.(*models.DataSource) | 
					
						
							|  |  |  | 			if ds.OrgId == user.OrgId { | 
					
						
							|  |  |  | 				return ds, nil | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	plog.Debug("Querying for data source via SQL store", "uid", datasourceUID, "orgId", user.OrgId) | 
					
						
							| 
									
										
										
										
											2021-10-07 22:33:50 +08:00
										 |  |  | 	query := &models.GetDataSourceQuery{Uid: datasourceUID, OrgId: user.OrgId} | 
					
						
							| 
									
										
										
										
											2021-10-18 23:06:19 +08:00
										 |  |  | 	err := dc.SQLStore.GetDataSource(context.TODO(), query) | 
					
						
							| 
									
										
										
										
											2021-01-14 02:16:27 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-07 22:33:50 +08:00
										 |  |  | 	ds := query.Result | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-14 02:16:27 +08:00
										 |  |  | 	dc.CacheService.Set(uidCacheKey, ds, time.Second*5) | 
					
						
							|  |  |  | 	dc.CacheService.Set(idKey(ds.Id), ds, time.Second*5) | 
					
						
							|  |  |  | 	return ds, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func idKey(id int64) string { | 
					
						
							|  |  |  | 	return fmt.Sprintf("ds-%d", id) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func uidKey(orgID int64, uid string) string { | 
					
						
							|  |  |  | 	return fmt.Sprintf("ds-orgid-uid-%d-%s", orgID, uid) | 
					
						
							|  |  |  | } |