refactor(unified-storage): move generated protos to own pkg (#105356)
This commit is contained in:
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/grafana/grafana-app-sdk/logging"
|
||||
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/db"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/dbutil"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate"
|
||||
@@ -36,7 +37,7 @@ const defaultPrunerHistoryLimit = 20
|
||||
|
||||
type Backend interface {
|
||||
resource.StorageBackend
|
||||
resource.DiagnosticsServer
|
||||
resourcepb.DiagnosticsServer
|
||||
resource.LifecycleHooks
|
||||
}
|
||||
|
||||
@@ -218,7 +219,7 @@ func (b *backend) initPruner(ctx context.Context) error {
|
||||
res, err := dbutil.Exec(ctx, tx, sqlResourceHistoryPrune, &sqlPruneHistoryRequest{
|
||||
SQLTemplate: sqltemplate.New(b.dialect),
|
||||
HistoryLimit: defaultPrunerHistoryLimit,
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: key.namespace,
|
||||
Group: key.group,
|
||||
Resource: key.resource,
|
||||
@@ -260,14 +261,14 @@ func (b *backend) initPruner(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *backend) IsHealthy(ctx context.Context, r *resource.HealthCheckRequest) (*resource.HealthCheckResponse, error) {
|
||||
func (b *backend) IsHealthy(ctx context.Context, _ *resourcepb.HealthCheckRequest) (*resourcepb.HealthCheckResponse, error) {
|
||||
// ctxLogger := s.log.FromContext(log.WithContextualAttributes(ctx, []any{"method", "isHealthy"}))
|
||||
|
||||
if err := b.db.PingContext(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &resource.HealthCheckResponse{Status: resource.HealthCheckResponse_SERVING}, nil
|
||||
return &resourcepb.HealthCheckResponse{Status: resourcepb.HealthCheckResponse_SERVING}, nil
|
||||
}
|
||||
|
||||
func (b *backend) Stop(_ context.Context) error {
|
||||
@@ -313,11 +314,11 @@ func (b *backend) WriteEvent(ctx context.Context, event resource.WriteEvent) (in
|
||||
defer span.End()
|
||||
// TODO: validate key ?
|
||||
switch event.Type {
|
||||
case resource.WatchEvent_ADDED:
|
||||
case resourcepb.WatchEvent_ADDED:
|
||||
return b.create(ctx, event)
|
||||
case resource.WatchEvent_MODIFIED:
|
||||
case resourcepb.WatchEvent_MODIFIED:
|
||||
return b.update(ctx, event)
|
||||
case resource.WatchEvent_DELETED:
|
||||
case resourcepb.WatchEvent_DELETED:
|
||||
return b.delete(ctx, event)
|
||||
default:
|
||||
return 0, fmt.Errorf("unsupported event type")
|
||||
@@ -525,7 +526,7 @@ func (b *backend) delete(ctx context.Context, event resource.WriteEvent) (int64,
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
func (b *backend) ReadResource(ctx context.Context, req *resource.ReadRequest) *resource.BackendReadResponse {
|
||||
func (b *backend) ReadResource(ctx context.Context, req *resourcepb.ReadRequest) *resource.BackendReadResponse {
|
||||
_, span := b.tracer.Start(ctx, tracePrefix+".Read")
|
||||
defer span.End()
|
||||
|
||||
@@ -558,7 +559,7 @@ func (b *backend) ReadResource(ctx context.Context, req *resource.ReadRequest) *
|
||||
return res
|
||||
}
|
||||
|
||||
func (b *backend) ListIterator(ctx context.Context, req *resource.ListRequest, cb func(resource.ListIterator) error) (int64, error) {
|
||||
func (b *backend) ListIterator(ctx context.Context, req *resourcepb.ListRequest, cb func(resource.ListIterator) error) (int64, error) {
|
||||
ctx, span := b.tracer.Start(ctx, tracePrefix+"List")
|
||||
defer span.End()
|
||||
|
||||
@@ -570,7 +571,7 @@ func (b *backend) ListIterator(ctx context.Context, req *resource.ListRequest, c
|
||||
return 0, fmt.Errorf("missing group or resource")
|
||||
}
|
||||
|
||||
if req.Source != resource.ListRequest_STORE {
|
||||
if req.Source != resourcepb.ListRequest_STORE {
|
||||
return b.getHistory(ctx, req, cb)
|
||||
}
|
||||
|
||||
@@ -652,7 +653,7 @@ func (l *listIter) Next() bool {
|
||||
var _ resource.ListIterator = (*listIter)(nil)
|
||||
|
||||
// listLatest fetches the resources from the resource table.
|
||||
func (b *backend) listLatest(ctx context.Context, req *resource.ListRequest, cb func(resource.ListIterator) error) (int64, error) {
|
||||
func (b *backend) listLatest(ctx context.Context, req *resourcepb.ListRequest, cb func(resource.ListIterator) error) (int64, error) {
|
||||
ctx, span := b.tracer.Start(ctx, tracePrefix+"listLatest")
|
||||
defer span.End()
|
||||
|
||||
@@ -673,9 +674,9 @@ func (b *backend) listLatest(ctx context.Context, req *resource.ListRequest, cb
|
||||
|
||||
listReq := sqlResourceListRequest{
|
||||
SQLTemplate: sqltemplate.New(b.dialect),
|
||||
Request: new(resource.ListRequest),
|
||||
Request: new(resourcepb.ListRequest),
|
||||
}
|
||||
listReq.Request = proto.Clone(req).(*resource.ListRequest)
|
||||
listReq.Request = proto.Clone(req).(*resourcepb.ListRequest)
|
||||
|
||||
rows, err := dbutil.QueryRows(ctx, tx, sqlResourceList, listReq)
|
||||
if rows != nil {
|
||||
@@ -696,7 +697,7 @@ func (b *backend) listLatest(ctx context.Context, req *resource.ListRequest, cb
|
||||
}
|
||||
|
||||
// listAtRevision fetches the resources from the resource_history table at a specific revision.
|
||||
func (b *backend) listAtRevision(ctx context.Context, req *resource.ListRequest, cb func(resource.ListIterator) error) (int64, error) {
|
||||
func (b *backend) listAtRevision(ctx context.Context, req *resourcepb.ListRequest, cb func(resource.ListIterator) error) (int64, error) {
|
||||
ctx, span := b.tracer.Start(ctx, tracePrefix+"listAtRevision")
|
||||
defer span.End()
|
||||
|
||||
@@ -756,7 +757,7 @@ func (b *backend) listAtRevision(ctx context.Context, req *resource.ListRequest,
|
||||
}
|
||||
|
||||
// readHistory fetches the resource history from the resource_history table.
|
||||
func (b *backend) readHistory(ctx context.Context, key *resource.ResourceKey, rv int64) *resource.BackendReadResponse {
|
||||
func (b *backend) readHistory(ctx context.Context, key *resourcepb.ResourceKey, rv int64) *resource.BackendReadResponse {
|
||||
_, span := b.tracer.Start(ctx, tracePrefix+".ReadHistory")
|
||||
defer span.End()
|
||||
|
||||
@@ -787,19 +788,19 @@ func (b *backend) readHistory(ctx context.Context, key *resource.ResourceKey, rv
|
||||
}
|
||||
|
||||
// getHistory fetches the resource history from the resource_history table.
|
||||
func (b *backend) getHistory(ctx context.Context, req *resource.ListRequest, cb func(resource.ListIterator) error) (int64, error) {
|
||||
func (b *backend) getHistory(ctx context.Context, req *resourcepb.ListRequest, cb func(resource.ListIterator) error) (int64, error) {
|
||||
ctx, span := b.tracer.Start(ctx, tracePrefix+"getHistory")
|
||||
defer span.End()
|
||||
listReq := sqlGetHistoryRequest{
|
||||
SQLTemplate: sqltemplate.New(b.dialect),
|
||||
Key: req.Options.Key,
|
||||
Trash: req.Source == resource.ListRequest_TRASH,
|
||||
Trash: req.Source == resourcepb.ListRequest_TRASH,
|
||||
}
|
||||
|
||||
// We are assuming that users want history in ascending order
|
||||
// when they are using NotOlderThan matching, and descending order
|
||||
// for Unset (default) and Exact matching.
|
||||
listReq.SortAscending = req.GetVersionMatchV2() == resource.ResourceVersionMatchV2_NotOlderThan
|
||||
listReq.SortAscending = req.GetVersionMatchV2() == resourcepb.ResourceVersionMatchV2_NotOlderThan
|
||||
|
||||
iter := &listIter{}
|
||||
if req.NextPageToken != "" {
|
||||
@@ -813,7 +814,7 @@ func (b *backend) getHistory(ctx context.Context, req *resource.ListRequest, cb
|
||||
iter.sortAsc = listReq.SortAscending
|
||||
|
||||
// Set ExactRV when using Exact matching
|
||||
if req.VersionMatchV2 == resource.ResourceVersionMatchV2_Exact {
|
||||
if req.VersionMatchV2 == resourcepb.ResourceVersionMatchV2_Exact {
|
||||
if req.ResourceVersion <= 0 {
|
||||
return 0, fmt.Errorf("expecting an explicit resource version query when using Exact matching")
|
||||
}
|
||||
@@ -821,12 +822,12 @@ func (b *backend) getHistory(ctx context.Context, req *resource.ListRequest, cb
|
||||
}
|
||||
|
||||
// Set MinRV when using NotOlderThan matching to filter at the database level
|
||||
if req.ResourceVersion > 0 && req.VersionMatchV2 == resource.ResourceVersionMatchV2_NotOlderThan {
|
||||
if req.ResourceVersion > 0 && req.VersionMatchV2 == resourcepb.ResourceVersionMatchV2_NotOlderThan {
|
||||
listReq.MinRV = req.ResourceVersion
|
||||
}
|
||||
|
||||
// Ignore last deleted history record when listing the trash, using exact matching or not older than matching with a specific RV
|
||||
useLatestDeletionAsMinRV := listReq.MinRV == 0 && !listReq.Trash && req.VersionMatchV2 != resource.ResourceVersionMatchV2_Exact
|
||||
useLatestDeletionAsMinRV := listReq.MinRV == 0 && !listReq.Trash && req.VersionMatchV2 != resourcepb.ResourceVersionMatchV2_Exact
|
||||
|
||||
err := b.db.WithTx(ctx, ReadCommittedRO, func(ctx context.Context, tx db.Tx) error {
|
||||
var err error
|
||||
@@ -836,7 +837,7 @@ func (b *backend) getHistory(ctx context.Context, req *resource.ListRequest, cb
|
||||
}
|
||||
|
||||
if useLatestDeletionAsMinRV {
|
||||
latestDeletedRV, err := b.fetchLatestHistoryRV(ctx, tx, b.dialect, req.Options.Key, resource.WatchEvent_DELETED)
|
||||
latestDeletedRV, err := b.fetchLatestHistoryRV(ctx, tx, b.dialect, req.Options.Key, resourcepb.WatchEvent_DELETED)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -914,7 +915,7 @@ func (b *backend) fetchLatestRV(ctx context.Context, x db.ContextExecer, d sqlte
|
||||
}
|
||||
|
||||
// fetchLatestHistoryRV returns the current maximum RV in the resource_history table
|
||||
func (b *backend) fetchLatestHistoryRV(ctx context.Context, x db.ContextExecer, d sqltemplate.Dialect, key *resource.ResourceKey, eventType resource.WatchEvent_Type) (int64, error) {
|
||||
func (b *backend) fetchLatestHistoryRV(ctx context.Context, x db.ContextExecer, d sqltemplate.Dialect, key *resourcepb.ResourceKey, eventType resourcepb.WatchEvent_Type) (int64, error) {
|
||||
ctx, span := b.tracer.Start(ctx, tracePrefix+"fetchLatestHistoryRV")
|
||||
defer span.End()
|
||||
res, err := dbutil.QueryRow(ctx, x, sqlResourceHistoryReadLatestRV, sqlResourceHistoryReadLatestRVRequest{
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/db/dbimpl"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/test"
|
||||
"github.com/grafana/grafana/pkg/util/testutil"
|
||||
@@ -22,7 +23,7 @@ import (
|
||||
|
||||
var (
|
||||
errTest = errors.New("things happened")
|
||||
resKey = &resource.ResourceKey{
|
||||
resKey = &resourcepb.ResourceKey{
|
||||
Namespace: "ns",
|
||||
Group: "gr",
|
||||
Resource: "rs",
|
||||
@@ -212,7 +213,7 @@ func TestBackend_create(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
event := resource.WriteEvent{
|
||||
Type: resource.WatchEvent_ADDED,
|
||||
Type: resourcepb.WatchEvent_ADDED,
|
||||
Key: resKey,
|
||||
Object: meta,
|
||||
}
|
||||
@@ -292,7 +293,7 @@ func TestBackend_update(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
meta.SetFolder("folderuid")
|
||||
event := resource.WriteEvent{
|
||||
Type: resource.WatchEvent_MODIFIED,
|
||||
Type: resourcepb.WatchEvent_MODIFIED,
|
||||
Key: resKey,
|
||||
Object: meta,
|
||||
}
|
||||
@@ -350,7 +351,7 @@ func TestBackend_delete(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
event := resource.WriteEvent{
|
||||
Type: resource.WatchEvent_DELETED,
|
||||
Type: resourcepb.WatchEvent_DELETED,
|
||||
Key: resKey,
|
||||
Object: meta,
|
||||
}
|
||||
@@ -445,7 +446,7 @@ func TestBackend_ReadResource(t *testing.T) {
|
||||
))
|
||||
b.SQLMock.ExpectCommit()
|
||||
|
||||
req := &resource.ReadRequest{
|
||||
req := &resourcepb.ReadRequest{
|
||||
Key: resKey,
|
||||
}
|
||||
rps := b.ReadResource(ctx, req)
|
||||
@@ -464,7 +465,7 @@ func TestBackend_ReadResource(t *testing.T) {
|
||||
WillReturnRows(sqlmock.NewRows([]string{}))
|
||||
b.SQLMock.ExpectCommit()
|
||||
|
||||
req := &resource.ReadRequest{
|
||||
req := &resourcepb.ReadRequest{
|
||||
Key: resKey,
|
||||
}
|
||||
res := b.ReadResource(ctx, req)
|
||||
@@ -503,7 +504,7 @@ func TestBackend_ReadResource(t *testing.T) {
|
||||
))
|
||||
b.SQLMock.ExpectCommit()
|
||||
|
||||
req := &resource.ReadRequest{
|
||||
req := &resourcepb.ReadRequest{
|
||||
Key: resKey,
|
||||
ResourceVersion: 300,
|
||||
}
|
||||
@@ -521,7 +522,7 @@ func TestBackend_ReadResource(t *testing.T) {
|
||||
b.SQLMock.ExpectQuery("SELECT .* FROM resource_history").
|
||||
WillReturnError(errTest)
|
||||
|
||||
req := &resource.ReadRequest{
|
||||
req := &resourcepb.ReadRequest{
|
||||
Key: resKey,
|
||||
}
|
||||
rps := b.ReadResource(ctx, req)
|
||||
@@ -533,7 +534,7 @@ func TestBackend_getHistory(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Common setup
|
||||
key := &resource.ResourceKey{
|
||||
key := &resourcepb.ResourceKey{
|
||||
Namespace: "ns",
|
||||
Group: "gr",
|
||||
Resource: "rs",
|
||||
@@ -544,8 +545,8 @@ func TestBackend_getHistory(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
source resource.ListRequest_Source
|
||||
versionMatch resource.ResourceVersionMatchV2
|
||||
source resourcepb.ListRequest_Source
|
||||
versionMatch resourcepb.ResourceVersionMatchV2
|
||||
resourceVersion int64
|
||||
expectedVersions []int64
|
||||
expectedListRv int64
|
||||
@@ -555,8 +556,8 @@ func TestBackend_getHistory(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "with ResourceVersionMatch_NotOlderThan",
|
||||
source: resource.ListRequest_HISTORY,
|
||||
versionMatch: resource.ResourceVersionMatchV2_NotOlderThan,
|
||||
source: resourcepb.ListRequest_HISTORY,
|
||||
versionMatch: resourcepb.ResourceVersionMatchV2_NotOlderThan,
|
||||
resourceVersion: rv2,
|
||||
expectedVersions: []int64{rv2, rv3}, // Should be in ASC order due to NotOlderThan
|
||||
expectedListRv: rv3,
|
||||
@@ -564,8 +565,8 @@ func TestBackend_getHistory(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "with ResourceVersionMatch_NotOlderThan and ResourceVersion=0",
|
||||
source: resource.ListRequest_HISTORY,
|
||||
versionMatch: resource.ResourceVersionMatchV2_NotOlderThan,
|
||||
source: resourcepb.ListRequest_HISTORY,
|
||||
versionMatch: resourcepb.ResourceVersionMatchV2_NotOlderThan,
|
||||
resourceVersion: 0,
|
||||
expectedVersions: []int64{rv1, rv2, rv3}, // Should be in ASC order due to NotOlderThan
|
||||
expectedListRv: rv3,
|
||||
@@ -574,8 +575,8 @@ func TestBackend_getHistory(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "with ResourceVersionMatch_Exact",
|
||||
source: resource.ListRequest_HISTORY,
|
||||
versionMatch: resource.ResourceVersionMatchV2_Exact,
|
||||
source: resourcepb.ListRequest_HISTORY,
|
||||
versionMatch: resourcepb.ResourceVersionMatchV2_Exact,
|
||||
resourceVersion: rv2,
|
||||
expectedVersions: []int64{rv2},
|
||||
expectedListRv: rv3,
|
||||
@@ -583,7 +584,7 @@ func TestBackend_getHistory(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "with ResourceVersionMatch_Unset (default)",
|
||||
source: resource.ListRequest_HISTORY,
|
||||
source: resourcepb.ListRequest_HISTORY,
|
||||
expectedVersions: []int64{rv3, rv2, rv1}, // Should be in DESC order by default
|
||||
expectedListRv: rv3,
|
||||
expectedRowsCount: 3,
|
||||
@@ -591,14 +592,14 @@ func TestBackend_getHistory(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "error with ResourceVersionMatch_Exact and ResourceVersion <= 0",
|
||||
source: resource.ListRequest_HISTORY,
|
||||
versionMatch: resource.ResourceVersionMatchV2_Exact,
|
||||
source: resourcepb.ListRequest_HISTORY,
|
||||
versionMatch: resourcepb.ResourceVersionMatchV2_Exact,
|
||||
resourceVersion: 0,
|
||||
expectedErr: "expecting an explicit resource version query when using Exact matching",
|
||||
},
|
||||
{
|
||||
name: "with ListRequest_TRASH",
|
||||
source: resource.ListRequest_TRASH,
|
||||
source: resourcepb.ListRequest_TRASH,
|
||||
expectedVersions: []int64{rv3, rv2, rv1}, // Should be in DESC order by default
|
||||
expectedListRv: rv3,
|
||||
expectedRowsCount: 3,
|
||||
@@ -612,8 +613,8 @@ func TestBackend_getHistory(t *testing.T) {
|
||||
b, ctx := setupBackendTest(t)
|
||||
|
||||
// Build request with appropriate matcher
|
||||
req := &resource.ListRequest{
|
||||
Options: &resource.ListOptions{Key: key},
|
||||
req := &resourcepb.ListRequest{
|
||||
Options: &resourcepb.ListOptions{Key: key},
|
||||
ResourceVersion: tc.resourceVersion,
|
||||
VersionMatchV2: tc.versionMatch,
|
||||
Source: tc.source,
|
||||
@@ -700,7 +701,7 @@ func TestBackend_getHistoryPagination(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Common setup
|
||||
key := &resource.ResourceKey{
|
||||
key := &resourcepb.ResourceKey{
|
||||
Namespace: "ns",
|
||||
Group: "gr",
|
||||
Resource: "rs",
|
||||
@@ -749,11 +750,11 @@ func TestBackend_getHistoryPagination(t *testing.T) {
|
||||
|
||||
// Test each page
|
||||
for _, page := range pages {
|
||||
req := &resource.ListRequest{
|
||||
Options: &resource.ListOptions{Key: key},
|
||||
req := &resourcepb.ListRequest{
|
||||
Options: &resourcepb.ListOptions{Key: key},
|
||||
ResourceVersion: initialRV,
|
||||
VersionMatchV2: resource.ResourceVersionMatchV2_NotOlderThan,
|
||||
Source: resource.ListRequest_HISTORY,
|
||||
VersionMatchV2: resourcepb.ResourceVersionMatchV2_NotOlderThan,
|
||||
Source: resourcepb.ListRequest_HISTORY,
|
||||
Limit: 4,
|
||||
}
|
||||
if page.token != nil {
|
||||
@@ -790,11 +791,11 @@ func TestBackend_getHistoryPagination(t *testing.T) {
|
||||
t.Run("pagination with ResourceVersion=0 and NotOlderThan should return entries in ASC order", func(t *testing.T) {
|
||||
b, ctx := setupBackendTest(t)
|
||||
|
||||
req := &resource.ListRequest{
|
||||
Options: &resource.ListOptions{Key: key},
|
||||
req := &resourcepb.ListRequest{
|
||||
Options: &resourcepb.ListOptions{Key: key},
|
||||
ResourceVersion: 0,
|
||||
VersionMatchV2: resource.ResourceVersionMatchV2_NotOlderThan,
|
||||
Source: resource.ListRequest_HISTORY,
|
||||
VersionMatchV2: resourcepb.ResourceVersionMatchV2_NotOlderThan,
|
||||
Source: resourcepb.ListRequest_HISTORY,
|
||||
Limit: 4,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package sql
|
||||
|
||||
import (
|
||||
context "context"
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/db"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/dbutil"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate"
|
||||
@@ -25,12 +26,12 @@ func (b *backend) SupportsSignedURLs() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *backend) PutResourceBlob(ctx context.Context, req *resource.PutBlobRequest) (*resource.PutBlobResponse, error) {
|
||||
func (b *backend) PutResourceBlob(ctx context.Context, req *resourcepb.PutBlobRequest) (*resourcepb.PutBlobResponse, error) {
|
||||
ctx, span := b.tracer.Start(ctx, tracePrefix+"PutResourceBlob")
|
||||
defer span.End()
|
||||
|
||||
if req.Method == resource.PutBlobRequest_HTTP {
|
||||
return &resource.PutBlobResponse{
|
||||
if req.Method == resourcepb.PutBlobRequest_HTTP {
|
||||
return &resourcepb.PutBlobResponse{
|
||||
Error: resource.NewBadRequestError("signed url upload not supported"),
|
||||
}, nil
|
||||
}
|
||||
@@ -49,7 +50,7 @@ func (b *backend) PutResourceBlob(ctx context.Context, req *resource.PutBlobRequ
|
||||
info.SetContentType(req.ContentType)
|
||||
|
||||
if info.Size < 1 {
|
||||
return &resource.PutBlobResponse{
|
||||
return &resourcepb.PutBlobResponse{
|
||||
Error: resource.NewBadRequestError("empty content"),
|
||||
}, nil
|
||||
}
|
||||
@@ -68,11 +69,11 @@ func (b *backend) PutResourceBlob(ctx context.Context, req *resource.PutBlobRequ
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return &resource.PutBlobResponse{
|
||||
return &resourcepb.PutBlobResponse{
|
||||
Error: resource.AsErrorResult(err),
|
||||
}, nil
|
||||
}
|
||||
return &resource.PutBlobResponse{
|
||||
return &resourcepb.PutBlobResponse{
|
||||
Uid: info.UID,
|
||||
Size: info.Size,
|
||||
MimeType: info.MimeType,
|
||||
@@ -81,17 +82,17 @@ func (b *backend) PutResourceBlob(ctx context.Context, req *resource.PutBlobRequ
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *backend) GetResourceBlob(ctx context.Context, key *resource.ResourceKey, info *utils.BlobInfo, mustProxy bool) (*resource.GetBlobResponse, error) {
|
||||
func (b *backend) GetResourceBlob(ctx context.Context, key *resourcepb.ResourceKey, info *utils.BlobInfo, mustProxy bool) (*resourcepb.GetBlobResponse, error) {
|
||||
ctx, span := b.tracer.Start(ctx, tracePrefix+"GetResourceBlob")
|
||||
defer span.End()
|
||||
|
||||
if info == nil {
|
||||
return &resource.GetBlobResponse{
|
||||
return &resourcepb.GetBlobResponse{
|
||||
Error: resource.NewBadRequestError("missing blob info"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
rsp := &resource.GetBlobResponse{}
|
||||
rsp := &resourcepb.GetBlobResponse{}
|
||||
err := b.db.WithTx(ctx, ReadCommitted, func(ctx context.Context, tx db.Tx) error {
|
||||
rows, err := dbutil.QueryRows(ctx, tx, sqlResourceBlobQuery, sqlResourceBlobQueryRequest{
|
||||
SQLTemplate: sqltemplate.New(b.dialect),
|
||||
@@ -109,7 +110,7 @@ func (b *backend) GetResourceBlob(ctx context.Context, key *resource.ResourceKey
|
||||
}
|
||||
return err
|
||||
}
|
||||
rsp.Error = &resource.ErrorResult{
|
||||
rsp.Error = &resourcepb.ErrorResult{
|
||||
Code: http.StatusNotFound,
|
||||
}
|
||||
return err
|
||||
|
||||
@@ -14,9 +14,11 @@ import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/logging"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/parquet"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/db"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/dbutil"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate"
|
||||
@@ -62,14 +64,14 @@ type bulkLock struct {
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func (x *bulkLock) Start(keys []*resource.ResourceKey) error {
|
||||
func (x *bulkLock) Start(keys []*resourcepb.ResourceKey) error {
|
||||
x.mu.Lock()
|
||||
defer x.mu.Unlock()
|
||||
|
||||
// First verify that it is not already running
|
||||
ids := make([]string, len(keys))
|
||||
for i, k := range keys {
|
||||
id := k.NSGR()
|
||||
id := resource.NSGR(k)
|
||||
if x.running[id] {
|
||||
return &apierrors.StatusError{ErrStatus: metav1.Status{
|
||||
Code: http.StatusPreconditionFailed,
|
||||
@@ -86,11 +88,11 @@ func (x *bulkLock) Start(keys []*resource.ResourceKey) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *bulkLock) Finish(keys []*resource.ResourceKey) {
|
||||
func (x *bulkLock) Finish(keys []*resourcepb.ResourceKey) {
|
||||
x.mu.Lock()
|
||||
defer x.mu.Unlock()
|
||||
for _, k := range keys {
|
||||
delete(x.running, k.NSGR())
|
||||
delete(x.running, resource.NSGR(k))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,10 +102,10 @@ func (x *bulkLock) Active() bool {
|
||||
return len(x.running) > 0
|
||||
}
|
||||
|
||||
func (b *backend) ProcessBulk(ctx context.Context, setting resource.BulkSettings, iter resource.BulkRequestIterator) *resource.BulkResponse {
|
||||
func (b *backend) ProcessBulk(ctx context.Context, setting resource.BulkSettings, iter resource.BulkRequestIterator) *resourcepb.BulkResponse {
|
||||
err := b.bulkLock.Start(setting.Collection)
|
||||
if err != nil {
|
||||
return &resource.BulkResponse{
|
||||
return &resourcepb.BulkResponse{
|
||||
Error: resource.AsErrorResult(err),
|
||||
}
|
||||
}
|
||||
@@ -113,14 +115,14 @@ func (b *backend) ProcessBulk(ctx context.Context, setting resource.BulkSettings
|
||||
if b.dialect.DialectName() == "sqlite" {
|
||||
file, err := os.CreateTemp("", "grafana-bulk-export-*.parquet")
|
||||
if err != nil {
|
||||
return &resource.BulkResponse{
|
||||
return &resourcepb.BulkResponse{
|
||||
Error: resource.AsErrorResult(err),
|
||||
}
|
||||
}
|
||||
|
||||
writer, err := parquet.NewParquetWriter(file)
|
||||
if err != nil {
|
||||
return &resource.BulkResponse{
|
||||
return &resourcepb.BulkResponse{
|
||||
Error: resource.AsErrorResult(err),
|
||||
}
|
||||
}
|
||||
@@ -136,7 +138,7 @@ func (b *backend) ProcessBulk(ctx context.Context, setting resource.BulkSettings
|
||||
// Replace the iterator with one from parquet
|
||||
iter, err = parquet.NewParquetReader(file.Name(), 50)
|
||||
if err != nil {
|
||||
return &resource.BulkResponse{
|
||||
return &resourcepb.BulkResponse{
|
||||
Error: resource.AsErrorResult(err),
|
||||
}
|
||||
}
|
||||
@@ -146,8 +148,8 @@ func (b *backend) ProcessBulk(ctx context.Context, setting resource.BulkSettings
|
||||
}
|
||||
|
||||
// internal bulk process
|
||||
func (b *backend) processBulk(ctx context.Context, setting resource.BulkSettings, iter resource.BulkRequestIterator) *resource.BulkResponse {
|
||||
rsp := &resource.BulkResponse{}
|
||||
func (b *backend) processBulk(ctx context.Context, setting resource.BulkSettings, iter resource.BulkRequestIterator) *resourcepb.BulkResponse {
|
||||
rsp := &resourcepb.BulkResponse{}
|
||||
err := b.db.WithTx(ctx, ReadCommitted, func(ctx context.Context, tx db.Tx) error {
|
||||
rollbackWithError := func(err error) error {
|
||||
txerr := tx.Rollback()
|
||||
@@ -168,7 +170,7 @@ func (b *backend) processBulk(ctx context.Context, setting resource.BulkSettings
|
||||
// Calculate the RV based on incoming request timestamps
|
||||
rv := newBulkRV()
|
||||
|
||||
summaries := make(map[string]*resource.BulkResponse_Summary, len(setting.Collection)*4)
|
||||
summaries := make(map[string]*resourcepb.BulkResponse_Summary, len(setting.Collection)*4)
|
||||
|
||||
// First clear everything in the transaction
|
||||
if setting.RebuildCollection {
|
||||
@@ -177,7 +179,7 @@ func (b *backend) processBulk(ctx context.Context, setting resource.BulkSettings
|
||||
if err != nil {
|
||||
return rollbackWithError(err)
|
||||
}
|
||||
summaries[key.NSGR()] = summary
|
||||
summaries[resource.NSGR(key)] = summary
|
||||
rsp.Summary = append(rsp.Summary, summary)
|
||||
}
|
||||
}
|
||||
@@ -195,8 +197,8 @@ func (b *backend) processBulk(ctx context.Context, setting resource.BulkSettings
|
||||
}
|
||||
rsp.Processed++
|
||||
|
||||
if req.Action == resource.BulkRequest_UNKNOWN {
|
||||
rsp.Rejected = append(rsp.Rejected, &resource.BulkResponse_Rejected{
|
||||
if req.Action == resourcepb.BulkRequest_UNKNOWN {
|
||||
rsp.Rejected = append(rsp.Rejected, &resourcepb.BulkResponse_Rejected{
|
||||
Key: req.Key,
|
||||
Action: req.Action,
|
||||
Error: "unknown action",
|
||||
@@ -206,7 +208,7 @@ func (b *backend) processBulk(ctx context.Context, setting resource.BulkSettings
|
||||
|
||||
err := obj.UnmarshalJSON(req.Value)
|
||||
if err != nil {
|
||||
rsp.Rejected = append(rsp.Rejected, &resource.BulkResponse_Rejected{
|
||||
rsp.Rejected = append(rsp.Rejected, &resourcepb.BulkResponse_Rejected{
|
||||
Key: req.Key,
|
||||
Action: req.Action,
|
||||
Error: "unable to unmarshal json",
|
||||
@@ -219,7 +221,7 @@ func (b *backend) processBulk(ctx context.Context, setting resource.BulkSettings
|
||||
SQLTemplate: sqltemplate.New(b.dialect),
|
||||
WriteEvent: resource.WriteEvent{
|
||||
Key: req.Key,
|
||||
Type: resource.WatchEvent_Type(req.Action),
|
||||
Type: resourcepb.WatchEvent_Type(req.Action),
|
||||
Value: req.Value,
|
||||
PreviousRV: -1, // Used for WATCH, but we want to skip watch events
|
||||
},
|
||||
@@ -268,8 +270,8 @@ type bulkWroker struct {
|
||||
}
|
||||
|
||||
// This will remove everything from the `resource` and `resource_history` table for a given namespace/group/resource
|
||||
func (w *bulkWroker) deleteCollection(key *resource.ResourceKey) (*resource.BulkResponse_Summary, error) {
|
||||
summary := &resource.BulkResponse_Summary{
|
||||
func (w *bulkWroker) deleteCollection(key *resourcepb.ResourceKey) (*resourcepb.BulkResponse_Summary, error) {
|
||||
summary := &resourcepb.BulkResponse_Summary{
|
||||
Namespace: key.Namespace,
|
||||
Group: key.Group,
|
||||
Resource: key.Resource,
|
||||
@@ -306,8 +308,8 @@ func (w *bulkWroker) deleteCollection(key *resource.ResourceKey) (*resource.Bulk
|
||||
}
|
||||
|
||||
// Copy the latest value from history into the active resource table
|
||||
func (w *bulkWroker) syncCollection(key *resource.ResourceKey, summary *resource.BulkResponse_Summary) error {
|
||||
w.logger.Info("synchronize collection", "key", key.NSGR())
|
||||
func (w *bulkWroker) syncCollection(key *resourcepb.ResourceKey, summary *resourcepb.BulkResponse_Summary) error {
|
||||
w.logger.Info("synchronize collection", "key", resource.NSGR(key))
|
||||
_, err := dbutil.Exec(w.ctx, w.tx, sqlResourceInsertFromHistory, &sqlResourceInsertFromHistoryRequest{
|
||||
SQLTemplate: sqltemplate.New(w.dialect),
|
||||
Key: key,
|
||||
@@ -316,7 +318,7 @@ func (w *bulkWroker) syncCollection(key *resource.ResourceKey, summary *resource
|
||||
return err
|
||||
}
|
||||
|
||||
w.logger.Info("get stats (still in transaction)", "key", key.NSGR())
|
||||
w.logger.Info("get stats (still in transaction)", "key", resource.NSGR(key))
|
||||
rows, err := dbutil.QueryRows(w.ctx, w.tx, sqlResourceStats, &sqlStatsRequest{
|
||||
SQLTemplate: sqltemplate.New(w.dialect),
|
||||
Namespace: key.Namespace,
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/grafana/grafana-app-sdk/logging"
|
||||
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate"
|
||||
)
|
||||
|
||||
@@ -197,13 +198,13 @@ func (p *pollingNotifier) poll(ctx context.Context, grp string, res string, sinc
|
||||
}
|
||||
stream <- &resource.WrittenEvent{
|
||||
Value: rec.Value,
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: rec.Key.Namespace,
|
||||
Group: rec.Key.Group,
|
||||
Resource: rec.Key.Resource,
|
||||
Name: rec.Key.Name,
|
||||
},
|
||||
Type: resource.WatchEvent_Type(rec.Action),
|
||||
Type: resourcepb.WatchEvent_Type(rec.Action),
|
||||
PreviousRV: *prevRV,
|
||||
Folder: rec.Folder,
|
||||
ResourceVersion: rec.ResourceVersion,
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.opentelemetry.io/otel/trace/noop"
|
||||
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate"
|
||||
)
|
||||
|
||||
@@ -209,7 +209,7 @@ func TestPollingNotifier(t *testing.T) {
|
||||
defer close(done)
|
||||
|
||||
testEvent := &historyPollResponse{
|
||||
Key: resource.ResourceKey{
|
||||
Key: resourcepb.ResourceKey{
|
||||
Namespace: "test-ns",
|
||||
Group: "test-group",
|
||||
Resource: "test-resource",
|
||||
|
||||
@@ -6,7 +6,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/logging"
|
||||
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@@ -21,8 +24,8 @@ func TestChannelNotifier(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
testEvent := &resource.WrittenEvent{
|
||||
Type: resource.WatchEvent_ADDED,
|
||||
Key: &resource.ResourceKey{
|
||||
Type: resourcepb.WatchEvent_ADDED,
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Group: "test",
|
||||
Resource: "test",
|
||||
Name: "test1",
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate"
|
||||
)
|
||||
|
||||
@@ -88,7 +89,7 @@ func (r sqlResourceRequest) Validate() error {
|
||||
|
||||
type sqlResourceInsertFromHistoryRequest struct {
|
||||
sqltemplate.SQLTemplate
|
||||
Key *resource.ResourceKey
|
||||
Key *resourcepb.ResourceKey
|
||||
}
|
||||
|
||||
func (r sqlResourceInsertFromHistoryRequest) Validate() error {
|
||||
@@ -115,7 +116,7 @@ func (r sqlStatsRequest) Validate() error {
|
||||
}
|
||||
|
||||
type historyPollResponse struct {
|
||||
Key resource.ResourceKey
|
||||
Key resourcepb.ResourceKey
|
||||
GUID string
|
||||
ResourceVersion int64
|
||||
PreviousRV *int64
|
||||
@@ -148,7 +149,7 @@ func (r *sqlResourceHistoryPollRequest) Results() (*historyPollResponse, error)
|
||||
prevRV = new(int64)
|
||||
}
|
||||
return &historyPollResponse{
|
||||
Key: resource.ResourceKey{
|
||||
Key: resourcepb.ResourceKey{
|
||||
Namespace: r.Response.Key.Namespace,
|
||||
Group: r.Response.Key.Group,
|
||||
Resource: r.Response.Key.Resource,
|
||||
@@ -165,13 +166,13 @@ func (r *sqlResourceHistoryPollRequest) Results() (*historyPollResponse, error)
|
||||
// sqlResourceReadRequest can be used to retrieve a row fromthe "resource" tables.
|
||||
func NewReadResponse() *resource.BackendReadResponse {
|
||||
return &resource.BackendReadResponse{
|
||||
Key: &resource.ResourceKey{},
|
||||
Key: &resourcepb.ResourceKey{},
|
||||
}
|
||||
}
|
||||
|
||||
type sqlResourceReadRequest struct {
|
||||
sqltemplate.SQLTemplate
|
||||
Request *resource.ReadRequest
|
||||
Request *resourcepb.ReadRequest
|
||||
Response *resource.BackendReadResponse
|
||||
}
|
||||
|
||||
@@ -186,7 +187,7 @@ func (r *sqlResourceReadRequest) Results() (*resource.BackendReadResponse, error
|
||||
// List
|
||||
type sqlResourceListRequest struct {
|
||||
sqltemplate.SQLTemplate
|
||||
Request *resource.ListRequest
|
||||
Request *resourcepb.ListRequest
|
||||
}
|
||||
|
||||
func (r sqlResourceListRequest) Validate() error {
|
||||
@@ -194,7 +195,7 @@ func (r sqlResourceListRequest) Validate() error {
|
||||
}
|
||||
|
||||
type historyReadRequest struct {
|
||||
Key *resource.ResourceKey
|
||||
Key *resourcepb.ResourceKey
|
||||
ResourceVersion int64
|
||||
}
|
||||
|
||||
@@ -213,8 +214,8 @@ func (r sqlResourceHistoryReadRequest) Results() (*resource.BackendReadResponse,
|
||||
}
|
||||
|
||||
type historyReadLatestRVRequest struct {
|
||||
Key *resource.ResourceKey
|
||||
EventType resource.WatchEvent_Type
|
||||
Key *resourcepb.ResourceKey
|
||||
EventType resourcepb.WatchEvent_Type
|
||||
}
|
||||
|
||||
type sqlResourceHistoryReadLatestRVRequest struct {
|
||||
@@ -242,25 +243,25 @@ func (r *resourceHistoryReadLatestRVResponse) Results() (*resourceHistoryReadLat
|
||||
type historyListRequest struct {
|
||||
ResourceVersion, Limit, Offset int64
|
||||
Folder string
|
||||
Options *resource.ListOptions
|
||||
Options *resourcepb.ListOptions
|
||||
}
|
||||
type sqlResourceHistoryListRequest struct {
|
||||
sqltemplate.SQLTemplate
|
||||
Request *historyListRequest
|
||||
Response *resource.ResourceWrapper
|
||||
Response *resourcepb.ResourceWrapper
|
||||
}
|
||||
|
||||
func (r sqlResourceHistoryListRequest) Validate() error {
|
||||
return nil // TODO
|
||||
}
|
||||
|
||||
func (r sqlResourceHistoryListRequest) Results() (*resource.ResourceWrapper, error) {
|
||||
func (r sqlResourceHistoryListRequest) Results() (*resourcepb.ResourceWrapper, error) {
|
||||
// sqlResourceHistoryListRequest is a set-returning query. As such, it
|
||||
// should not return its *Response, since that will be overwritten in the
|
||||
// next call to `Scan`, so it needs to return a copy of it. Note, though,
|
||||
// that it is safe to return the same `Response.Value` since `Scan`
|
||||
// allocates a new slice of bytes each time.
|
||||
return &resource.ResourceWrapper{
|
||||
return &resourcepb.ResourceWrapper{
|
||||
ResourceVersion: r.Response.ResourceVersion,
|
||||
Value: r.Response.Value,
|
||||
}, nil
|
||||
@@ -292,7 +293,7 @@ func (r *sqlResourceHistoryDeleteRequest) Validate() error {
|
||||
|
||||
type sqlGetHistoryRequest struct {
|
||||
sqltemplate.SQLTemplate
|
||||
Key *resource.ResourceKey
|
||||
Key *resourcepb.ResourceKey
|
||||
Trash bool // only deleted items
|
||||
StartRV int64 // from NextPageToken
|
||||
MinRV int64 // minimum resource version for NotOlderThan
|
||||
@@ -307,7 +308,7 @@ func (r sqlGetHistoryRequest) Validate() error {
|
||||
// prune resource history
|
||||
type sqlPruneHistoryRequest struct {
|
||||
sqltemplate.SQLTemplate
|
||||
Key *resource.ResourceKey
|
||||
Key *resourcepb.ResourceKey
|
||||
PartitionByGeneration bool // include generation in the partition
|
||||
HistoryLimit int64
|
||||
}
|
||||
@@ -335,7 +336,7 @@ type sqlResourceBlobInsertRequest struct {
|
||||
sqltemplate.SQLTemplate
|
||||
Now time.Time
|
||||
Info *utils.BlobInfo
|
||||
Key *resource.ResourceKey
|
||||
Key *resourcepb.ResourceKey
|
||||
Value []byte
|
||||
ContentType string
|
||||
}
|
||||
@@ -349,7 +350,7 @@ func (r sqlResourceBlobInsertRequest) Validate() error {
|
||||
|
||||
type sqlResourceBlobQueryRequest struct {
|
||||
sqltemplate.SQLTemplate
|
||||
Key *resource.ResourceKey
|
||||
Key *resourcepb.ResourceKey
|
||||
UID string
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate/mocks"
|
||||
)
|
||||
|
||||
@@ -21,7 +22,7 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Data: &sqlResourceRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
WriteEvent: resource.WriteEvent{
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "nn",
|
||||
Group: "gg",
|
||||
Resource: "rr",
|
||||
@@ -37,13 +38,13 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Data: &sqlResourceRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
WriteEvent: resource.WriteEvent{
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "nn",
|
||||
Group: "gg",
|
||||
Resource: "rr",
|
||||
Name: "name",
|
||||
},
|
||||
Type: resource.WatchEvent_ADDED,
|
||||
Type: resourcepb.WatchEvent_ADDED,
|
||||
PreviousRV: 123,
|
||||
},
|
||||
Folder: "fldr",
|
||||
@@ -56,7 +57,7 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Data: &sqlResourceRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
WriteEvent: resource.WriteEvent{
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "nn",
|
||||
Group: "gg",
|
||||
Resource: "rr",
|
||||
@@ -72,8 +73,8 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Name: "without_resource_version",
|
||||
Data: &sqlResourceReadRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Request: &resource.ReadRequest{
|
||||
Key: &resource.ResourceKey{
|
||||
Request: &resourcepb.ReadRequest{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "nn",
|
||||
Group: "gg",
|
||||
Resource: "rr",
|
||||
@@ -90,10 +91,10 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Name: "filter_on_namespace",
|
||||
Data: &sqlResourceListRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Request: &resource.ListRequest{
|
||||
Request: &resourcepb.ListRequest{
|
||||
Limit: 10,
|
||||
Options: &resource.ListOptions{
|
||||
Key: &resource.ResourceKey{
|
||||
Options: &resourcepb.ListOptions{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "ns",
|
||||
},
|
||||
},
|
||||
@@ -109,13 +110,13 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Request: &historyListRequest{
|
||||
Limit: 10,
|
||||
Options: &resource.ListOptions{
|
||||
Key: &resource.ResourceKey{
|
||||
Options: &resourcepb.ListOptions{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "ns",
|
||||
},
|
||||
},
|
||||
},
|
||||
Response: new(resource.ResourceWrapper),
|
||||
Response: new(resourcepb.ResourceWrapper),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -152,7 +153,7 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Request: &historyReadRequest{
|
||||
ResourceVersion: 123,
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "ns",
|
||||
Group: "gp",
|
||||
Resource: "rs",
|
||||
@@ -170,7 +171,7 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Data: &sqlResourceHistoryReadLatestRVRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Request: &historyReadLatestRVRequest{
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "ns",
|
||||
Group: "gp",
|
||||
Resource: "rs",
|
||||
@@ -185,13 +186,13 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Data: &sqlResourceHistoryReadLatestRVRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Request: &historyReadLatestRVRequest{
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "ns",
|
||||
Group: "gp",
|
||||
Resource: "rs",
|
||||
Name: "nm",
|
||||
},
|
||||
EventType: resource.WatchEvent_DELETED,
|
||||
EventType: resourcepb.WatchEvent_DELETED,
|
||||
},
|
||||
Response: new(resourceHistoryReadLatestRVResponse),
|
||||
},
|
||||
@@ -218,7 +219,7 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Generation: 789,
|
||||
WriteEvent: resource.WriteEvent{
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "nn",
|
||||
Group: "gg",
|
||||
Resource: "rr",
|
||||
@@ -236,7 +237,7 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Name: "read object history",
|
||||
Data: &sqlGetHistoryRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "nn",
|
||||
Group: "gg",
|
||||
Resource: "rr",
|
||||
@@ -248,7 +249,7 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Name: "read trash",
|
||||
Data: &sqlGetHistoryRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "nn",
|
||||
Group: "gg",
|
||||
Resource: "rr",
|
||||
@@ -260,7 +261,7 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Name: "read trash second page",
|
||||
Data: &sqlGetHistoryRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "nn",
|
||||
Group: "gg",
|
||||
Resource: "rr",
|
||||
@@ -276,7 +277,7 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Name: "max-versions",
|
||||
Data: &sqlPruneHistoryRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "default",
|
||||
Group: "provisioning.grafana.app",
|
||||
Resource: "repositories",
|
||||
@@ -289,7 +290,7 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Name: "collapse-generations",
|
||||
Data: &sqlPruneHistoryRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "default",
|
||||
Group: "provisioning.grafana.app",
|
||||
Resource: "repositories",
|
||||
@@ -386,7 +387,7 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Name: "basic",
|
||||
Data: &sqlResourceBlobInsertRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "x",
|
||||
Group: "g",
|
||||
Resource: "r",
|
||||
@@ -409,7 +410,7 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Name: "basic",
|
||||
Data: &sqlResourceBlobQueryRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "x",
|
||||
Group: "g",
|
||||
Resource: "r",
|
||||
@@ -422,7 +423,7 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Name: "resource", // NOTE: this returns multiple values
|
||||
Data: &sqlResourceBlobQueryRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "x",
|
||||
Group: "g",
|
||||
Resource: "r",
|
||||
@@ -454,7 +455,7 @@ func TestUnifiedStorageQueries(t *testing.T) {
|
||||
Name: "update",
|
||||
Data: &sqlResourceInsertFromHistoryRequest{
|
||||
SQLTemplate: mocks.NewTestingSQLTemplate(),
|
||||
Key: &resource.ResourceKey{
|
||||
Key: &resourcepb.ResourceKey{
|
||||
Namespace: "default",
|
||||
Group: "dashboard.grafana.app",
|
||||
Resource: "dashboards",
|
||||
|
||||
@@ -8,15 +8,16 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/db"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/dbutil"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"go.opentelemetry.io/otel/trace/noop"
|
||||
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/db"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/dbutil"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -82,9 +83,9 @@ type writeOpResult struct {
|
||||
|
||||
// writeOp is a write operation that is executed with an incremented resource version
|
||||
type writeOp struct {
|
||||
key *resource.ResourceKey // The key of the resource
|
||||
fn WriteEventFunc // The function to execute to write the event
|
||||
done chan writeOpResult // A channel informing the operation is done
|
||||
key *resourcepb.ResourceKey // The key of the resource
|
||||
fn WriteEventFunc // The function to execute to write the event
|
||||
done chan writeOpResult // A channel informing the operation is done
|
||||
}
|
||||
|
||||
// WriteEventFunc is a function that writes a resource to the database
|
||||
@@ -128,7 +129,7 @@ func NewResourceVersionManager(opts ResourceManagerOptions) (*resourceVersionMan
|
||||
}
|
||||
|
||||
// ExecWithRV executes the given function with an incremented resource version
|
||||
func (m *resourceVersionManager) ExecWithRV(ctx context.Context, key *resource.ResourceKey, fn WriteEventFunc) (rv int64, err error) {
|
||||
func (m *resourceVersionManager) ExecWithRV(ctx context.Context, key *resourcepb.ResourceKey, fn WriteEventFunc) (rv int64, err error) {
|
||||
rvmInflightWrites.WithLabelValues(key.Group, key.Resource).Inc()
|
||||
defer rvmInflightWrites.WithLabelValues(key.Group, key.Resource).Dec()
|
||||
|
||||
|
||||
@@ -3,13 +3,14 @@ package sql
|
||||
import (
|
||||
"testing"
|
||||
|
||||
sqlmock "github.com/DATA-DOG/go-sqlmock"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/db"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/test"
|
||||
"github.com/grafana/grafana/pkg/util/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func expectSuccessfulResourceVersionLock(t *testing.T, dbp test.TestDBProvider, rv int64, timestamp int64) {
|
||||
@@ -44,7 +45,7 @@ func TestResourceVersionManager(t *testing.T) {
|
||||
require.NotNil(t, manager)
|
||||
|
||||
t.Run("should handle single operation", func(t *testing.T) {
|
||||
key := &resource.ResourceKey{
|
||||
key := &resourcepb.ResourceKey{
|
||||
Group: "test-group",
|
||||
Resource: "test-resource",
|
||||
}
|
||||
|
||||
@@ -6,17 +6,18 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/db"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/dbutil"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate"
|
||||
)
|
||||
|
||||
// Support using SQL as fallback when the indexer is not running
|
||||
var _ resource.ResourceIndexServer = &backend{}
|
||||
var _ resourcepb.ResourceIndexServer = &backend{}
|
||||
|
||||
// GetStats implements resource.ResourceIndexServer.
|
||||
// This will use the SQL index to count values
|
||||
func (b *backend) GetStats(ctx context.Context, req *resource.ResourceStatsRequest) (*resource.ResourceStatsResponse, error) {
|
||||
func (b *backend) GetStats(ctx context.Context, req *resourcepb.ResourceStatsRequest) (*resourcepb.ResourceStatsResponse, error) {
|
||||
ctx, span := b.tracer.Start(ctx, tracePrefix+".GetStats")
|
||||
defer span.End()
|
||||
|
||||
@@ -26,7 +27,7 @@ func (b *backend) GetStats(ctx context.Context, req *resource.ResourceStatsReque
|
||||
Folder: req.Folder,
|
||||
}
|
||||
|
||||
rsp := &resource.ResourceStatsResponse{}
|
||||
rsp := &resourcepb.ResourceStatsResponse{}
|
||||
err := b.db.WithTx(ctx, ReadCommittedRO, func(ctx context.Context, tx db.Tx) error {
|
||||
rows, err := dbutil.QueryRows(ctx, tx, sqlResourceStats, sreq)
|
||||
if err != nil {
|
||||
@@ -39,7 +40,7 @@ func (b *backend) GetStats(ctx context.Context, req *resource.ResourceStatsReque
|
||||
return err
|
||||
}
|
||||
|
||||
rsp.Stats = append(rsp.Stats, &resource.ResourceStatsResponse_Stats{
|
||||
rsp.Stats = append(rsp.Stats, &resourcepb.ResourceStatsResponse_Stats{
|
||||
Group: row.Group,
|
||||
Resource: row.Resource,
|
||||
Count: row.Count,
|
||||
@@ -53,18 +54,18 @@ func (b *backend) GetStats(ctx context.Context, req *resource.ResourceStatsReque
|
||||
return rsp, nil
|
||||
}
|
||||
|
||||
func (b *backend) RepositoryList(ctx context.Context, req *resource.ListManagedObjectsRequest) (*resource.ListManagedObjectsResponse, error) {
|
||||
func (b *backend) RepositoryList(ctx context.Context, req *resourcepb.ListManagedObjectsRequest) (*resourcepb.ListManagedObjectsResponse, error) {
|
||||
return nil, fmt.Errorf("SQL backend does not implement RepositoryList")
|
||||
}
|
||||
|
||||
func (b *backend) RepositoryStats(context.Context, *resource.CountManagedObjectsRequest) (*resource.CountManagedObjectsResponse, error) {
|
||||
func (b *backend) RepositoryStats(context.Context, *resourcepb.CountManagedObjectsRequest) (*resourcepb.CountManagedObjectsResponse, error) {
|
||||
return nil, fmt.Errorf("SQL backend does not implement RepositoryStats")
|
||||
}
|
||||
|
||||
// Search implements resource.ResourceIndexServer.
|
||||
func (b *backend) Search(context.Context, *resource.ResourceSearchRequest) (*resource.ResourceSearchResponse, error) {
|
||||
return &resource.ResourceSearchResponse{
|
||||
Error: &resource.ErrorResult{
|
||||
func (b *backend) Search(context.Context, *resourcepb.ResourceSearchRequest) (*resourcepb.ResourceSearchResponse, error) {
|
||||
return &resourcepb.ResourceSearchResponse{
|
||||
Error: &resourcepb.ErrorResult{
|
||||
Code: http.StatusNotImplemented,
|
||||
Message: "SQL backend does not implement Search",
|
||||
},
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource/grpc"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/search"
|
||||
)
|
||||
|
||||
@@ -136,12 +137,12 @@ func (s *service) start(ctx context.Context) error {
|
||||
}
|
||||
|
||||
srv := s.handler.GetServer()
|
||||
resource.RegisterResourceStoreServer(srv, server)
|
||||
resource.RegisterBulkStoreServer(srv, server)
|
||||
resource.RegisterResourceIndexServer(srv, server)
|
||||
resource.RegisterManagedObjectIndexServer(srv, server)
|
||||
resource.RegisterBlobStoreServer(srv, server)
|
||||
resource.RegisterDiagnosticsServer(srv, server)
|
||||
resourcepb.RegisterResourceStoreServer(srv, server)
|
||||
resourcepb.RegisterBulkStoreServer(srv, server)
|
||||
resourcepb.RegisterResourceIndexServer(srv, server)
|
||||
resourcepb.RegisterManagedObjectIndexServer(srv, server)
|
||||
resourcepb.RegisterBlobStoreServer(srv, server)
|
||||
resourcepb.RegisterDiagnosticsServer(srv, server)
|
||||
grpc_health_v1.RegisterHealthServer(srv, healthService)
|
||||
|
||||
// register reflection service
|
||||
|
||||
@@ -13,12 +13,14 @@ import (
|
||||
"github.com/grafana/authlib/authn"
|
||||
"github.com/grafana/authlib/types"
|
||||
"github.com/grafana/dskit/services"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/storage/unified"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/search"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/db/dbimpl"
|
||||
@@ -157,7 +159,7 @@ func TestClientServer(t *testing.T) {
|
||||
|
||||
svc, err := sql.ProvideUnifiedStorageGrpcService(cfg, features, dbstore, nil, prometheus.NewPedanticRegistry(), nil, nil, nil, nil)
|
||||
require.NoError(t, err)
|
||||
var client resource.ResourceStoreClient
|
||||
var client resourcepb.ResourceStoreClient
|
||||
|
||||
clientCtx := types.WithAuthInfo(context.Background(), authn.NewAccessTokenAuthInfo(authn.Claims[authn.AccessTokenClaims]{
|
||||
Claims: jwt.Claims{
|
||||
@@ -193,7 +195,7 @@ func TestClientServer(t *testing.T) {
|
||||
},
|
||||
"spec": {}
|
||||
}`)
|
||||
resp, err := client.Create(clientCtx, &resource.CreateRequest{
|
||||
resp, err := client.Create(clientCtx, &resourcepb.CreateRequest{
|
||||
Key: resourceKey("item1"),
|
||||
Value: raw,
|
||||
})
|
||||
@@ -203,7 +205,7 @@ func TestClientServer(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Read the resource", func(t *testing.T) {
|
||||
resp, err := client.Read(clientCtx, &resource.ReadRequest{
|
||||
resp, err := client.Read(clientCtx, &resourcepb.ReadRequest{
|
||||
Key: resourceKey("item1"),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
@@ -217,8 +219,8 @@ func TestClientServer(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func resourceKey(name string) *resource.ResourceKey {
|
||||
return &resource.ResourceKey{
|
||||
func resourceKey(name string) *resourcepb.ResourceKey {
|
||||
return &resourcepb.ResourceKey{
|
||||
Namespace: "namespace",
|
||||
Group: "group",
|
||||
Resource: "resource",
|
||||
|
||||
Reference in New Issue
Block a user