From 6281a2f7770adf3836039a690762d43ebd3dbfd7 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Tue, 17 Dec 2024 10:05:46 -0800 Subject: [PATCH] Rename database APIs (#8143) # Description This change renames the database APIs to have clearer names. ## Type of change - This pull request is a minor refactor, code cleanup, test improvement, or other maintenance task and doesn't change the functionality of Radius (issue link optional). ## Contributor checklist Please verify that the PR meets the following requirements, where applicable: - [ ] An overview of proposed schema changes is included in a linked GitHub issue. - [ ] A design document PR is created in the [design-notes repository](https://github.com/radius-project/design-notes/), if new APIs are being introduced. - [ ] If applicable, design document has been reviewed and approved by Radius maintainers/approvers. - [ ] A PR for the [samples repository](https://github.com/radius-project/samples) is created, if existing samples are affected by the changes in this PR. - [ ] A PR for the [documentation repository](https://github.com/radius-project/docs) is created, if the changes in this PR affect the documentation or any user facing updates are made. - [ ] A PR for the [recipes repository](https://github.com/radius-project/recipes) is created, if existing recipes are affected by the changes in this PR. Signed-off-by: Ryan Nowak --- build/generate.mk | 4 +- cmd/applications-rp/cmd/root.go | 8 +- cmd/ucpd/cmd/root.go | 8 +- .../asyncoperation/controller/controller.go | 22 +- .../statusmanager/statusmanager.go | 32 +-- .../statusmanager/statusmanager_test.go | 38 ++-- pkg/armrpc/asyncoperation/worker/registry.go | 4 +- .../asyncoperation/worker/registry_test.go | 6 +- pkg/armrpc/asyncoperation/worker/service.go | 14 +- pkg/armrpc/asyncoperation/worker/worker.go | 20 +- .../worker/worker_runoperation_test.go | 46 ++-- .../asyncoperation/worker/worker_test.go | 16 +- pkg/armrpc/builder/builder_test.go | 20 +- pkg/armrpc/builder/namespace_test.go | 4 +- pkg/armrpc/frontend/controller/controller.go | 28 +-- .../frontend/controller/controller_test.go | 32 +-- pkg/armrpc/frontend/controller/operation.go | 24 +- .../defaultasyncdelete_test.go | 12 +- .../defaultoperation/defaultasyncput_test.go | 38 ++-- .../defaultoperation/defaultsyncdelete.go | 6 +- .../defaultsyncdelete_test.go | 14 +- .../defaultoperation/defaultsyncput_test.go | 32 +-- .../defaultoperation/getoperationresult.go | 6 +- .../getoperationresult_test.go | 24 +- .../defaultoperation/getoperationstatus.go | 4 +- .../getoperationstatus_test.go | 22 +- .../defaultoperation/getresource_test.go | 22 +- .../defaultoperation/listresources.go | 8 +- .../defaultoperation/listresources_test.go | 30 +-- .../defaultoperation/resource_test.go | 6 +- pkg/armrpc/frontend/server/handler.go | 7 - pkg/armrpc/frontend/server/handler_test.go | 16 +- pkg/armrpc/frontend/server/service.go | 18 +- pkg/armrpc/hostoptions/hostoptions.go | 2 +- pkg/armrpc/hostoptions/providerconfig.go | 12 +- pkg/armrpc/rpctest/controllers.go | 10 +- .../controller/createorupdateresource.go | 16 +- .../controller/createorupdateresource_test.go | 30 +-- .../backend/controller/deleteresource.go | 8 +- .../backend/controller/deleteresource_test.go | 12 +- .../backend/deployment/deploymentprocessor.go | 18 +- .../deployment/deploymentprocessor_test.go | 212 ++++++++--------- .../controller/applications/getgraph_test.go | 10 +- .../controller/applications/updatefilter.go | 6 +- .../applications/updatefilter_test.go | 40 ++-- .../environments/createorupdateenvironment.go | 2 +- .../createorupdateenvironment_test.go | 112 ++++----- .../environments/getrecipemetadata_test.go | 52 ++--- .../extenders/listsecretsextender_test.go | 30 +-- .../controller/secretstores/kubernetes.go | 6 +- .../secretstores/kubernetes_test.go | 54 ++--- .../secretstores/listsecrets_test.go | 36 +-- pkg/corerp/frontend/controller/util/query.go | 10 +- pkg/corerp/setup/setup_test.go | 10 +- pkg/daprrp/setup/setup_test.go | 10 +- .../listsecretsmongodatabase_test.go | 48 ++-- .../rediscaches/listsecretsrediscache.go | 4 +- .../rediscaches/listsecretsrediscache_test.go | 48 ++-- .../listsecretssqldatabase_test.go | 48 ++-- pkg/datastoresrp/setup/setup_test.go | 10 +- pkg/dynamicrp/backend/service.go | 8 +- pkg/dynamicrp/config.go | 12 +- pkg/dynamicrp/frontend/service.go | 2 +- pkg/dynamicrp/options.go | 18 +- pkg/dynamicrp/server/server.go | 8 +- .../listsecretsrabbitmq_test.go | 28 +-- pkg/messagingrp/setup/setup_test.go | 10 +- .../controller/createorupdateresource.go | 18 +- .../controller/createorupdateresource_test.go | 20 +- .../backend/controller/deleteresource.go | 8 +- .../backend/controller/deleteresource_test.go | 12 +- pkg/recipes/controllerconfig/config.go | 4 +- pkg/recipes/driver/terraform.go | 2 +- pkg/recipes/terraform/config/providers/aws.go | 2 +- .../terraform/config/providers/azure.go | 2 +- .../terraform/config/providers/types.go | 2 +- pkg/recipes/terraform/execute.go | 2 +- pkg/rp/kube/resources.go | 6 +- pkg/rp/kube/resources_test.go | 8 +- pkg/rp/util/datastore.go | 10 +- pkg/server/apiservice.go | 12 +- pkg/server/asyncworker.go | 8 +- .../resourcegroups/trackedresourceprocess.go | 12 +- .../trackedresourceprocess_test.go | 62 ++--- .../resourceproviders/apiversion_delete.go | 4 +- .../resourceproviders/apiversion_put.go | 2 +- .../resourceproviders/location_delete.go | 4 +- .../resourceproviders/location_put.go | 2 +- .../resourceprovider_delete.go | 8 +- .../resourceproviders/resourceprovider_put.go | 2 +- .../resourceproviders/resourcetype_delete.go | 4 +- .../resourceproviders/resourcetype_put.go | 4 +- .../controller/resourceproviders/util.go | 20 +- .../controller/resourceproviders/util_test.go | 14 +- pkg/ucp/backend/service.go | 4 +- pkg/ucp/credentials/aws.go | 6 +- pkg/ucp/credentials/azure.go | 6 +- .../api/ucp.dev/v1alpha1/groupversion_info.go | 0 .../ucp.dev/v1alpha1/queuemessage_types.go | 0 .../api/ucp.dev/v1alpha1/resource_types.go | 0 .../ucp.dev/v1alpha1/zz_generated.deepcopy.go | 0 .../apiserverstore/apiserverclient.go | 92 ++++---- .../apiserverstore/apiserverclient_test.go | 40 ++-- pkg/ucp/{store => database}/client.go | 14 +- pkg/ucp/{store => database}/client_test.go | 2 +- .../databaseutil}/doc.go | 4 +- .../storeutil => database/databaseutil}/id.go | 6 +- .../databaseutil}/id_test.go | 36 +-- pkg/ucp/{store => database}/err.go | 2 +- .../etcdstore/etcdclient.go | 84 +++---- .../etcdstore/etcdclient_test.go | 0 pkg/ucp/{store => database}/filter.go | 2 +- pkg/ucp/{store => database}/filter_test.go | 2 +- .../{store => database}/inmemory/client.go | 92 ++++---- .../inmemory/client_test.go | 0 pkg/ucp/{store => database}/inmemory/doc.go | 0 pkg/ucp/{store => database}/map.go | 2 +- pkg/ucp/{store => database}/map_test.go | 2 +- pkg/ucp/database/mock_client.go | 214 ++++++++++++++++++ pkg/ucp/{store => database}/object.go | 8 +- pkg/ucp/{store => database}/options.go | 44 ++-- .../postgres/postgresclient.go | 112 ++++----- .../postgres/postgresclient_test.go | 0 pkg/ucp/{store => database}/resources.go | 2 +- .../factory.go | 30 +-- .../options.go | 21 +- .../storageprovider.go | 62 ++--- .../storageprovider_test.go | 44 ++-- .../types.go | 14 +- pkg/ucp/frontend/api/routes.go | 10 +- pkg/ucp/frontend/api/routes_test.go | 18 +- pkg/ucp/frontend/api/server.go | 48 ++-- pkg/ucp/frontend/aws/routes.go | 10 +- pkg/ucp/frontend/aws/routes_test.go | 16 +- pkg/ucp/frontend/azure/routes.go | 10 +- pkg/ucp/frontend/azure/routes_test.go | 16 +- .../controller/awsproxy/awsproxytest.go | 10 +- .../createorupdateawsresource_test.go | 8 +- .../createorupdateawsresourcewithpost_test.go | 12 +- .../awsproxy/deleteawsresource_test.go | 4 +- .../deleteawsresourcewithpost_test.go | 6 +- .../awsproxy/getawsoperationresults_test.go | 4 +- .../awsproxy/getawsoperationstatuses_test.go | 6 +- .../awsproxy/getawsresource_test.go | 8 +- .../awsproxy/getawsresourcewithpost_test.go | 10 +- .../awsproxy/listawsresources_test.go | 8 +- .../aws/createorupdateawscredential_test.go | 50 ++-- .../credentials/aws/deleteawscredential.go | 6 +- .../aws/deleteawscredential_test.go | 54 ++--- .../createorupdateazurecredential_test.go | 50 ++-- .../azure/deleteazurecredential.go | 6 +- .../azure/deleteazurecredential_test.go | 54 ++--- .../frontend/controller/planes/listplanes.go | 12 +- .../controller/planes/listplanes_test.go | 22 +- .../controller/planes/listplanesbytype.go | 10 +- .../planes/listplanesbytype_test.go | 14 +- pkg/ucp/frontend/controller/radius/proxy.go | 14 +- .../frontend/controller/radius/proxy_test.go | 84 +++---- .../resourcegroups/listresourcegroups.go | 10 +- .../resourcegroups/listresourcegroups_test.go | 16 +- .../resourcegroups/listresources.go | 12 +- .../resourcegroups/listresources_test.go | 40 ++-- .../controller/resourcegroups/util.go | 30 +-- .../controller/resourcegroups/util_test.go | 118 +++++----- .../getresourceprovidersummary.go | 12 +- .../listresourceprovidersummaries.go | 12 +- pkg/ucp/frontend/modules/types.go | 10 +- pkg/ucp/frontend/radius/routes.go | 12 +- pkg/ucp/frontend/radius/routes_test.go | 16 +- pkg/ucp/hostoptions/providerconfig.go | 12 +- pkg/ucp/integrationtests/aws/awstest.go | 6 +- pkg/ucp/integrationtests/radius/proxy_test.go | 2 +- pkg/ucp/integrationtests/testrp/async.go | 16 +- pkg/ucp/integrationtests/testrp/sync.go | 14 +- .../integrationtests/testserver/testserver.go | 82 +++---- pkg/ucp/queue/apiserver/client.go | 2 +- pkg/ucp/queue/apiserver/client_test.go | 2 +- .../{provider => queueprovider}/factory.go | 4 +- .../{provider => queueprovider}/options.go | 6 +- .../{provider => queueprovider}/provider.go | 6 +- .../provider_test.go | 4 +- .../{provider => queueprovider}/types.go | 2 +- .../{provider => secretprovider}/factory.go | 8 +- .../{provider => secretprovider}/options.go | 6 +- .../{provider => secretprovider}/provider.go | 2 +- .../provider_test.go | 2 +- .../{provider => secretprovider}/types.go | 2 +- pkg/ucp/server/server.go | 48 ++-- pkg/ucp/store/mock_storageClient.go | 214 ------------------ pkg/ucp/trackedresource/update.go | 26 +-- pkg/ucp/trackedresource/update_test.go | 86 +++---- test/ucp/kubeenv/testenv.go | 2 +- test/ucp/storetest/shared.go | 108 ++++----- 193 files changed, 2123 insertions(+), 2141 deletions(-) rename pkg/ucp/{store => database}/apiserverstore/api/ucp.dev/v1alpha1/groupversion_info.go (100%) rename pkg/ucp/{store => database}/apiserverstore/api/ucp.dev/v1alpha1/queuemessage_types.go (100%) rename pkg/ucp/{store => database}/apiserverstore/api/ucp.dev/v1alpha1/resource_types.go (100%) rename pkg/ucp/{store => database}/apiserverstore/api/ucp.dev/v1alpha1/zz_generated.deepcopy.go (100%) rename pkg/ucp/{store => database}/apiserverstore/apiserverclient.go (83%) rename pkg/ucp/{store => database}/apiserverstore/apiserverclient_test.go (97%) rename pkg/ucp/{store => database}/client.go (91%) rename pkg/ucp/{store => database}/client_test.go (99%) rename pkg/ucp/{store/storeutil => database/databaseutil}/doc.go (84%) rename pkg/ucp/{store/storeutil => database/databaseutil}/id.go (97%) rename pkg/ucp/{store/storeutil => database/databaseutil}/id_test.go (95%) rename pkg/ucp/{store => database}/err.go (99%) rename pkg/ucp/{store => database}/etcdstore/etcdclient.go (76%) rename pkg/ucp/{store => database}/etcdstore/etcdclient_test.go (100%) rename pkg/ucp/{store => database}/filter.go (99%) rename pkg/ucp/{store => database}/filter_test.go (99%) rename pkg/ucp/{store => database}/inmemory/client.go (63%) rename pkg/ucp/{store => database}/inmemory/client_test.go (100%) rename pkg/ucp/{store => database}/inmemory/doc.go (100%) rename pkg/ucp/{store => database}/map.go (98%) rename pkg/ucp/{store => database}/map_test.go (99%) create mode 100644 pkg/ucp/database/mock_client.go rename pkg/ucp/{store => database}/object.go (87%) rename pkg/ucp/{store => database}/options.go (77%) rename pkg/ucp/{store => database}/postgres/postgresclient.go (70%) rename pkg/ucp/{store => database}/postgres/postgresclient_test.go (100%) rename pkg/ucp/{store => database}/resources.go (97%) rename pkg/ucp/{dataprovider => databaseprovider}/factory.go (74%) rename pkg/ucp/{dataprovider => databaseprovider}/options.go (81%) rename pkg/ucp/{dataprovider => databaseprovider}/storageprovider.go (51%) rename pkg/ucp/{dataprovider => databaseprovider}/storageprovider_test.go (63%) rename pkg/ucp/{dataprovider => databaseprovider}/types.go (71%) rename pkg/ucp/queue/{provider => queueprovider}/factory.go (95%) rename pkg/ucp/queue/{provider => queueprovider}/options.go (92%) rename pkg/ucp/queue/{provider => queueprovider}/provider.go (92%) rename pkg/ucp/queue/{provider => queueprovider}/provider_test.go (94%) rename pkg/ucp/queue/{provider => queueprovider}/types.go (97%) rename pkg/ucp/secret/{provider => secretprovider}/factory.go (91%) rename pkg/ucp/secret/{provider => secretprovider}/options.go (86%) rename pkg/ucp/secret/{provider => secretprovider}/provider.go (98%) rename pkg/ucp/secret/{provider => secretprovider}/provider_test.go (97%) rename pkg/ucp/secret/{provider => secretprovider}/types.go (97%) delete mode 100644 pkg/ucp/store/mock_storageClient.go diff --git a/build/generate.mk b/build/generate.mk index e0a969f997..13c4fc0a53 100644 --- a/build/generate.mk +++ b/build/generate.mk @@ -62,8 +62,8 @@ generate-controller-gen-installed: .PHONY: generate-ucp-crd generate-ucp-crd: generate-controller-gen-installed ## Generates the CRDs for UCP APIServer store. @echo "$(ARROW) Generating CRDs for ucp.dev..." - controller-gen object:headerFile=./boilerplate.go.txt paths=./pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1/... - controller-gen crd paths=./pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1/... output:crd:dir=./deploy/Chart/crds/ucpd + controller-gen object:headerFile=./boilerplate.go.txt paths=./pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1/... + controller-gen crd paths=./pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1/... output:crd:dir=./deploy/Chart/crds/ucpd .PHONY: generate-controller generate-controller: generate-controller-gen-installed ## Generates the CRDs for the Radius controller. diff --git a/cmd/applications-rp/cmd/root.go b/cmd/applications-rp/cmd/root.go index 88650ee966..75241ea968 100644 --- a/cmd/applications-rp/cmd/root.go +++ b/cmd/applications-rp/cmd/root.go @@ -34,7 +34,7 @@ import ( "github.com/radius-project/radius/pkg/trace" "github.com/radius-project/radius/pkg/ucp/data" - "github.com/radius-project/radius/pkg/ucp/dataprovider" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" "github.com/radius-project/radius/pkg/ucp/hosting" "github.com/radius-project/radius/pkg/ucp/ucplog" @@ -79,14 +79,14 @@ var rootCmd = &cobra.Command{ // Must set the logger before using controller-runtime. runtimelog.SetLogger(logger) - if options.Config.StorageProvider.Provider == dataprovider.TypeETCD && - options.Config.StorageProvider.ETCD.InMemory { + if options.Config.DatabaseProvider.Provider == databaseprovider.TypeETCD && + options.Config.DatabaseProvider.ETCD.InMemory { // For in-memory etcd we need to register another service to manage its lifecycle. // // The client will be initialized asynchronously. logger.Info("Enabled in-memory etcd") client := hosting.NewAsyncValue[etcdclient.Client]() - options.Config.StorageProvider.ETCD.Client = client + options.Config.DatabaseProvider.ETCD.Client = client options.Config.SecretProvider.ETCD.Client = client hostingSvc = append(hostingSvc, data.NewEmbeddedETCDService(data.EmbeddedETCDServiceOptions{ClientConfigSink: client})) diff --git a/cmd/ucpd/cmd/root.go b/cmd/ucpd/cmd/root.go index c6672ea03f..c11ec85178 100644 --- a/cmd/ucpd/cmd/root.go +++ b/cmd/ucpd/cmd/root.go @@ -26,7 +26,7 @@ import ( runtimelog "sigs.k8s.io/controller-runtime/pkg/log" "github.com/radius-project/radius/pkg/armrpc/hostoptions" - "github.com/radius-project/radius/pkg/ucp/dataprovider" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" "github.com/radius-project/radius/pkg/ucp/hosting" "github.com/radius-project/radius/pkg/ucp/server" "github.com/radius-project/radius/pkg/ucp/ucplog" @@ -52,13 +52,13 @@ var rootCmd = &cobra.Command{ // Must set the logger before using controller-runtime. runtimelog.SetLogger(logger) - if options.StorageProviderOptions.Provider == dataprovider.TypeETCD && - options.StorageProviderOptions.ETCD.InMemory { + if options.DatabaseProviderOptions.Provider == databaseprovider.TypeETCD && + options.DatabaseProviderOptions.ETCD.InMemory { // For in-memory etcd we need to register another service to manage its lifecycle. // // The client will be initialized asynchronously. clientconfigSource := hosting.NewAsyncValue[etcdclient.Client]() - options.StorageProviderOptions.ETCD.Client = clientconfigSource + options.DatabaseProviderOptions.ETCD.Client = clientconfigSource options.SecretProviderOptions.ETCD.Client = clientconfigSource } diff --git a/pkg/armrpc/asyncoperation/controller/controller.go b/pkg/armrpc/asyncoperation/controller/controller.go index 1a1ce535b9..a0a89b0720 100644 --- a/pkg/armrpc/asyncoperation/controller/controller.go +++ b/pkg/armrpc/asyncoperation/controller/controller.go @@ -21,15 +21,15 @@ import ( "errors" "github.com/radius-project/radius/pkg/corerp/backend/deployment" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" runtimeclient "sigs.k8s.io/controller-runtime/pkg/client" ) // Options represents controller options. type Options struct { - // StorageClient is the data storage client. - StorageClient store.StorageClient + // DatabaseClient is the database client. + DatabaseClient database.Client // KubeClient is the Kubernetes controller runtime client. KubeClient runtimeclient.Client @@ -44,11 +44,11 @@ type Options struct { // Validate validates that required fields are set on the options. func (o Options) Validate() error { var err error - if o.StorageClient == nil { - err = errors.Join(err, errors.New("StorageClient is required")) + if o.DatabaseClient == nil { + err = errors.Join(err, errors.New(".DatabaseClient is required")) } if o.ResourceType == "" { - err = errors.Join(err, errors.New("ResourceType is required")) + err = errors.Join(err, errors.New(".ResourceType is required")) } // KubeClient and GetDeploymentProcessor are not used by the majority of the code, so they @@ -62,8 +62,8 @@ type Controller interface { // Run runs async request operation. Run(ctx context.Context, request *Request) (Result, error) - // StorageClient gets the storage client for resource type. - StorageClient() store.StorageClient + // DatabaseClient gets the database client for resource type. + DatabaseClient() database.Client } // BaseController is the base struct of async operation controller. @@ -76,9 +76,9 @@ func NewBaseAsyncController(options Options) BaseController { return BaseController{options} } -// StorageClient gets storage client for this controller. -func (b *BaseController) StorageClient() store.StorageClient { - return b.options.StorageClient +// DatabaseClient gets database client for this controller. +func (b *BaseController) DatabaseClient() database.Client { + return b.options.DatabaseClient } // KubeClient gets Kubernetes client for this controller. diff --git a/pkg/armrpc/asyncoperation/statusmanager/statusmanager.go b/pkg/armrpc/asyncoperation/statusmanager/statusmanager.go index e87c5f71c1..bc9b2acc1a 100644 --- a/pkg/armrpc/asyncoperation/statusmanager/statusmanager.go +++ b/pkg/armrpc/asyncoperation/statusmanager/statusmanager.go @@ -27,18 +27,18 @@ import ( ctrl "github.com/radius-project/radius/pkg/armrpc/asyncoperation/controller" "github.com/radius-project/radius/pkg/metrics" "github.com/radius-project/radius/pkg/trace" + "github.com/radius-project/radius/pkg/ucp/database" queue "github.com/radius-project/radius/pkg/ucp/queue/client" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/google/uuid" ) // statusManager includes the necessary functions to manage asynchronous operations. type statusManager struct { - storageClient store.StorageClient - queue queue.Client - location string + databaseClient database.Client + queue queue.Client + location string } // QueueOperationOptions is the options type provided when queueing an async operation. @@ -64,11 +64,11 @@ type StatusManager interface { } // New creates statusManager instance. -func New(storageClient store.StorageClient, q queue.Client, location string) StatusManager { +func New(databaseClient database.Client, queueClient queue.Client, location string) StatusManager { return &statusManager{ - storageClient: storageClient, - queue: q, - location: location, + databaseClient: databaseClient, + queue: queueClient, + location: location, } } @@ -78,7 +78,7 @@ func (aom *statusManager) operationStatusResourceID(id resources.ID, operationID } // QueueAsyncOperation creates and saves a new status resource with the given parameters in datastore, and queues -// a request message. If an error occurs, the status is deleted using the storeClient. +// a request message. If an error occurs, the status is deleted using the databaseClient. func (aom *statusManager) QueueAsyncOperation(ctx context.Context, sCtx *v1.ARMRequestContext, options QueueOperationOptions) error { ctx, span := trace.StartProducerSpan(ctx, "statusmanager.QueueAsyncOperation publish", trace.FrontendTracerName) defer span.End() @@ -106,8 +106,8 @@ func (aom *statusManager) QueueAsyncOperation(ctx context.Context, sCtx *v1.ARMR ClientObjectID: sCtx.ClientObjectID, } - err := aom.storageClient.Save(ctx, &store.Object{ - Metadata: store.Metadata{ID: opID}, + err := aom.databaseClient.Save(ctx, &database.Object{ + Metadata: database.Metadata{ID: opID}, Data: aos, }) @@ -116,7 +116,7 @@ func (aom *statusManager) QueueAsyncOperation(ctx context.Context, sCtx *v1.ARMR } if err = aom.queueRequestMessage(ctx, sCtx, aos, options.OperationTimeout); err != nil { - delErr := aom.storageClient.Delete(ctx, opID) + delErr := aom.databaseClient.Delete(ctx, opID) if delErr != nil { return delErr } @@ -130,7 +130,7 @@ func (aom *statusManager) QueueAsyncOperation(ctx context.Context, sCtx *v1.ARMR // Get gets a status object from the datastore or an error if the retrieval fails. func (aom *statusManager) Get(ctx context.Context, id resources.ID, operationID uuid.UUID) (*Status, error) { - obj, err := aom.storageClient.Get(ctx, aom.operationStatusResourceID(id, operationID)) + obj, err := aom.databaseClient.Get(ctx, aom.operationStatusResourceID(id, operationID)) if err != nil { return nil, err } @@ -147,7 +147,7 @@ func (aom *statusManager) Get(ctx context.Context, id resources.ID, operationID // given parameters, and saves it back to the store. func (aom *statusManager) Update(ctx context.Context, id resources.ID, operationID uuid.UUID, state v1.ProvisioningState, endTime *time.Time, opError *v1.ErrorDetails) error { opID := aom.operationStatusResourceID(id, operationID) - obj, err := aom.storageClient.Get(ctx, opID) + obj, err := aom.databaseClient.Get(ctx, opID) if err != nil { return err } @@ -170,13 +170,13 @@ func (aom *statusManager) Update(ctx context.Context, id resources.ID, operation obj.Data = s - return aom.storageClient.Save(ctx, obj, store.WithETag(obj.ETag)) + return aom.databaseClient.Save(ctx, obj, database.WithETag(obj.ETag)) } // Delete deletes the operation status resource associated with the given ID and // operationID, and returns an error if unsuccessful. func (aom *statusManager) Delete(ctx context.Context, id resources.ID, operationID uuid.UUID) error { - return aom.storageClient.Delete(ctx, aom.operationStatusResourceID(id, operationID)) + return aom.databaseClient.Delete(ctx, aom.operationStatusResourceID(id, operationID)) } // queueRequestMessage function is to put the async operation message to the queue to be worked on. diff --git a/pkg/armrpc/asyncoperation/statusmanager/statusmanager_test.go b/pkg/armrpc/asyncoperation/statusmanager/statusmanager_test.go index c61872cf3d..c1de8a5bd6 100644 --- a/pkg/armrpc/asyncoperation/statusmanager/statusmanager_test.go +++ b/pkg/armrpc/asyncoperation/statusmanager/statusmanager_test.go @@ -26,17 +26,17 @@ import ( "github.com/google/uuid" v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" "github.com/radius-project/radius/pkg/armrpc/rpctest" + "github.com/radius-project/radius/pkg/ucp/database" queue "github.com/radius-project/radius/pkg/ucp/queue/client" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) type asyncOperationsManagerTest struct { - manager StatusManager - storeClient *store.MockStorageClient - queue *queue.MockClient + manager StatusManager + databaseClient *database.MockClient + queueClient *queue.MockClient } const ( @@ -52,10 +52,10 @@ const ( func setup(tb testing.TB) (asyncOperationsManagerTest, *gomock.Controller) { ctrl := gomock.NewController(tb) - sc := store.NewMockStorageClient(ctrl) + sc := database.NewMockClient(ctrl) enq := queue.NewMockClient(ctrl) aom := New(sc, enq, "test-location") - return asyncOperationsManagerTest{manager: aom, storeClient: sc, queue: enq}, ctrl + return asyncOperationsManagerTest{manager: aom, databaseClient: sc, queueClient: enq}, ctrl } var reqCtx = &v1.ARMRequestContext{ @@ -151,16 +151,16 @@ func TestCreateAsyncOperationStatus(t *testing.T) { aomTest, mctrl := setup(t) defer mctrl.Finish() - aomTest.storeClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(tt.SaveErr) + aomTest.databaseClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(tt.SaveErr) // We can't expect an async operation to be queued if it is not saved to the DB. if tt.SaveErr == nil { - aomTest.queue.EXPECT().Enqueue(gomock.Any(), gomock.Any(), gomock.Any()).Return(tt.EnqueueErr) + aomTest.queueClient.EXPECT().Enqueue(gomock.Any(), gomock.Any(), gomock.Any()).Return(tt.EnqueueErr) } // If there is an error when enqueuing the message, the async operation should be deleted. if tt.EnqueueErr != nil { - aomTest.storeClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(tt.DeleteErr) + aomTest.databaseClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(tt.DeleteErr) } options := QueueOperationOptions{ @@ -208,7 +208,7 @@ func TestDeleteAsyncOperationStatus(t *testing.T) { aomTest, mctrl := setup(t) defer mctrl.Finish() - aomTest.storeClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(tt.DeleteErr) + aomTest.databaseClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(tt.DeleteErr) rid, err := resources.ParseResource(azureEnvResourceID) require.NoError(t, err) err = aomTest.manager.Delete(context.TODO(), rid, uuid.New()) @@ -226,13 +226,13 @@ func TestGetAsyncOperationStatus(t *testing.T) { getCases := []struct { Desc string GetErr error - Obj *store.Object + Obj *database.Object }{ { Desc: "get_success", GetErr: nil, - Obj: &store.Object{ - Metadata: store.Metadata{ID: opID.String(), ETag: "etag"}, + Obj: &database.Object{ + Metadata: database.Metadata{ID: opID.String(), ETag: "etag"}, Data: testAos, }, }, @@ -248,7 +248,7 @@ func TestGetAsyncOperationStatus(t *testing.T) { aomTest, mctrl := setup(t) defer mctrl.Finish() - aomTest.storeClient. + aomTest.databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any(), gomock.Any()). Return(tt.Obj, tt.GetErr) @@ -275,14 +275,14 @@ func TestUpdateAsyncOperationStatus(t *testing.T) { updateCases := []struct { Desc string GetErr error - Obj *store.Object + Obj *database.Object SaveErr error }{ { Desc: "update_success", GetErr: nil, - Obj: &store.Object{ - Metadata: store.Metadata{ID: opID.String(), ETag: "etag"}, + Obj: &database.Object{ + Metadata: database.Metadata{ID: opID.String(), ETag: "etag"}, Data: testAos, }, SaveErr: nil, @@ -294,13 +294,13 @@ func TestUpdateAsyncOperationStatus(t *testing.T) { aomTest, mctrl := setup(t) defer mctrl.Finish() - aomTest.storeClient. + aomTest.databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any(), gomock.Any()). Return(tt.Obj, tt.GetErr) if tt.GetErr == nil { - aomTest.storeClient. + aomTest.databaseClient. EXPECT(). Save(gomock.Any(), gomock.Any(), gomock.Any()). Return(tt.SaveErr) diff --git a/pkg/armrpc/asyncoperation/worker/registry.go b/pkg/armrpc/asyncoperation/worker/registry.go index eb21ec1042..ddef93093d 100644 --- a/pkg/armrpc/asyncoperation/worker/registry.go +++ b/pkg/armrpc/asyncoperation/worker/registry.go @@ -76,8 +76,8 @@ func (h *ControllerRegistry) RegisterDefault(factoryFn ControllerFactoryFunc, op defer h.ctrlMapMu.Unlock() // Note: we can't call opts.Validate() here because we don't know the resource type yet. - if opts.StorageClient == nil { - return fmt.Errorf("invalid controller options: .StorageClient is required") + if opts.DatabaseClient == nil { + return fmt.Errorf("invalid controller options: .DatabaseClient is required") } h.defaultFactory = factoryFn diff --git a/pkg/armrpc/asyncoperation/worker/registry_test.go b/pkg/armrpc/asyncoperation/worker/registry_test.go index c3078e6dcb..3df0c2ac5e 100644 --- a/pkg/armrpc/asyncoperation/worker/registry_test.go +++ b/pkg/armrpc/asyncoperation/worker/registry_test.go @@ -23,7 +23,7 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" ctrl "github.com/radius-project/radius/pkg/armrpc/asyncoperation/controller" "github.com/radius-project/radius/pkg/corerp/backend/deployment" - "github.com/radius-project/radius/pkg/ucp/store/inmemory" + "github.com/radius-project/radius/pkg/ucp/database/inmemory" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) @@ -38,7 +38,7 @@ func TestRegister_Get(t *testing.T) { opPut := v1.OperationType{Type: "Applications.Core/environments", Method: v1.OperationPut} ctrlOpts := ctrl.Options{ - StorageClient: inmemory.NewClient(), + DatabaseClient: inmemory.NewClient(), GetDeploymentProcessor: func() deployment.DeploymentProcessor { return nil }, } @@ -79,7 +79,7 @@ func TestRegister_Get_WithDefault(t *testing.T) { opGet := v1.OperationType{Type: "Applications.Core/environments", Method: v1.OperationGet} ctrlOpts := ctrl.Options{ - StorageClient: inmemory.NewClient(), + DatabaseClient: inmemory.NewClient(), GetDeploymentProcessor: func() deployment.DeploymentProcessor { return nil }, } diff --git a/pkg/armrpc/asyncoperation/worker/service.go b/pkg/armrpc/asyncoperation/worker/service.go index a70b98778e..7a2440266c 100644 --- a/pkg/armrpc/asyncoperation/worker/service.go +++ b/pkg/armrpc/asyncoperation/worker/service.go @@ -21,9 +21,9 @@ import ( manager "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" "github.com/radius-project/radius/pkg/armrpc/hostoptions" - "github.com/radius-project/radius/pkg/ucp/dataprovider" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" queue "github.com/radius-project/radius/pkg/ucp/queue/client" - qprovider "github.com/radius-project/radius/pkg/ucp/queue/provider" + "github.com/radius-project/radius/pkg/ucp/queue/queueprovider" "github.com/radius-project/radius/pkg/ucp/ucplog" ) @@ -33,8 +33,8 @@ type Service struct { ProviderName string // Options is the server hosting options. Options hostoptions.HostOptions - // StorageProvider is the provider of storage client. - StorageProvider *dataprovider.DataStorageProvider + // DatabaseProvider is the provider of the database client. + DatabaseProvider *databaseprovider.DatabaseProvider // OperationStatusManager is the manager of the operation status. OperationStatusManager manager.StatusManager // Controllers is the registry of the async operation controllers. @@ -46,11 +46,11 @@ type Service struct { // Init initializes worker service - it initializes the StorageProvider, RequestQueue, OperationStatusManager, Controllers, KubeClient and // returns an error if any of these operations fail. func (s *Service) Init(ctx context.Context) error { - s.StorageProvider = dataprovider.DataStorageProviderFromOptions(s.Options.Config.StorageProvider) - qp := qprovider.New(s.Options.Config.QueueProvider) + s.DatabaseProvider = databaseprovider.FromOptions(s.Options.Config.DatabaseProvider) + qp := queueprovider.New(s.Options.Config.QueueProvider) var err error - storageClient, err := s.StorageProvider.GetClient(ctx) + storageClient, err := s.DatabaseProvider.GetClient(ctx) if err != nil { return err } diff --git a/pkg/armrpc/asyncoperation/worker/worker.go b/pkg/armrpc/asyncoperation/worker/worker.go index 0539576109..d10d862a8a 100644 --- a/pkg/armrpc/asyncoperation/worker/worker.go +++ b/pkg/armrpc/asyncoperation/worker/worker.go @@ -31,9 +31,9 @@ import ( "github.com/radius-project/radius/pkg/logging" "github.com/radius-project/radius/pkg/metrics" "github.com/radius-project/radius/pkg/trace" + "github.com/radius-project/radius/pkg/ucp/database" queue "github.com/radius-project/radius/pkg/ucp/queue/client" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/ucplog" "github.com/google/uuid" @@ -192,7 +192,7 @@ func (w *AsyncRequestProcessWorker) Start(ctx context.Context) error { Code: v1.CodeInternal, Message: errMsg, }) - w.completeOperation(reqCtx, msgreq, failed, asyncCtrl.StorageClient()) + w.completeOperation(reqCtx, msgreq, failed, asyncCtrl.DatabaseClient()) return } @@ -210,7 +210,7 @@ func (w *AsyncRequestProcessWorker) Start(ctx context.Context) error { return } - if err = w.updateResourceAndOperationStatus(reqCtx, asyncCtrl.StorageClient(), op, v1.ProvisioningStateUpdating, nil); err != nil { + if err = w.updateResourceAndOperationStatus(reqCtx, asyncCtrl.DatabaseClient(), op, v1.ProvisioningStateUpdating, nil); err != nil { return } @@ -274,7 +274,7 @@ func (w *AsyncRequestProcessWorker) runOperation(ctx context.Context, message *q // 2. When parent context is canceled or done, we need to requeue the operation to reprocess the request. // Such cases should not call w.completeOperation. if !errors.Is(asyncReqCtx.Err(), context.Canceled) { - w.completeOperation(ctx, message, result, asyncCtrl.StorageClient()) + w.completeOperation(ctx, message, result, asyncCtrl.DatabaseClient()) } trace.SetAsyncResultStatus(result, span) }() @@ -300,7 +300,7 @@ func (w *AsyncRequestProcessWorker) runOperation(ctx context.Context, message *q errMessage := fmt.Sprintf("Operation (%s) has timed out because it was processing longer than %d s.", asyncReq.OperationType, int(asyncReq.Timeout().Seconds())) result := ctrl.NewCanceledResult(errMessage) result.Error.Target = asyncReq.ResourceID - w.completeOperation(ctx, message, result, asyncCtrl.StorageClient()) + w.completeOperation(ctx, message, result, asyncCtrl.DatabaseClient()) return case <-ctx.Done(): @@ -326,7 +326,7 @@ func extractError(err error) v1.ErrorDetails { } } -func (w *AsyncRequestProcessWorker) completeOperation(ctx context.Context, message *queue.Message, result ctrl.Result, sc store.StorageClient) { +func (w *AsyncRequestProcessWorker) completeOperation(ctx context.Context, message *queue.Message, result ctrl.Result, sc database.Client) { logger := ucplog.FromContextOrDiscard(ctx) req := &ctrl.Request{} if err := json.Unmarshal(message.Data, req); err != nil { @@ -350,7 +350,7 @@ func (w *AsyncRequestProcessWorker) completeOperation(ctx context.Context, messa metrics.DefaultAsyncOperationMetrics.RecordAsyncOperation(ctx, req, &result) } -func (w *AsyncRequestProcessWorker) updateResourceAndOperationStatus(ctx context.Context, sc store.StorageClient, req *ctrl.Request, state v1.ProvisioningState, opErr *v1.ErrorDetails) error { +func (w *AsyncRequestProcessWorker) updateResourceAndOperationStatus(ctx context.Context, sc database.Client, req *ctrl.Request, state v1.ProvisioningState, opErr *v1.ErrorDetails) error { logger := ucplog.FromContextOrDiscard(ctx) rID, err := resources.ParseResource(req.ResourceID) @@ -360,7 +360,7 @@ func (w *AsyncRequestProcessWorker) updateResourceAndOperationStatus(ctx context } err = updateResourceState(ctx, sc, rID.String(), state) - if errors.Is(err, &store.ErrNotFound{}) { + if errors.Is(err, &database.ErrNotFound{}) { logger.Info("failed to update the provisioningState in resource because it no longer exists.") } else if err != nil { logger.Error(err, "failed to update the provisioningState in resource.") @@ -408,7 +408,7 @@ func (w *AsyncRequestProcessWorker) getMessageExtendDuration(visibleAt time.Time return d } -func updateResourceState(ctx context.Context, sc store.StorageClient, id string, state v1.ProvisioningState) error { +func updateResourceState(ctx context.Context, sc database.Client, id string, state v1.ProvisioningState) error { obj, err := sc.Get(ctx, id) if err != nil { return err @@ -425,7 +425,7 @@ func updateResourceState(ctx context.Context, sc store.StorageClient, id string, objmap["provisioningState"] = string(state) - err = sc.Save(ctx, obj, store.WithETag(obj.ETag)) + err = sc.Save(ctx, obj, database.WithETag(obj.ETag)) if err != nil { return err } diff --git a/pkg/armrpc/asyncoperation/worker/worker_runoperation_test.go b/pkg/armrpc/asyncoperation/worker/worker_runoperation_test.go index 9ff93b40b1..9359186c6d 100644 --- a/pkg/armrpc/asyncoperation/worker/worker_runoperation_test.go +++ b/pkg/armrpc/asyncoperation/worker/worker_runoperation_test.go @@ -29,11 +29,11 @@ import ( ctrl "github.com/radius-project/radius/pkg/armrpc/asyncoperation/controller" manager "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" "github.com/radius-project/radius/pkg/corerp/backend/deployment" + "github.com/radius-project/radius/pkg/ucp/database" + inmemorystore "github.com/radius-project/radius/pkg/ucp/database/inmemory" queue "github.com/radius-project/radius/pkg/ucp/queue/client" "github.com/radius-project/radius/pkg/ucp/queue/inmemory" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" - inmemorystore "github.com/radius-project/radius/pkg/ucp/store/inmemory" "github.com/stretchr/testify/require" "go.uber.org/atomic" "go.uber.org/mock/gomock" @@ -75,7 +75,7 @@ func (c *testAsyncController) Run(ctx context.Context, request *ctrl.Request) (c type testContext struct { ctx context.Context - mockSC *store.MockStorageClient + mockSC *database.MockClient mockSM *manager.MockStatusManager testQueue *inmemory.Client @@ -83,8 +83,8 @@ type testContext struct { } // newTestResourceObject returns new store.Object to prevent datarace when updateResourceState accesses map[string]any{} concurrently. -func newTestResourceObject() *store.Object { - return &store.Object{ +func newTestResourceObject() *database.Object { + return &database.Object{ Data: map[string]any{ "name": "env0", "provisioningState": "Accepted", @@ -114,10 +114,10 @@ func (c *testContext) cancellable(timeout time.Duration) (context.Context, conte func newTestContext(t *testing.T, lockTime time.Duration) (*testContext, *gomock.Controller) { mctrl := gomock.NewController(t) inmemQ := inmemory.NewInMemQueue(lockTime) - storageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) return &testContext{ ctx: context.Background(), - mockSC: storageClient, + mockSC: databaseClient, mockSM: manager.NewMockStatusManager(mctrl), internalQ: inmemQ, testQueue: inmemory.New(inmemQ), @@ -150,7 +150,7 @@ func TestStart_UnknownOperation(t *testing.T) { worker := New(Options{DequeueIntervalDuration: defaultTestDequeueInterval}, nil, tCtx.testQueue, registry) opts := ctrl.Options{ - StorageClient: tCtx.mockSC, + DatabaseClient: tCtx.mockSC, GetDeploymentProcessor: func() deployment.DeploymentProcessor { return deployment.NewMockDeploymentProcessor(mctrl) }, @@ -202,7 +202,7 @@ func TestStart_MaxDequeueCount(t *testing.T) { // set up mocks tCtx.mockSC.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { return newTestResourceObject(), nil }).AnyTimes() tCtx.mockSC.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) @@ -214,7 +214,7 @@ func TestStart_MaxDequeueCount(t *testing.T) { worker := New(Options{MaxOperationRetryCount: expectedDequeueCount, DequeueIntervalDuration: defaultTestDequeueInterval}, tCtx.mockSM, tCtx.testQueue, registry) opts := ctrl.Options{ - StorageClient: tCtx.mockSC, + DatabaseClient: tCtx.mockSC, } testCtrl := &testAsyncController{ @@ -230,7 +230,7 @@ func TestStart_MaxDequeueCount(t *testing.T) { func(opts ctrl.Options) (ctrl.Controller, error) { return testCtrl, nil }, ctrl.Options{ - StorageClient: tCtx.mockSC, + DatabaseClient: tCtx.mockSC, }) require.NoError(t, err) @@ -262,7 +262,7 @@ func TestStart_MaxConcurrency(t *testing.T) { // set up mocks tCtx.mockSC.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { return newTestResourceObject(), nil }).AnyTimes() tCtx.mockSC.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() @@ -273,7 +273,7 @@ func TestStart_MaxConcurrency(t *testing.T) { worker := New(Options{DequeueIntervalDuration: defaultTestDequeueInterval}, tCtx.mockSM, tCtx.testQueue, registry) opts := ctrl.Options{ - StorageClient: tCtx.mockSC, + DatabaseClient: tCtx.mockSC, GetDeploymentProcessor: func() deployment.DeploymentProcessor { return deployment.NewMockDeploymentProcessor(mctrl) }, @@ -338,7 +338,7 @@ func TestStart_RunOperation(t *testing.T) { // set up mocks tCtx.mockSC.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { return newTestResourceObject(), nil }).AnyTimes() tCtx.mockSC.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() @@ -349,7 +349,7 @@ func TestStart_RunOperation(t *testing.T) { worker := New(Options{}, tCtx.mockSM, tCtx.testQueue, registry) opts := ctrl.Options{ - StorageClient: tCtx.mockSC, + DatabaseClient: tCtx.mockSC, GetDeploymentProcessor: func() deployment.DeploymentProcessor { return deployment.NewMockDeploymentProcessor(mctrl) }, @@ -407,7 +407,7 @@ func TestRunOperation_Successfully(t *testing.T) { // set up mocks tCtx.mockSC.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { return newTestResourceObject(), nil }).AnyTimes() tCtx.mockSC.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() @@ -419,7 +419,7 @@ func TestRunOperation_Successfully(t *testing.T) { worker := New(Options{}, tCtx.mockSM, tCtx.testQueue, nil) opts := ctrl.Options{ - StorageClient: tCtx.mockSC, + DatabaseClient: tCtx.mockSC, GetDeploymentProcessor: func() deployment.DeploymentProcessor { return deployment.NewMockDeploymentProcessor(mctrl) }, @@ -445,7 +445,7 @@ func TestRunOperation_ExtendMessageLock(t *testing.T) { // set up mocks tCtx.mockSC.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { return newTestResourceObject(), nil }).AnyTimes() tCtx.mockSC.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() @@ -458,7 +458,7 @@ func TestRunOperation_ExtendMessageLock(t *testing.T) { worker := New(Options{}, tCtx.mockSM, tCtx.testQueue, nil) opts := ctrl.Options{ - StorageClient: tCtx.mockSC, + DatabaseClient: tCtx.mockSC, GetDeploymentProcessor: func() deployment.DeploymentProcessor { return deployment.NewMockDeploymentProcessor(mctrl) }, @@ -500,7 +500,7 @@ func TestRunOperation_CancelContext(t *testing.T) { // Instead we use the in-memory store. opts := ctrl.Options{ - StorageClient: inmemorystore.NewClient(), + DatabaseClient: inmemorystore.NewClient(), GetDeploymentProcessor: func() deployment.DeploymentProcessor { return nil }, @@ -536,7 +536,7 @@ func TestRunOperation_Timeout(t *testing.T) { // set up mocks tCtx.mockSC.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { return newTestResourceObject(), nil }).AnyTimes() tCtx.mockSC.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() @@ -555,7 +555,7 @@ func TestRunOperation_Timeout(t *testing.T) { worker := New(Options{}, tCtx.mockSM, tCtx.testQueue, nil) opts := ctrl.Options{ - StorageClient: tCtx.mockSC, + DatabaseClient: tCtx.mockSC, GetDeploymentProcessor: func() deployment.DeploymentProcessor { return deployment.NewMockDeploymentProcessor(mctrl) }, @@ -589,7 +589,7 @@ func TestRunOperation_PanicController(t *testing.T) { worker := New(Options{}, nil, tCtx.testQueue, nil) opts := ctrl.Options{ - StorageClient: tCtx.mockSC, + DatabaseClient: tCtx.mockSC, GetDeploymentProcessor: func() deployment.DeploymentProcessor { return nil }, diff --git a/pkg/armrpc/asyncoperation/worker/worker_test.go b/pkg/armrpc/asyncoperation/worker/worker_test.go index f6c8a6f4d6..390e0b7598 100644 --- a/pkg/armrpc/asyncoperation/worker/worker_test.go +++ b/pkg/armrpc/asyncoperation/worker/worker_test.go @@ -23,7 +23,7 @@ import ( "time" v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) @@ -84,30 +84,30 @@ func TestUpdateResourceState(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() - mStorageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) ctx := context.Background() - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, options ...store.GetOptions) (*store.Object, error) { - return &store.Object{ + DoAndReturn(func(ctx context.Context, id string, options ...database.GetOptions) (*database.Object, error) { + return &database.Object{ Data: tt.in, }, nil }) if tt.callSave { - mStorageClient. + databaseClient. EXPECT(). Save(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, obj *store.Object, options ...store.SaveOptions) error { + DoAndReturn(func(ctx context.Context, obj *database.Object, options ...database.SaveOptions) error { k := obj.Data.(map[string]any) require.Equal(t, k["provisioningState"].(string), string(tt.updateState)) return nil }) } - err := updateResourceState(ctx, mStorageClient, "fakeid", tt.updateState) + err := updateResourceState(ctx, databaseClient, "fakeid", tt.updateState) require.ErrorIs(t, err, tt.outErr) }) } diff --git a/pkg/armrpc/builder/builder_test.go b/pkg/armrpc/builder/builder_test.go index 90695a363c..b25ad4b72b 100644 --- a/pkg/armrpc/builder/builder_test.go +++ b/pkg/armrpc/builder/builder_test.go @@ -28,7 +28,7 @@ import ( "github.com/radius-project/radius/pkg/armrpc/asyncoperation/worker" apictrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rpctest" - "github.com/radius-project/radius/pkg/ucp/store/inmemory" + "github.com/radius-project/radius/pkg/ucp/database/inmemory" "github.com/radius-project/radius/test/testcontext" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -173,10 +173,10 @@ func TestApplyAPIHandlers(t *testing.T) { r := chi.NewRouter() options := apictrl.Options{ - Address: "localhost:8080", - PathBase: "/api.ucp.dev", - StorageClient: inmemory.NewClient(), - StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), + Address: "localhost:8080", + PathBase: "/api.ucp.dev", + DatabaseClient: inmemory.NewClient(), + StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), } return r, b.ApplyAPIHandlers(ctx, r, options) @@ -228,10 +228,10 @@ func TestApplyAPIHandlers_AvailableOperations(t *testing.T) { rpctest.AssertRequests(t, handlerTests, "/api.ucp.dev", "/planes/radius/local", func(ctx context.Context) (chi.Router, error) { r := chi.NewRouter() options := apictrl.Options{ - Address: "localhost:8080", - PathBase: "/api.ucp.dev", - StorageClient: inmemory.NewClient(), - StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), + Address: "localhost:8080", + PathBase: "/api.ucp.dev", + DatabaseClient: inmemory.NewClient(), + StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), } return r, builder.ApplyAPIHandlers(ctx, r, options) }) @@ -244,7 +244,7 @@ func TestApplyAsyncHandler(t *testing.T) { ctx := testcontext.New(t) options := backendctrl.Options{ - StorageClient: inmemory.NewClient(), + DatabaseClient: inmemory.NewClient(), } err := builder.ApplyAsyncHandler(ctx, registry, options) diff --git a/pkg/armrpc/builder/namespace_test.go b/pkg/armrpc/builder/namespace_test.go index b247c72810..60e9890416 100644 --- a/pkg/armrpc/builder/namespace_test.go +++ b/pkg/armrpc/builder/namespace_test.go @@ -26,7 +26,7 @@ import ( apictrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rest" "github.com/radius-project/radius/pkg/armrpc/rpctest" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/stretchr/testify/require" ) @@ -45,7 +45,7 @@ func (c *testAsyncController) Run(ctx context.Context, request *asyncctrl.Reques return asyncctrl.Result{}, nil } -func (c *testAsyncController) StorageClient() store.StorageClient { +func (c *testAsyncController) DatabaseClient() database.Client { return nil } diff --git a/pkg/armrpc/frontend/controller/controller.go b/pkg/armrpc/frontend/controller/controller.go index bbda7f3537..8acd02118a 100644 --- a/pkg/armrpc/frontend/controller/controller.go +++ b/pkg/armrpc/frontend/controller/controller.go @@ -26,7 +26,7 @@ import ( sm "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" "github.com/radius-project/radius/pkg/armrpc/hostoptions" "github.com/radius-project/radius/pkg/armrpc/rest" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" runtimeclient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -52,8 +52,8 @@ type Options struct { // Code that needs to construct a URL path should use the base path prefix when constructing the URL path. PathBase string - // StorageClient is the data storage client. - StorageClient store.StorageClient + // DatabaseClient is the database client. + DatabaseClient database.Client // KubeClient is the Kubernetes controller runtime client. KubeClient runtimeclient.Client @@ -71,8 +71,8 @@ func (o Options) Validate() error { if o.Address == "" { err = errors.Join(err, errors.New(".Address is required")) } - if o.StorageClient == nil { - err = errors.Join(err, errors.New(".StorageClient is required")) + if o.DatabaseClient == nil { + err = errors.Join(err, errors.New(".DatabaseClient is required")) } if o.ResourceType == "" { err = errors.Join(err, errors.New(".ResourceType is required")) @@ -136,9 +136,9 @@ func NewBaseController(options Options) BaseController { } } -// StorageClient gets storage client for this controller. -func (b *BaseController) StorageClient() store.StorageClient { - return b.options.StorageClient +// DatabaseClient gets database client for this controller. +func (b *BaseController) DatabaseClient() database.Client { + return b.options.DatabaseClient } // KubeClient gets Kubernetes client for this controller. @@ -160,8 +160,8 @@ func (b *BaseController) StatusManager() sm.StatusManager { // the ETag of the resource and an error if one occurs. func (c *BaseController) GetResource(ctx context.Context, id string, out any) (etag string, err error) { etag = "" - var res *store.Object - if res, err = c.StorageClient().Get(ctx, id); err == nil { + var res *database.Object + if res, err = c.DatabaseClient().Get(ctx, id); err == nil { if err = res.As(out); err == nil { etag = res.ETag return @@ -171,14 +171,14 @@ func (c *BaseController) GetResource(ctx context.Context, id string, out any) (e } // SaveResource saves a resource to the data store with an ETag and returns a store object or an error if the save fails. -func (c *BaseController) SaveResource(ctx context.Context, id string, in any, etag string) (*store.Object, error) { - nr := &store.Object{ - Metadata: store.Metadata{ +func (c *BaseController) SaveResource(ctx context.Context, id string, in any, etag string) (*database.Object, error) { + nr := &database.Object{ + Metadata: database.Metadata{ ID: id, }, Data: in, } - err := c.StorageClient().Save(ctx, nr, store.WithETag(etag)) + err := c.DatabaseClient().Save(ctx, nr, database.WithETag(etag)) if err != nil { return nil, err } diff --git a/pkg/armrpc/frontend/controller/controller_test.go b/pkg/armrpc/frontend/controller/controller_test.go index af31d927d6..5e28bd77c8 100644 --- a/pkg/armrpc/frontend/controller/controller_test.go +++ b/pkg/armrpc/frontend/controller/controller_test.go @@ -21,7 +21,7 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/stretchr/testify/require" ) @@ -112,39 +112,39 @@ func TestOptionsValidate(t *testing.T) { { name: "valid options", options: Options{ - Address: "localhost:8080", - StorageClient: &store.MockStorageClient{}, - ResourceType: "testResource", - StatusManager: &statusmanager.MockStatusManager{}, + Address: "localhost:8080", + DatabaseClient: &database.MockClient{}, + ResourceType: "testResource", + StatusManager: &statusmanager.MockStatusManager{}, }, wantErr: false, }, { name: "missing address", options: Options{ - StorageClient: &store.MockStorageClient{}, - ResourceType: "testResource", - StatusManager: &statusmanager.MockStatusManager{}, + DatabaseClient: &database.MockClient{}, + ResourceType: "testResource", + StatusManager: &statusmanager.MockStatusManager{}, }, wantErr: true, errMsg: ".Address is required", }, { - name: "missing storage client", + name: "missing database client", options: Options{ Address: "localhost:8080", ResourceType: "testResource", StatusManager: &statusmanager.MockStatusManager{}, }, wantErr: true, - errMsg: ".StorageClient is required", + errMsg: ".DatabaseClient is required", }, { name: "missing resource type", options: Options{ - Address: "localhost:8080", - StorageClient: &store.MockStorageClient{}, - StatusManager: &statusmanager.MockStatusManager{}, + Address: "localhost:8080", + DatabaseClient: &database.MockClient{}, + StatusManager: &statusmanager.MockStatusManager{}, }, wantErr: true, errMsg: ".ResourceType is required", @@ -152,9 +152,9 @@ func TestOptionsValidate(t *testing.T) { { name: "missing status manager", options: Options{ - Address: "localhost:8080", - StorageClient: &store.MockStorageClient{}, - ResourceType: "testResource", + Address: "localhost:8080", + DatabaseClient: &database.MockClient{}, + ResourceType: "testResource", }, wantErr: true, errMsg: ".StatusManager is required", diff --git a/pkg/armrpc/frontend/controller/operation.go b/pkg/armrpc/frontend/controller/operation.go index 2d720c1f47..d8ecbf11bb 100644 --- a/pkg/armrpc/frontend/controller/operation.go +++ b/pkg/armrpc/frontend/controller/operation.go @@ -26,8 +26,8 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" sm "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" "github.com/radius-project/radius/pkg/armrpc/rest" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" ) const ( @@ -58,9 +58,9 @@ func (b *Operation[P, T]) Options() *Options { return &b.options } -// StorageClient gets storage client for this controller. -func (b *Operation[P, T]) StorageClient() store.StorageClient { - return b.options.StorageClient +// DatabaseClient gets database client for this controller. +func (b *Operation[P, T]) DatabaseClient() database.Client { + return b.options.DatabaseClient } // ResourceType gets the resource type for this controller. @@ -89,12 +89,12 @@ func (c *Operation[P, T]) GetResourceFromRequest(ctx context.Context, req *http. return dm, nil } -// GetResource is the helper to get the resource via storage client. +// GetResource is the helper to get the resource via database client. func (c *Operation[P, T]) GetResource(ctx context.Context, id resources.ID) (out *T, etag string, err error) { etag = "" out = new(T) - var res *store.Object - if res, err = c.StorageClient().Get(ctx, id.String()); err == nil { + var res *database.Object + if res, err = c.DatabaseClient().Get(ctx, id.String()); err == nil { if err = res.As(out); err == nil { etag = res.ETag return @@ -102,21 +102,21 @@ func (c *Operation[P, T]) GetResource(ctx context.Context, id resources.ID) (out } out = nil - if errors.Is(&store.ErrNotFound{ID: id.String()}, err) { + if errors.Is(&database.ErrNotFound{ID: id.String()}, err) { err = nil } return } -// SaveResource is the helper to save the resource via storage client. +// SaveResource is the helper to save the resource via database client. func (c *Operation[P, T]) SaveResource(ctx context.Context, id string, in *T, etag string) (string, error) { - nr := &store.Object{ - Metadata: store.Metadata{ + nr := &database.Object{ + Metadata: database.Metadata{ ID: id, }, Data: in, } - err := c.StorageClient().Save(ctx, nr, store.WithETag(etag)) + err := c.DatabaseClient().Save(ctx, nr, database.WithETag(etag)) if err != nil { return "", err } diff --git a/pkg/armrpc/frontend/defaultoperation/defaultasyncdelete_test.go b/pkg/armrpc/frontend/defaultoperation/defaultasyncdelete_test.go index 7787f17772..e28a7b6f66 100644 --- a/pkg/armrpc/frontend/defaultoperation/defaultasyncdelete_test.go +++ b/pkg/armrpc/frontend/defaultoperation/defaultasyncdelete_test.go @@ -29,7 +29,7 @@ import ( ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rest" "github.com/radius-project/radius/pkg/armrpc/rpctest" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -46,7 +46,7 @@ func TestDefaultAsyncDelete(t *testing.T) { rejectedByFilter bool code int }{ - {"async-delete-non-existing-resource-no-etag", "", v1.ProvisioningStateNone, &store.ErrNotFound{}, nil, nil, false, http.StatusNoContent}, + {"async-delete-non-existing-resource-no-etag", "", v1.ProvisioningStateNone, &database.ErrNotFound{}, nil, nil, false, http.StatusNoContent}, {"async-delete-existing-resource-blocked-by-filter", "", v1.ProvisioningStateSucceeded, nil, nil, nil, true, http.StatusConflict}, {"async-delete-existing-resource-not-in-terminal-state", "", v1.ProvisioningStateUpdating, nil, nil, nil, false, http.StatusConflict}, {"async-delete-existing-resource-success", "", v1.ProvisioningStateSucceeded, nil, nil, nil, false, http.StatusAccepted}, @@ -75,8 +75,8 @@ func TestDefaultAsyncDelete(t *testing.T) { mds.EXPECT(). Get(gomock.Any(), gomock.Any()). - Return(&store.Object{ - Metadata: store.Metadata{ID: appDataModel.ID}, + Return(&database.Object{ + Metadata: database.Metadata{ID: appDataModel.ID}, Data: appDataModel, }, tt.getErr). Times(1) @@ -96,8 +96,8 @@ func TestDefaultAsyncDelete(t *testing.T) { } opts := ctrl.Options{ - StorageClient: mds, - StatusManager: msm, + DatabaseClient: mds, + StatusManager: msm, } resourceOpts := ctrl.ResourceOptions[TestResourceDataModel]{ diff --git a/pkg/armrpc/frontend/defaultoperation/defaultasyncput_test.go b/pkg/armrpc/frontend/defaultoperation/defaultasyncput_test.go index 005349d86e..a66a120c6f 100644 --- a/pkg/armrpc/frontend/defaultoperation/defaultasyncput_test.go +++ b/pkg/armrpc/frontend/defaultoperation/defaultasyncput_test.go @@ -29,7 +29,7 @@ import ( "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rpctest" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/test/testutil" "github.com/stretchr/testify/require" @@ -48,7 +48,7 @@ func TestDefaultAsyncPut_Create(t *testing.T) { }{ { "async-create-new-resource-success", - &store.ErrNotFound{}, + &database.ErrNotFound{}, nil, nil, nil, @@ -57,16 +57,16 @@ func TestDefaultAsyncPut_Create(t *testing.T) { }, { "async-create-new-resource-concurrency-error", - &store.ErrConcurrency{}, + &database.ErrConcurrency{}, nil, nil, nil, http.StatusCreated, - &store.ErrConcurrency{}, + &database.ErrConcurrency{}, }, { "async-create-new-resource-enqueue-error", - &store.ErrNotFound{}, + &database.ErrNotFound{}, nil, errors.New("enqueuer client is unset"), nil, @@ -95,10 +95,10 @@ func TestDefaultAsyncPut_Create(t *testing.T) { var asyncOperationRetryAfter = 2*time.Second + 2*time.Millisecond mds.EXPECT().Get(gomock.Any(), gomock.Any()). - Return(&store.Object{}, tt.getErr). + Return(&database.Object{}, tt.getErr). Times(1) - if tt.getErr == nil || errors.Is(&store.ErrNotFound{}, tt.getErr) { + if tt.getErr == nil || errors.Is(&database.ErrNotFound{}, tt.getErr) { mds.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()). Return(tt.saveErr). Times(1) @@ -121,8 +121,8 @@ func TestDefaultAsyncPut_Create(t *testing.T) { } opts := ctrl.Options{ - StorageClient: mds, - StatusManager: msm, + DatabaseClient: mds, + StatusManager: msm, } resourceOpts := ctrl.ResourceOptions[TestResourceDataModel]{ @@ -211,11 +211,11 @@ func TestDefaultAsyncPut_Update(t *testing.T) { "resource-datamodel.json", nil, false, - &store.ErrConcurrency{}, + &database.ErrConcurrency{}, nil, nil, http.StatusInternalServerError, - &store.ErrConcurrency{}, + &database.ErrConcurrency{}, }, { "async-update-existing-resource-save-error", @@ -224,11 +224,11 @@ func TestDefaultAsyncPut_Update(t *testing.T) { "resource-datamodel.json", nil, false, - &store.ErrInvalid{Message: "testing initial save err"}, + &database.ErrInvalid{Message: "testing initial save err"}, nil, nil, http.StatusInternalServerError, - &store.ErrInvalid{Message: "testing initial save err"}, + &database.ErrInvalid{Message: "testing initial save err"}, }, { "async-update-existing-resource-enqueue-error", @@ -238,10 +238,10 @@ func TestDefaultAsyncPut_Update(t *testing.T) { nil, false, nil, - &store.ErrInvalid{Message: "testing initial save err"}, + &database.ErrInvalid{Message: "testing initial save err"}, nil, http.StatusInternalServerError, - &store.ErrInvalid{Message: "testing initial save err"}, + &database.ErrInvalid{Message: "testing initial save err"}, }, } @@ -265,8 +265,8 @@ func TestDefaultAsyncPut_Update(t *testing.T) { ctx := rpctest.NewARMRequestContext(req) sCtx := v1.ARMRequestContextFromContext(ctx) - so := &store.Object{ - Metadata: store.Metadata{ID: sCtx.ResourceID.String()}, + so := &database.Object{ + Metadata: database.Metadata{ID: sCtx.ResourceID.String()}, Data: reqDataModel, } @@ -293,8 +293,8 @@ func TestDefaultAsyncPut_Update(t *testing.T) { } opts := ctrl.Options{ - StorageClient: mds, - StatusManager: msm, + DatabaseClient: mds, + StatusManager: msm, } resourceOpts := ctrl.ResourceOptions[TestResourceDataModel]{ diff --git a/pkg/armrpc/frontend/defaultoperation/defaultsyncdelete.go b/pkg/armrpc/frontend/defaultoperation/defaultsyncdelete.go index 6971c3c74a..62ff4e67dd 100644 --- a/pkg/armrpc/frontend/defaultoperation/defaultsyncdelete.go +++ b/pkg/armrpc/frontend/defaultoperation/defaultsyncdelete.go @@ -24,7 +24,7 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rest" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" ) // DefaultSyncDelete is the controller implementation to delete resource synchronously. @@ -68,8 +68,8 @@ func (e *DefaultSyncDelete[P, T]) Run(ctx context.Context, w http.ResponseWriter } } - if err := e.StorageClient().Delete(ctx, serviceCtx.ResourceID.String()); err != nil { - if errors.Is(&store.ErrNotFound{ID: serviceCtx.ResourceID.String()}, err) { + if err := e.DatabaseClient().Delete(ctx, serviceCtx.ResourceID.String()); err != nil { + if errors.Is(&database.ErrNotFound{ID: serviceCtx.ResourceID.String()}, err) { return rest.NewNoContentResponse(), nil } return nil, err diff --git a/pkg/armrpc/frontend/defaultoperation/defaultsyncdelete_test.go b/pkg/armrpc/frontend/defaultoperation/defaultsyncdelete_test.go index 6568cb411b..361d1bef18 100644 --- a/pkg/armrpc/frontend/defaultoperation/defaultsyncdelete_test.go +++ b/pkg/armrpc/frontend/defaultoperation/defaultsyncdelete_test.go @@ -26,7 +26,7 @@ import ( ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rest" "github.com/radius-project/radius/pkg/armrpc/rpctest" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -42,9 +42,9 @@ func TestDefaultSyncDelete(t *testing.T) { code int }{ {"sync-delete-existing-resource-success", "", nil, nil, false, http.StatusOK}, - {"sync-delete-non-existing-resource", "", &store.ErrNotFound{}, nil, false, http.StatusNoContent}, + {"sync-delete-non-existing-resource", "", &database.ErrNotFound{}, nil, false, http.StatusNoContent}, {"sync-delete-existing-resource-blocked-by-filter", "", nil, nil, true, http.StatusConflict}, - {"sync-delete-fails-resource-notfound", "", nil, &store.ErrNotFound{}, false, http.StatusNoContent}, + {"sync-delete-fails-resource-notfound", "", nil, &database.ErrNotFound{}, false, http.StatusNoContent}, } for _, tt := range deleteCases { @@ -63,8 +63,8 @@ func TestDefaultSyncDelete(t *testing.T) { mds.EXPECT(). Get(gomock.Any(), gomock.Any()). - Return(&store.Object{ - Metadata: store.Metadata{ID: appDataModel.ID}, + Return(&database.Object{ + Metadata: database.Metadata{ID: appDataModel.ID}, Data: appDataModel, }, tt.getErr). Times(1) @@ -78,8 +78,8 @@ func TestDefaultSyncDelete(t *testing.T) { } opts := ctrl.Options{ - StorageClient: mds, - StatusManager: msm, + DatabaseClient: mds, + StatusManager: msm, } resourceOpts := ctrl.ResourceOptions[TestResourceDataModel]{ diff --git a/pkg/armrpc/frontend/defaultoperation/defaultsyncput_test.go b/pkg/armrpc/frontend/defaultoperation/defaultsyncput_test.go index 025da32807..a5dd737b26 100644 --- a/pkg/armrpc/frontend/defaultoperation/defaultsyncput_test.go +++ b/pkg/armrpc/frontend/defaultoperation/defaultsyncput_test.go @@ -27,7 +27,7 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rpctest" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/test/testutil" "github.com/stretchr/testify/require" @@ -44,17 +44,17 @@ func TestDefaultSyncPut_Create(t *testing.T) { }{ { "sync-create-new-resource-success", - &store.ErrNotFound{}, + &database.ErrNotFound{}, nil, http.StatusOK, nil, }, { "sync-create-new-resource-concurrency-error", - &store.ErrConcurrency{}, + &database.ErrConcurrency{}, nil, http.StatusOK, - &store.ErrConcurrency{}, + &database.ErrConcurrency{}, }, } @@ -72,18 +72,18 @@ func TestDefaultSyncPut_Create(t *testing.T) { ctx := rpctest.NewARMRequestContext(req) mds.EXPECT().Get(gomock.Any(), gomock.Any()). - Return(&store.Object{}, tt.getErr). + Return(&database.Object{}, tt.getErr). Times(1) - if tt.getErr == nil || errors.Is(&store.ErrNotFound{}, tt.getErr) { + if tt.getErr == nil || errors.Is(&database.ErrNotFound{}, tt.getErr) { mds.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()). Return(tt.saveErr). Times(1) } opts := ctrl.Options{ - StorageClient: mds, - StatusManager: msm, + DatabaseClient: mds, + StatusManager: msm, } resourceOpts := ctrl.ResourceOptions[TestResourceDataModel]{ @@ -154,11 +154,11 @@ func TestDefaultSyncPut_Update(t *testing.T) { "resource-datamodel.json", nil, false, - &store.ErrConcurrency{}, + &database.ErrConcurrency{}, nil, nil, http.StatusInternalServerError, - &store.ErrConcurrency{}, + &database.ErrConcurrency{}, }, { "sync-update-existing-resource-save-error", @@ -166,11 +166,11 @@ func TestDefaultSyncPut_Update(t *testing.T) { "resource-datamodel.json", nil, false, - &store.ErrInvalid{Message: "testing initial save err"}, + &database.ErrInvalid{Message: "testing initial save err"}, nil, nil, http.StatusInternalServerError, - &store.ErrInvalid{Message: "testing initial save err"}, + &database.ErrInvalid{Message: "testing initial save err"}, }, } @@ -192,8 +192,8 @@ func TestDefaultSyncPut_Update(t *testing.T) { ctx := rpctest.NewARMRequestContext(req) sCtx := v1.ARMRequestContextFromContext(ctx) - so := &store.Object{ - Metadata: store.Metadata{ID: sCtx.ResourceID.String()}, + so := &database.Object{ + Metadata: database.Metadata{ID: sCtx.ResourceID.String()}, Data: reqDataModel, } @@ -208,8 +208,8 @@ func TestDefaultSyncPut_Update(t *testing.T) { } opts := ctrl.Options{ - StorageClient: mds, - StatusManager: msm, + DatabaseClient: mds, + StatusManager: msm, } resourceOpts := ctrl.ResourceOptions[TestResourceDataModel]{ diff --git a/pkg/armrpc/frontend/defaultoperation/getoperationresult.go b/pkg/armrpc/frontend/defaultoperation/getoperationresult.go index 473884ab24..a9b452892f 100644 --- a/pkg/armrpc/frontend/defaultoperation/getoperationresult.go +++ b/pkg/armrpc/frontend/defaultoperation/getoperationresult.go @@ -27,8 +27,8 @@ import ( manager "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rest" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" ) var _ ctrl.Controller = (*GetOperationResult)(nil) @@ -56,8 +56,8 @@ func (e *GetOperationResult) Run(ctx context.Context, w http.ResponseWriter, req return rest.NewBadRequestResponse(err.Error()), nil } - obj, err := e.StorageClient().Get(ctx, id.String()) - if errors.Is(&store.ErrNotFound{ID: id.String()}, err) { + obj, err := e.DatabaseClient().Get(ctx, id.String()) + if errors.Is(&database.ErrNotFound{ID: id.String()}, err) { return rest.NewNotFoundResponse(id), nil } diff --git a/pkg/armrpc/frontend/defaultoperation/getoperationresult_test.go b/pkg/armrpc/frontend/defaultoperation/getoperationresult_test.go index 9434bfed4a..b6fee80ac4 100644 --- a/pkg/armrpc/frontend/defaultoperation/getoperationresult_test.go +++ b/pkg/armrpc/frontend/defaultoperation/getoperationresult_test.go @@ -28,7 +28,7 @@ import ( manager "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rpctest" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/test/testcontext" "github.com/radius-project/radius/test/testutil" @@ -50,22 +50,22 @@ func TestGetOperationResultRun(t *testing.T) { t.Run("get non-existing resource", func(t *testing.T) { mctrl := gomock.NewController(t) - storageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) w := httptest.NewRecorder() req, err := rpctest.NewHTTPRequestFromJSON(testcontext.New(t), http.MethodGet, operationStatusTestHeaderFile, nil) require.NoError(t, err) ctx := rpctest.NewARMRequestContext(req) - storageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }) ctl, err := NewGetOperationResult(ctrl.Options{ - StorageClient: storageClient, + DatabaseClient: databaseClient, }) require.NoError(t, err) @@ -116,7 +116,7 @@ func TestGetOperationResultRun(t *testing.T) { for _, tt := range opResTestCases { t.Run(tt.desc, func(t *testing.T) { mctrl := gomock.NewController(t) - storageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) w := httptest.NewRecorder() req, err := rpctest.NewHTTPRequestFromJSON(testcontext.New(t), http.MethodGet, operationStatusTestHeaderFile, nil) @@ -126,18 +126,18 @@ func TestGetOperationResultRun(t *testing.T) { osDataModel.Status = tt.provisioningState osDataModel.RetryAfter = time.Second * 5 - storageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id}, Data: osDataModel, }, nil }) ctl, err := NewGetOperationResult(ctrl.Options{ - StorageClient: storageClient, + DatabaseClient: databaseClient, }) require.NoError(t, err) diff --git a/pkg/armrpc/frontend/defaultoperation/getoperationstatus.go b/pkg/armrpc/frontend/defaultoperation/getoperationstatus.go index f83b31d4eb..558822c8aa 100644 --- a/pkg/armrpc/frontend/defaultoperation/getoperationstatus.go +++ b/pkg/armrpc/frontend/defaultoperation/getoperationstatus.go @@ -25,7 +25,7 @@ import ( manager "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rest" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" ) var _ ctrl.Controller = (*GetOperationStatus)(nil) @@ -49,7 +49,7 @@ func (e *GetOperationStatus) Run(ctx context.Context, w http.ResponseWriter, req os := &manager.Status{} _, err := e.GetResource(ctx, serviceCtx.ResourceID.String(), os) - if err != nil && errors.Is(&store.ErrNotFound{ID: serviceCtx.ResourceID.String()}, err) { + if err != nil && errors.Is(&database.ErrNotFound{ID: serviceCtx.ResourceID.String()}, err) { return rest.NewNotFoundResponse(serviceCtx.ResourceID), nil } diff --git a/pkg/armrpc/frontend/defaultoperation/getoperationstatus_test.go b/pkg/armrpc/frontend/defaultoperation/getoperationstatus_test.go index 2b4ee7cccb..1ab1f52225 100644 --- a/pkg/armrpc/frontend/defaultoperation/getoperationstatus_test.go +++ b/pkg/armrpc/frontend/defaultoperation/getoperationstatus_test.go @@ -27,7 +27,7 @@ import ( manager "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rpctest" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/test/testutil" "github.com/stretchr/testify/require" @@ -38,7 +38,7 @@ func TestGetOperationStatusRun(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() - mStorageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) ctx := context.Background() rawDataModel := testutil.ReadFixture("operationstatus_datamodel.json") @@ -55,15 +55,15 @@ func TestGetOperationStatusRun(t *testing.T) { require.NoError(t, err) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }) ctl, err := NewGetOperationStatus(ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, }) require.NoError(t, err) @@ -79,18 +79,18 @@ func TestGetOperationStatusRun(t *testing.T) { require.NoError(t, err) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id}, Data: osDataModel, }, nil }) ctl, err := NewGetOperationStatus(ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, }) require.NoError(t, err) diff --git a/pkg/armrpc/frontend/defaultoperation/getresource_test.go b/pkg/armrpc/frontend/defaultoperation/getresource_test.go index 9531b9b9e6..3c48a8f977 100644 --- a/pkg/armrpc/frontend/defaultoperation/getresource_test.go +++ b/pkg/armrpc/frontend/defaultoperation/getresource_test.go @@ -26,7 +26,7 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rpctest" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -90,7 +90,7 @@ func TestGetResourceRun(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() - mStorageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) ctx := context.Background() testResourceDataModel := &testDataModel{ @@ -106,15 +106,15 @@ func TestGetResourceRun(t *testing.T) { require.NoError(t, err) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctrlOpts := ctrl.ResourceOptions[testDataModel]{ @@ -136,18 +136,18 @@ func TestGetResourceRun(t *testing.T) { require.NoError(t, err) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id}, Data: testResourceDataModel, }, nil }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctrlOpts := ctrl.ResourceOptions[testDataModel]{ diff --git a/pkg/armrpc/frontend/defaultoperation/listresources.go b/pkg/armrpc/frontend/defaultoperation/listresources.go index 0329d6650e..4aee3fe37d 100644 --- a/pkg/armrpc/frontend/defaultoperation/listresources.go +++ b/pkg/armrpc/frontend/defaultoperation/listresources.go @@ -23,7 +23,7 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rest" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" ) // ListResources is the controller implementation to get the list of resources in resource group. @@ -48,13 +48,13 @@ func NewListResources[P interface { func (e *ListResources[P, T]) Run(ctx context.Context, w http.ResponseWriter, req *http.Request) (rest.Response, error) { serviceCtx := v1.ARMRequestContextFromContext(ctx) - query := store.Query{ + query := database.Query{ RootScope: serviceCtx.ResourceID.RootScope(), ResourceType: serviceCtx.ResourceID.Type(), ScopeRecursive: e.listRecursiveQuery, } - result, err := e.StorageClient().Query(ctx, query, store.WithPaginationToken(serviceCtx.SkipToken), store.WithMaxQueryItemCount(serviceCtx.Top)) + result, err := e.DatabaseClient().Query(ctx, query, database.WithPaginationToken(serviceCtx.SkipToken), database.WithMaxQueryItemCount(serviceCtx.Top)) if err != nil { return nil, err } @@ -64,7 +64,7 @@ func (e *ListResources[P, T]) Run(ctx context.Context, w http.ResponseWriter, re return rest.NewOKResponse(pagination), err } -func (e *ListResources[P, T]) createPaginationResponse(ctx context.Context, req *http.Request, result *store.ObjectQueryResult) (*v1.PaginatedList, error) { +func (e *ListResources[P, T]) createPaginationResponse(ctx context.Context, req *http.Request, result *database.ObjectQueryResult) (*v1.PaginatedList, error) { serviceCtx := v1.ARMRequestContextFromContext(ctx) items := []any{} diff --git a/pkg/armrpc/frontend/defaultoperation/listresources_test.go b/pkg/armrpc/frontend/defaultoperation/listresources_test.go index 9d11b14188..c000973cb9 100644 --- a/pkg/armrpc/frontend/defaultoperation/listresources_test.go +++ b/pkg/armrpc/frontend/defaultoperation/listresources_test.go @@ -27,7 +27,7 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rpctest" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/google/uuid" "github.com/stretchr/testify/require" @@ -43,7 +43,7 @@ func TestListResourcesRun(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() - mStorageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) ctx := context.Background() testResourceDataModel := &testDataModel{ @@ -59,17 +59,17 @@ func TestListResourcesRun(t *testing.T) { require.NoError(t, err) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Query(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { - return &store.ObjectQueryResult{ - Items: []store.Object{}, + DoAndReturn(func(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { + return &database.ObjectQueryResult{ + Items: []database.Object{}, }, nil }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctrlOpts := ctrl.ResourceOptions[testDataModel]{ @@ -123,10 +123,10 @@ func TestListResourcesRun(t *testing.T) { paginationToken = "nextLink" } - items := []store.Object{} + items := []database.Object{} for i := 0; i < tt.batchCount; i++ { - item := store.Object{ - Metadata: store.Metadata{ + item := database.Object{ + Metadata: database.Metadata{ ID: uuid.New().String(), }, Data: testResourceDataModel, @@ -134,7 +134,7 @@ func TestListResourcesRun(t *testing.T) { items = append(items, item) } - expectedQuery := store.Query{ + expectedQuery := database.Query{ RootScope: serviceCtx.ResourceID.RootScope(), ResourceType: serviceCtx.ResourceID.Type(), @@ -144,18 +144,18 @@ func TestListResourcesRun(t *testing.T) { ScopeRecursive: tt.planeScope, } - mStorageClient. + databaseClient. EXPECT(). Query(gomock.Any(), expectedQuery, gomock.Any()). - DoAndReturn(func(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { - return &store.ObjectQueryResult{ + DoAndReturn(func(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { + return &database.ObjectQueryResult{ Items: items, PaginationToken: paginationToken, }, nil }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctrlOpts := ctrl.ResourceOptions[testDataModel]{ diff --git a/pkg/armrpc/frontend/defaultoperation/resource_test.go b/pkg/armrpc/frontend/defaultoperation/resource_test.go index c66edf0a37..ad17c88548 100644 --- a/pkg/armrpc/frontend/defaultoperation/resource_test.go +++ b/pkg/armrpc/frontend/defaultoperation/resource_test.go @@ -29,7 +29,7 @@ import ( "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rest" "github.com/radius-project/radius/pkg/to" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/test/testutil" "go.uber.org/mock/gomock" @@ -207,9 +207,9 @@ func loadTestResurce() (*TestResource, *TestResourceDataModel, *TestResource) { return reqModel, datamodel, respModel } -func setupTest(tb testing.TB) (func(testing.TB), *store.MockStorageClient, *statusmanager.MockStatusManager) { +func setupTest(tb testing.TB) (func(testing.TB), *database.MockClient, *statusmanager.MockStatusManager) { mctrl := gomock.NewController(tb) - mds := store.NewMockStorageClient(mctrl) + mds := database.NewMockClient(mctrl) msm := statusmanager.NewMockStatusManager(mctrl) return func(tb testing.TB) { diff --git a/pkg/armrpc/frontend/server/handler.go b/pkg/armrpc/frontend/server/handler.go index e5d3c47b3d..fdcbd99453 100644 --- a/pkg/armrpc/frontend/server/handler.go +++ b/pkg/armrpc/frontend/server/handler.go @@ -55,11 +55,6 @@ type ControllerFactoryFunc func(ctrl.Options) (ctrl.Controller, error) // multiple types of resources (e.g. PUT on any type of AWS resource): // - Set ResourceType for operations that are scoped to a resource type. // - Set OperationType for general operations. -// -// In the controller options passed to the controller factory: -// -// - When ResourceType is set, the StorageClient will be configured to use the resource type. -// - When OperationType is set, the StorageClient will be generic and not filtered to a specific resource type. type HandlerOptions struct { // ParentRouter is the router to register the handler with. ParentRouter chi.Router @@ -68,8 +63,6 @@ type HandlerOptions struct { Path string // ResourceType is the resource type of the operation. May be blank if Operation is specified. - // - // If specified the ResourceType will be used to filter the StorageClient. ResourceType string // Method is the method of the operation. May be blank if Operation is specified. diff --git a/pkg/armrpc/frontend/server/handler_test.go b/pkg/armrpc/frontend/server/handler_test.go index 107c8b6877..bd323a06a9 100644 --- a/pkg/armrpc/frontend/server/handler_test.go +++ b/pkg/armrpc/frontend/server/handler_test.go @@ -33,7 +33,7 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rest" "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/middleware" - "github.com/radius-project/radius/pkg/ucp/store/inmemory" + "github.com/radius-project/radius/pkg/ucp/database/inmemory" "github.com/radius-project/radius/test/testcontext" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -75,10 +75,10 @@ func Test_NewSubrouter(t *testing.T) { func Test_RegisterHandler_DeplicatedRoutes(t *testing.T) { ctrlOpts := ctrl.Options{ - Address: "localhost:8080", - ResourceType: "Applications.Test/testResources", - StorageClient: inmemory.NewClient(), - StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), + Address: "localhost:8080", + ResourceType: "Applications.Test/testResources", + DatabaseClient: inmemory.NewClient(), + StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), } p := chi.NewRouter() @@ -169,9 +169,9 @@ func Test_RegisterHandler(t *testing.T) { } ctrlOpts := ctrl.Options{ - Address: "localhost:8080", - StorageClient: inmemory.NewClient(), - StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), + Address: "localhost:8080", + DatabaseClient: inmemory.NewClient(), + StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), } for _, tc := range tests { diff --git a/pkg/armrpc/frontend/server/service.go b/pkg/armrpc/frontend/server/service.go index 6d31f1c958..265ec4e17d 100644 --- a/pkg/armrpc/frontend/server/service.go +++ b/pkg/armrpc/frontend/server/service.go @@ -25,8 +25,8 @@ import ( "github.com/radius-project/radius/pkg/armrpc/authentication" "github.com/radius-project/radius/pkg/armrpc/hostoptions" "github.com/radius-project/radius/pkg/kubeutil" - "github.com/radius-project/radius/pkg/ucp/dataprovider" - qprovider "github.com/radius-project/radius/pkg/ucp/queue/provider" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" + "github.com/radius-project/radius/pkg/ucp/queue/queueprovider" "github.com/radius-project/radius/pkg/ucp/ucplog" controller_runtime "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -39,8 +39,8 @@ type Service struct { // Options is the server hosting options. Options hostoptions.HostOptions - // StorageProvider is the provider of storage client. - StorageProvider *dataprovider.DataStorageProvider + // DatabaseProvider is the provider of database client. + DatabaseProvider *databaseprovider.DatabaseProvider // OperationStatusManager is the manager of the operation status. OperationStatusManager manager.StatusManager @@ -52,15 +52,15 @@ type Service struct { KubeClient controller_runtime.Client } -// Init initializes web service - it initializes the StorageProvider, QueueProvider, OperationStatusManager, KubeClient and ARMCertManager +// Init initializes web service - it initializes the DatabaseProvider, QueueProvider, OperationStatusManager, KubeClient and ARMCertManager // with the given context and returns an error if any of the initialization fails. func (s *Service) Init(ctx context.Context) error { logger := ucplog.FromContextOrDiscard(ctx) - s.StorageProvider = dataprovider.DataStorageProviderFromOptions(s.Options.Config.StorageProvider) - qp := qprovider.New(s.Options.Config.QueueProvider) + s.DatabaseProvider = databaseprovider.FromOptions(s.Options.Config.DatabaseProvider) + qp := queueprovider.New(s.Options.Config.QueueProvider) - storageClient, err := s.StorageProvider.GetClient(ctx) + databaseClient, err := s.DatabaseProvider.GetClient(ctx) if err != nil { return err } @@ -69,7 +69,7 @@ func (s *Service) Init(ctx context.Context) error { if err != nil { return err } - s.OperationStatusManager = manager.New(storageClient, reqQueueClient, s.Options.Config.Env.RoleLocation) + s.OperationStatusManager = manager.New(databaseClient, reqQueueClient, s.Options.Config.Env.RoleLocation) s.KubeClient, err = kubeutil.NewRuntimeClient(s.Options.K8sConfig) if err != nil { return err diff --git a/pkg/armrpc/hostoptions/hostoptions.go b/pkg/armrpc/hostoptions/hostoptions.go index f669c93f92..37750cf659 100644 --- a/pkg/armrpc/hostoptions/hostoptions.go +++ b/pkg/armrpc/hostoptions/hostoptions.go @@ -32,7 +32,7 @@ import ( "github.com/radius-project/radius/pkg/sdk" "github.com/radius-project/radius/pkg/ucp/config" sdk_cred "github.com/radius-project/radius/pkg/ucp/credentials" - sprovider "github.com/radius-project/radius/pkg/ucp/secret/provider" + sprovider "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" "gopkg.in/yaml.v3" corev1 "k8s.io/api/core/v1" diff --git a/pkg/armrpc/hostoptions/providerconfig.go b/pkg/armrpc/hostoptions/providerconfig.go index 05f4318012..f2acbf3d28 100644 --- a/pkg/armrpc/hostoptions/providerconfig.go +++ b/pkg/armrpc/hostoptions/providerconfig.go @@ -21,9 +21,9 @@ import ( profilerprovider "github.com/radius-project/radius/pkg/profiler/provider" "github.com/radius-project/radius/pkg/trace" "github.com/radius-project/radius/pkg/ucp/config" - "github.com/radius-project/radius/pkg/ucp/dataprovider" - qprovider "github.com/radius-project/radius/pkg/ucp/queue/provider" - sprovider "github.com/radius-project/radius/pkg/ucp/secret/provider" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" + "github.com/radius-project/radius/pkg/ucp/queue/queueprovider" + "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" "github.com/radius-project/radius/pkg/ucp/ucplog" ) @@ -31,9 +31,9 @@ import ( type ProviderConfig struct { Env EnvironmentOptions `yaml:"environment"` Identity IdentityOptions `yaml:"identity"` - StorageProvider dataprovider.StorageProviderOptions `yaml:"storageProvider"` - SecretProvider sprovider.SecretProviderOptions `yaml:"secretProvider"` - QueueProvider qprovider.QueueProviderOptions `yaml:"queueProvider"` + DatabaseProvider databaseprovider.Options `yaml:"storageProvider"` + SecretProvider secretprovider.SecretProviderOptions `yaml:"secretProvider"` + QueueProvider queueprovider.QueueProviderOptions `yaml:"queueProvider"` Server *ServerOptions `yaml:"server,omitempty"` WorkerServer *WorkerServerOptions `yaml:"workerServer,omitempty"` MetricsProvider metricsprovider.MetricsProviderOptions `yaml:"metricsProvider"` diff --git a/pkg/armrpc/rpctest/controllers.go b/pkg/armrpc/rpctest/controllers.go index 80610ea8f4..819da12b6f 100644 --- a/pkg/armrpc/rpctest/controllers.go +++ b/pkg/armrpc/rpctest/controllers.go @@ -22,7 +22,7 @@ import ( "testing" v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "go.uber.org/mock/gomock" ) @@ -30,7 +30,7 @@ import ( type ControllerContext struct { Ctx context.Context MCtrl *gomock.Controller - MockSC *store.MockStorageClient + MockSC *database.MockClient } // NewControllerContext creates a new ControllerContext for testing. @@ -40,12 +40,12 @@ func NewControllerContext(t *testing.T) *ControllerContext { return &ControllerContext{ Ctx: context.Background(), MCtrl: mctrl, - MockSC: store.NewMockStorageClient(mctrl), + MockSC: database.NewMockClient(mctrl), } } // FakeStoreObject creates store.Object for datamodel. -func FakeStoreObject(dm v1.DataModelInterface) *store.Object { +func FakeStoreObject(dm v1.DataModelInterface) *database.Object { b, err := json.Marshal(dm) if err != nil { panic(err) @@ -55,5 +55,5 @@ func FakeStoreObject(dm v1.DataModelInterface) *store.Object { if err != nil { panic(err) } - return &store.Object{Data: r} + return &database.Object{Data: r} } diff --git a/pkg/corerp/backend/controller/createorupdateresource.go b/pkg/corerp/backend/controller/createorupdateresource.go index 8a9a5f0b60..65a86ff108 100644 --- a/pkg/corerp/backend/controller/createorupdateresource.go +++ b/pkg/corerp/backend/controller/createorupdateresource.go @@ -30,8 +30,8 @@ import ( "github.com/radius-project/radius/pkg/corerp/renderers/gateway" "github.com/radius-project/radius/pkg/corerp/renderers/volume" rpv1 "github.com/radius-project/radius/pkg/rp/v1" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" ) var _ ctrl.Controller = (*CreateOrUpdateResource)(nil) @@ -63,18 +63,18 @@ func getDataModel(id resources.ID) (v1.DataModelInterface, error) { // Run checks if the resource exists, renders the resource, deploys the resource, applies the // deployment output to the resource, deletes any resources that are no longer needed, and saves the resource. func (c *CreateOrUpdateResource) Run(ctx context.Context, request *ctrl.Request) (ctrl.Result, error) { - obj, err := c.StorageClient().Get(ctx, request.ResourceID) - if err != nil && !errors.Is(&store.ErrNotFound{ID: request.ResourceID}, err) { + obj, err := c.DatabaseClient().Get(ctx, request.ResourceID) + if err != nil && !errors.Is(&database.ErrNotFound{ID: request.ResourceID}, err) { return ctrl.Result{}, err } isNewResource := false - if errors.Is(&store.ErrNotFound{ID: request.ResourceID}, err) { + if errors.Is(&database.ErrNotFound{ID: request.ResourceID}, err) { isNewResource = true } opType, _ := v1.ParseOperationType(request.OperationType) - if opType.Method == http.MethodPatch && errors.Is(&store.ErrNotFound{ID: request.ResourceID}, err) { + if opType.Method == http.MethodPatch && errors.Is(&database.ErrNotFound{ID: request.ResourceID}, err) { return ctrl.Result{}, err } @@ -122,13 +122,13 @@ func (c *CreateOrUpdateResource) Run(ctx context.Context, request *ctrl.Request) } } - nr := &store.Object{ - Metadata: store.Metadata{ + nr := &database.Object{ + Metadata: database.Metadata{ ID: request.ResourceID, }, Data: deploymentDataModel, } - err = c.StorageClient().Save(ctx, nr, store.WithETag(obj.ETag)) + err = c.DatabaseClient().Save(ctx, nr, database.WithETag(obj.ETag)) if err != nil { return ctrl.Result{}, err } diff --git a/pkg/corerp/backend/controller/createorupdateresource_test.go b/pkg/corerp/backend/controller/createorupdateresource_test.go index 3598519f04..8c5a0cc787 100644 --- a/pkg/corerp/backend/controller/createorupdateresource_test.go +++ b/pkg/corerp/backend/controller/createorupdateresource_test.go @@ -34,16 +34,16 @@ import ( "github.com/radius-project/radius/pkg/corerp/renderers/gateway" ds_ctrl "github.com/radius-project/radius/pkg/datastoresrp/frontend/controller" rpv1 "github.com/radius-project/radius/pkg/rp/v1" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" ) func TestCreateOrUpdateResourceRun_20231001Preview(t *testing.T) { - setupTest := func() (func(tb testing.TB), *store.MockStorageClient, *deployment.MockDeploymentProcessor) { + setupTest := func() (func(tb testing.TB), *database.MockClient, *deployment.MockDeploymentProcessor) { mctrl := gomock.NewController(t) - msc := store.NewMockStorageClient(mctrl) + msc := database.NewMockClient(mctrl) mdp := deployment.NewMockDeploymentProcessor(mctrl) return func(tb testing.TB) { @@ -80,7 +80,7 @@ func TestCreateOrUpdateResourceRun_20231001Preview(t *testing.T) { container.ResourceType, "APPLICATIONS.CORE/CONTAINERS|PUT", fmt.Sprintf("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/radius-test-rg/providers/Applications.Core/containers/%s", uuid.NewString()), - &store.ErrNotFound{}, + &database.ErrNotFound{}, false, nil, nil, @@ -116,7 +116,7 @@ func TestCreateOrUpdateResourceRun_20231001Preview(t *testing.T) { gateway.ResourceType, "APPLICATIONS.CORE/GATEWAYS|PUT", fmt.Sprintf("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/radius-test-rg/providers/Applications.Core/gateways/%s", uuid.NewString()), - &store.ErrNotFound{}, + &database.ErrNotFound{}, false, nil, nil, @@ -156,7 +156,7 @@ func TestCreateOrUpdateResourceRun_20231001Preview(t *testing.T) { getCall := msc.EXPECT(). Get(gomock.Any(), gomock.Any()). - Return(&store.Object{ + Return(&database.Object{ Data: map[string]any{ "name": "env0", "properties": map[string]any{ @@ -166,7 +166,7 @@ func TestCreateOrUpdateResourceRun_20231001Preview(t *testing.T) { }, tt.getErr). Times(1) - if (tt.getErr == nil || errors.Is(&store.ErrNotFound{ID: tt.rId}, tt.getErr)) && !tt.convErr { + if (tt.getErr == nil || errors.Is(&database.ErrNotFound{ID: tt.rId}, tt.getErr)) && !tt.convErr { renderCall := mdp.EXPECT(). Render(gomock.Any(), gomock.Any(), gomock.Any()). Return(renderers.RendererOutput{}, tt.renderErr). @@ -180,7 +180,7 @@ func TestCreateOrUpdateResourceRun_20231001Preview(t *testing.T) { After(renderCall). Times(1) - if !errors.Is(&store.ErrNotFound{}, tt.getErr) { + if !errors.Is(&database.ErrNotFound{}, tt.getErr) { mdp.EXPECT(). Delete(gomock.Any(), gomock.Any(), gomock.Any()). Return(nil). @@ -199,7 +199,7 @@ func TestCreateOrUpdateResourceRun_20231001Preview(t *testing.T) { } opts := ctrl.Options{ - StorageClient: msc, + DatabaseClient: msc, GetDeploymentProcessor: func() deployment.DeploymentProcessor { return mdp }, @@ -253,12 +253,12 @@ func TestCreateOrUpdateResourceRun_20231001Preview(t *testing.T) { container.ResourceType, "APPLICATIONS.CORE/CONTAINERS|PATCH", fmt.Sprintf("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/radius-test-rg/providers/Applications.Core/containers/%s", uuid.NewString()), - &store.ErrNotFound{}, + &database.ErrNotFound{}, false, nil, nil, nil, - &store.ErrNotFound{}, + &database.ErrNotFound{}, }, { "container-patch-get-err", @@ -289,12 +289,12 @@ func TestCreateOrUpdateResourceRun_20231001Preview(t *testing.T) { gateway.ResourceType, "APPLICATIONS.CORE/GATEWAYS|PATCH", fmt.Sprintf("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/radius-test-rg/providers/Applications.Core/gateways/%s", uuid.NewString()), - &store.ErrNotFound{}, + &database.ErrNotFound{}, false, nil, nil, nil, - &store.ErrNotFound{}, + &database.ErrNotFound{}, }, { "unsupported-type-patch", @@ -329,7 +329,7 @@ func TestCreateOrUpdateResourceRun_20231001Preview(t *testing.T) { getCall := msc.EXPECT(). Get(gomock.Any(), gomock.Any()). - Return(&store.Object{ + Return(&database.Object{ Data: map[string]any{ "name": "env0", "properties": map[string]any{ @@ -371,7 +371,7 @@ func TestCreateOrUpdateResourceRun_20231001Preview(t *testing.T) { } opts := ctrl.Options{ - StorageClient: msc, + DatabaseClient: msc, GetDeploymentProcessor: func() deployment.DeploymentProcessor { return mdp }, diff --git a/pkg/corerp/backend/controller/deleteresource.go b/pkg/corerp/backend/controller/deleteresource.go index de31e5c484..8ddaca6527 100644 --- a/pkg/corerp/backend/controller/deleteresource.go +++ b/pkg/corerp/backend/controller/deleteresource.go @@ -37,11 +37,11 @@ func NewDeleteResource(opts ctrl.Options) (ctrl.Controller, error) { return &DeleteResource{ctrl.NewBaseAsyncController(opts)}, nil } -// Run retrieves a resource from storage, parses its ID, gets its data model, converts it to a deployment -// data model, deletes the resource from the deployment processor, and deletes the resource from storage. +// Run retrieves a resource from the database, parses its ID, gets its data model, converts it to a deployment +// data model, deletes the resource from the deployment processor, and deletes the resource from the database. // It returns an error if any of these steps fail. func (c *DeleteResource) Run(ctx context.Context, request *ctrl.Request) (ctrl.Result, error) { - obj, err := c.StorageClient().Get(ctx, request.ResourceID) + obj, err := c.DatabaseClient().Get(ctx, request.ResourceID) if err != nil { return ctrl.NewFailedResult(v1.ErrorDetails{Message: err.Error()}), err } @@ -71,7 +71,7 @@ func (c *DeleteResource) Run(ctx context.Context, request *ctrl.Request) (ctrl.R return ctrl.Result{}, err } - err = c.StorageClient().Delete(ctx, request.ResourceID) + err = c.DatabaseClient().Delete(ctx, request.ResourceID) if err != nil { return ctrl.Result{}, err } diff --git a/pkg/corerp/backend/controller/deleteresource_test.go b/pkg/corerp/backend/controller/deleteresource_test.go index 639ccc0cdd..b1cff8cf7c 100644 --- a/pkg/corerp/backend/controller/deleteresource_test.go +++ b/pkg/corerp/backend/controller/deleteresource_test.go @@ -25,17 +25,17 @@ import ( "github.com/google/uuid" ctrl "github.com/radius-project/radius/pkg/armrpc/asyncoperation/controller" deployment "github.com/radius-project/radius/pkg/corerp/backend/deployment" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) func TestDeleteResourceRun_20231001Preview(t *testing.T) { - setupTest := func() (func(tb testing.TB), *store.MockStorageClient, *deployment.MockDeploymentProcessor, *ctrl.Request) { + setupTest := func() (func(tb testing.TB), *database.MockClient, *deployment.MockDeploymentProcessor, *ctrl.Request) { mctrl := gomock.NewController(t) - msc := store.NewMockStorageClient(mctrl) + msc := database.NewMockClient(mctrl) mdp := deployment.NewMockDeploymentProcessor(mctrl) req := &ctrl.Request{ @@ -61,7 +61,7 @@ func TestDeleteResourceRun_20231001Preview(t *testing.T) { scDelErr error }{ {"delete-existing-resource", nil, nil, nil}, - {"delete-non-existing-resource", &store.ErrNotFound{}, nil, nil}, + {"delete-non-existing-resource", &database.ErrNotFound{}, nil, nil}, {"delete-resource-dp-delete-error", nil, errors.New("deployment processor delete error"), nil}, {"delete-resource-delete-from-db-error", nil, nil, errors.New("delete from db error")}, } @@ -73,7 +73,7 @@ func TestDeleteResourceRun_20231001Preview(t *testing.T) { msc.EXPECT(). Get(gomock.Any(), gomock.Any()). - Return(&store.Object{}, tt.getErr). + Return(&database.Object{}, tt.getErr). Times(1) if tt.getErr == nil { @@ -91,7 +91,7 @@ func TestDeleteResourceRun_20231001Preview(t *testing.T) { } opts := ctrl.Options{ - StorageClient: msc, + DatabaseClient: msc, GetDeploymentProcessor: func() deployment.DeploymentProcessor { return mdp }, diff --git a/pkg/corerp/backend/deployment/deploymentprocessor.go b/pkg/corerp/backend/deployment/deploymentprocessor.go index 80392e48bc..a7803ae8bc 100644 --- a/pkg/corerp/backend/deployment/deploymentprocessor.go +++ b/pkg/corerp/backend/deployment/deploymentprocessor.go @@ -40,8 +40,8 @@ import ( msg_dm "github.com/radius-project/radius/pkg/messagingrp/datamodel" msg_ctrl "github.com/radius-project/radius/pkg/messagingrp/frontend/controller" "github.com/radius-project/radius/pkg/portableresources" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/ucplog" "github.com/go-openapi/jsonpointer" @@ -59,15 +59,15 @@ type DeploymentProcessor interface { } // NewDeploymentProcessor creates a new instance of the DeploymentProcessor struct with the given parameters. -func NewDeploymentProcessor(appmodel model.ApplicationModel, storageClient store.StorageClient, k8sClient controller_runtime.Client, k8sClientSet kubernetes.Interface) DeploymentProcessor { - return &deploymentProcessor{appmodel: appmodel, storageClient: storageClient, k8sClient: k8sClient, k8sClientSet: k8sClientSet} +func NewDeploymentProcessor(appmodel model.ApplicationModel, databaseClient database.Client, k8sClient controller_runtime.Client, k8sClientSet kubernetes.Interface) DeploymentProcessor { + return &deploymentProcessor{appmodel: appmodel, databaseClient: databaseClient, k8sClient: k8sClient, k8sClientSet: k8sClientSet} } var _ DeploymentProcessor = (*deploymentProcessor)(nil) type deploymentProcessor struct { - appmodel model.ApplicationModel - storageClient store.StorageClient + appmodel model.ApplicationModel + databaseClient database.Client // k8sClient is the Kubernetes controller runtime client. k8sClient controller_runtime.Client // k8sClientSet is the Kubernetes client. @@ -225,14 +225,14 @@ func (dp *deploymentProcessor) getApplicationAndEnvironmentForResourceID(ctx con // 2. fetch the application properties from the DB app := &corerp_dm.Application{} - err = rp_util.FetchScopeResource(ctx, dp.storageClient, res.AppID.String(), app) + err = rp_util.FetchScopeResource(ctx, dp.databaseClient, res.AppID.String(), app) if err != nil { return nil, nil, err } // 3. fetch the environment resource from the db to get the Namespace env := &corerp_dm.Environment{} - err = rp_util.FetchScopeResource(ctx, dp.storageClient, app.Properties.Environment, env) + err = rp_util.FetchScopeResource(ctx, dp.databaseClient, app.Properties.Environment, env) if err != nil { return nil, nil, err } @@ -480,9 +480,9 @@ func (dp *deploymentProcessor) getAppOptions(appProp *corerp_dm.ApplicationPrope // getResourceDataByID fetches resource for the provided id from the data store func (dp *deploymentProcessor) getResourceDataByID(ctx context.Context, resourceID resources.ID) (ResourceData, error) { errMsg := "failed to fetch the resource %q. Err: %w" - resource, err := dp.storageClient.Get(ctx, resourceID.String()) + resource, err := dp.databaseClient.Get(ctx, resourceID.String()) if err != nil { - if errors.Is(&store.ErrNotFound{ID: resourceID.String()}, err) { + if errors.Is(&database.ErrNotFound{ID: resourceID.String()}, err) { return ResourceData{}, v1.NewClientErrInvalidRequest(fmt.Sprintf("resource %q does not exist", resourceID.String())) } return ResourceData{}, fmt.Errorf(errMsg, resourceID.String(), err) diff --git a/pkg/corerp/backend/deployment/deploymentprocessor_test.go b/pkg/corerp/backend/deployment/deploymentprocessor_test.go index 0f2c4816e8..0cb4aaa29d 100644 --- a/pkg/corerp/backend/deployment/deploymentprocessor_test.go +++ b/pkg/corerp/backend/deployment/deploymentprocessor_test.go @@ -37,10 +37,10 @@ import ( "github.com/radius-project/radius/pkg/resourcemodel" rpv1 "github.com/radius-project/radius/pkg/rp/v1" "github.com/radius-project/radius/pkg/to" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/resources" resources_azure "github.com/radius-project/radius/pkg/ucp/resources/azure" resources_kubernetes "github.com/radius-project/radius/pkg/ucp/resources/kubernetes" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/test/testcontext" "github.com/radius-project/radius/test/testutil" @@ -50,7 +50,7 @@ import ( type SharedMocks struct { model model.ApplicationModel - storageClient *store.MockStorageClient + databaseClient *database.MockClient resourceHandler *handlers.MockResourceHandler renderer *renderers.MockRenderer mctrl *gomock.Controller @@ -129,10 +129,10 @@ func setup(t *testing.T) SharedMocks { }, } - storageClient := store.NewMockStorageClient(ctrl) + databaseClient := database.NewMockClient(ctrl) return SharedMocks{ model: model, - storageClient: storageClient, + databaseClient: databaseClient, resourceHandler: resourceHandler, renderer: renderer, mctrl: ctrl, @@ -301,7 +301,7 @@ func Test_Render(t *testing.T) { t.Run("verify render success", func(t *testing.T) { mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() testRendererOutput := getTestRendererOutput() @@ -313,13 +313,13 @@ func Test_Render(t *testing.T) { mocks.renderer.EXPECT().Render(gomock.Any(), gomock.Any(), gomock.Any()).Times(1).Return(testRendererOutput, nil) mocks.renderer.EXPECT().GetDependencyIDs(gomock.Any(), gomock.Any()).Times(1).Return(requiredResources, nil, nil) - cr := store.Object{ - Metadata: store.Metadata{ + cr := database.Object{ + Metadata: database.Metadata{ ID: testResource.ID, }, Data: testResource, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) application := datamodel.Application{ BaseResource: v1.BaseResource{ TrackedResource: v1.TrackedResource{ @@ -332,20 +332,20 @@ func Test_Render(t *testing.T) { }, }, } - ar := store.Object{ - Metadata: store.Metadata{ + ar := database.Object{ + Metadata: database.Metadata{ ID: application.ID, }, Data: application, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&ar, nil) - er := store.Object{ - Metadata: store.Metadata{ + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&ar, nil) + er := database.Object{ + Metadata: database.Metadata{ ID: env.ID, }, Data: env, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&er, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&er, nil) mongoResource := dsrp_dm.MongoDatabase{ BaseResource: v1.BaseResource{ @@ -359,14 +359,14 @@ func Test_Render(t *testing.T) { }, }, } - mr := store.Object{ - Metadata: store.Metadata{ + mr := database.Object{ + Metadata: database.Metadata{ ID: mongoResource.ID, }, Data: mongoResource, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&mr, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&mr, nil) rendererOutput, err := dp.Render(ctx, resourceID, &testResource) require.NoError(t, err) @@ -375,7 +375,7 @@ func Test_Render(t *testing.T) { t.Run("verify render success lowercase resourcetype", func(t *testing.T) { mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getLowerCaseTestResource() testRendererOutput := getTestRendererOutput() @@ -384,13 +384,13 @@ func Test_Render(t *testing.T) { mocks.renderer.EXPECT().Render(gomock.Any(), gomock.Any(), gomock.Any()).Times(1).Return(testRendererOutput, nil) mocks.renderer.EXPECT().GetDependencyIDs(gomock.Any(), gomock.Any()).Times(1).Return([]resources.ID{}, nil, nil) - cr := store.Object{ - Metadata: store.Metadata{ + cr := database.Object{ + Metadata: database.Metadata{ ID: testResource.ID, }, Data: testResource, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) application := datamodel.Application{ BaseResource: v1.BaseResource{ TrackedResource: v1.TrackedResource{ @@ -403,20 +403,20 @@ func Test_Render(t *testing.T) { }, }, } - ar := store.Object{ - Metadata: store.Metadata{ + ar := database.Object{ + Metadata: database.Metadata{ ID: application.ID, }, Data: application, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&ar, nil) - er := store.Object{ - Metadata: store.Metadata{ + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&ar, nil) + er := database.Object{ + Metadata: database.Metadata{ ID: env.ID, }, Data: env, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&er, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&er, nil) rendererOutput, err := dp.Render(ctx, resourceID, &testResource) require.NoError(t, err) @@ -425,7 +425,7 @@ func Test_Render(t *testing.T) { t.Run("verify render success uppercase resourcetype", func(t *testing.T) { mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getUpperCaseTestResource() testRendererOutput := getTestRendererOutput() @@ -434,13 +434,13 @@ func Test_Render(t *testing.T) { mocks.renderer.EXPECT().Render(gomock.Any(), gomock.Any(), gomock.Any()).Times(1).Return(testRendererOutput, nil) mocks.renderer.EXPECT().GetDependencyIDs(gomock.Any(), gomock.Any()).Times(1).Return([]resources.ID{}, nil, nil) - cr := store.Object{ - Metadata: store.Metadata{ + cr := database.Object{ + Metadata: database.Metadata{ ID: testResource.ID, }, Data: testResource, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) application := datamodel.Application{ BaseResource: v1.BaseResource{ TrackedResource: v1.TrackedResource{ @@ -453,20 +453,20 @@ func Test_Render(t *testing.T) { }, }, } - ar := store.Object{ - Metadata: store.Metadata{ + ar := database.Object{ + Metadata: database.Metadata{ ID: application.ID, }, Data: application, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&ar, nil) - er := store.Object{ - Metadata: store.Metadata{ + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&ar, nil) + er := database.Object{ + Metadata: database.Metadata{ ID: env.ID, }, Data: env, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&er, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&er, nil) rendererOutput, err := dp.Render(ctx, resourceID, &testResource) require.NoError(t, err) @@ -475,7 +475,7 @@ func Test_Render(t *testing.T) { t.Run("verify render error", func(t *testing.T) { mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() resourceID := getTestResourceID(testResource.ID) @@ -483,13 +483,13 @@ func Test_Render(t *testing.T) { mocks.renderer.EXPECT().GetDependencyIDs(gomock.Any(), gomock.Any()).Times(1).Return([]resources.ID{}, nil, nil) mocks.renderer.EXPECT().Render(gomock.Any(), gomock.Any(), gomock.Any()).Times(1).Return(renderers.RendererOutput{}, errors.New("failed to render the resource")) - cr := store.Object{ - Metadata: store.Metadata{ + cr := database.Object{ + Metadata: database.Metadata{ ID: testResource.ID, }, Data: testResource, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) application := datamodel.Application{ BaseResource: v1.BaseResource{ TrackedResource: v1.TrackedResource{ @@ -502,20 +502,20 @@ func Test_Render(t *testing.T) { }, }, } - ar := store.Object{ - Metadata: store.Metadata{ + ar := database.Object{ + Metadata: database.Metadata{ ID: application.ID, }, Data: application, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&ar, nil) - er := store.Object{ - Metadata: store.Metadata{ + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&ar, nil) + er := database.Object{ + Metadata: database.Metadata{ ID: env.ID, }, Data: env, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&er, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&er, nil) _, err := dp.Render(ctx, resourceID, &testResource) require.Error(t, err, "failed to render the resource") @@ -523,12 +523,12 @@ func Test_Render(t *testing.T) { t.Run("Resource not found in data store", func(t *testing.T) { mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() resourceID := getTestResourceID(testResource.ID) - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&store.Object{}, &store.ErrNotFound{ID: testResource.ID}) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&database.Object{}, &database.ErrNotFound{ID: testResource.ID}) _, err := dp.Render(ctx, resourceID, &testResource) require.Error(t, err) @@ -538,12 +538,12 @@ func Test_Render(t *testing.T) { t.Run("Data store access error", func(t *testing.T) { mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() resourceID := getTestResourceID(testResource.ID) - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&store.Object{}, errors.New("failed to connect to data store")) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&database.Object{}, errors.New("failed to connect to data store")) _, err := dp.Render(ctx, resourceID, &testResource) require.Error(t, err) @@ -552,7 +552,7 @@ func Test_Render(t *testing.T) { t.Run("Invalid resource type", func(t *testing.T) { mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testInvalidResourceID := "/subscriptions/test-sub/resourceGroups/test-group/providers/Applications.foo/foo/foo" testResource := getTestResource() @@ -564,19 +564,19 @@ func Test_Render(t *testing.T) { t.Run("Invalid application id", func(t *testing.T) { mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() resourceID := getTestResourceID(testResource.ID) testResource.Properties.Application = "invalid-app-id" - cr := store.Object{ - Metadata: store.Metadata{ + cr := database.Object{ + Metadata: database.Metadata{ ID: testResource.ID, }, Data: testResource, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) _, err := dp.Render(ctx, resourceID, &testResource) require.Error(t, err) @@ -586,19 +586,19 @@ func Test_Render(t *testing.T) { t.Run("Missing application id", func(t *testing.T) { mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() resourceID := getTestResourceID(testResource.ID) testResource.Properties.Application = "" - cr := store.Object{ - Metadata: store.Metadata{ + cr := database.Object{ + Metadata: database.Metadata{ ID: testResource.ID, }, Data: testResource, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) _, err := dp.Render(ctx, resourceID, &testResource) require.Error(t, err) @@ -607,19 +607,19 @@ func Test_Render(t *testing.T) { t.Run("Invalid application resource type", func(t *testing.T) { mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() resourceID := getTestResourceID(testResource.ID) testResource.Properties.Application = "/subscriptions/test-subscription/resourceGroups/test-resource-group/providers/Applications.Core/app/test-application" - cr := store.Object{ - Metadata: store.Metadata{ + cr := database.Object{ + Metadata: database.Metadata{ ID: testResource.ID, }, Data: testResource, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) _, err := dp.Render(ctx, resourceID, &testResource) require.Error(t, err) @@ -629,7 +629,7 @@ func Test_Render(t *testing.T) { t.Run("Missing output resource provider", func(t *testing.T) { mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() testRendererOutput := getTestRendererOutput() @@ -640,13 +640,13 @@ func Test_Render(t *testing.T) { mocks.renderer.EXPECT().Render(gomock.Any(), gomock.Any(), gomock.Any()).Times(1).Return(testRendererOutput, nil) mocks.renderer.EXPECT().GetDependencyIDs(gomock.Any(), gomock.Any()).Times(1).Return([]resources.ID{}, nil, nil) - cr := store.Object{ - Metadata: store.Metadata{ + cr := database.Object{ + Metadata: database.Metadata{ ID: testResource.ID, }, Data: testResource, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) application := datamodel.Application{ BaseResource: v1.BaseResource{ TrackedResource: v1.TrackedResource{ @@ -659,20 +659,20 @@ func Test_Render(t *testing.T) { }, }, } - ar := store.Object{ - Metadata: store.Metadata{ + ar := database.Object{ + Metadata: database.Metadata{ ID: application.ID, }, Data: application, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&ar, nil) - er := store.Object{ - Metadata: store.Metadata{ + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&ar, nil) + er := database.Object{ + Metadata: database.Metadata{ ID: env.ID, }, Data: env, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&er, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&er, nil) _, err := dp.Render(ctx, resourceID, &testResource) require.Error(t, err, "output resource \"Deployment\" does not have a provider specified") @@ -680,7 +680,7 @@ func Test_Render(t *testing.T) { t.Run("Unsupported output resource provider", func(t *testing.T) { mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() testRendererOutput := getTestRendererOutput() @@ -690,13 +690,13 @@ func Test_Render(t *testing.T) { mocks.renderer.EXPECT().GetDependencyIDs(gomock.Any(), gomock.Any()).Times(1).Return([]resources.ID{}, nil, nil) - cr := store.Object{ - Metadata: store.Metadata{ + cr := database.Object{ + Metadata: database.Metadata{ ID: testResource.ID, }, Data: testResource, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) application := datamodel.Application{ BaseResource: v1.BaseResource{ TrackedResource: v1.TrackedResource{ @@ -709,20 +709,20 @@ func Test_Render(t *testing.T) { }, }, } - ar := store.Object{ - Metadata: store.Metadata{ + ar := database.Object{ + Metadata: database.Metadata{ ID: application.ID, }, Data: application, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&ar, nil) - er := store.Object{ - Metadata: store.Metadata{ + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&ar, nil) + er := database.Object{ + Metadata: database.Metadata{ ID: env.ID, }, Data: env, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&er, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&er, nil) mocks.renderer.EXPECT().Render(gomock.Any(), gomock.Any(), gomock.Any()).Times(1).Return(testRendererOutput, nil) @@ -733,13 +733,13 @@ func Test_Render(t *testing.T) { func setupDeployMocks(mocks SharedMocks, simulated bool) { testResource := getTestResource() - cr := store.Object{ - Metadata: store.Metadata{ + cr := database.Object{ + Metadata: database.Metadata{ ID: testResource.ID, }, Data: testResource, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&cr, nil) app := datamodel.Application{ BaseResource: v1.BaseResource{ @@ -754,13 +754,13 @@ func setupDeployMocks(mocks SharedMocks, simulated bool) { }, } - ar := store.Object{ - Metadata: store.Metadata{ + ar := database.Object{ + Metadata: database.Metadata{ ID: mocks.testApp.ID, }, Data: app, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&ar, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&ar, nil) env := datamodel.Environment{ BaseResource: v1.BaseResource{ @@ -784,20 +784,20 @@ func setupDeployMocks(mocks SharedMocks, simulated bool) { env.Properties.Simulated = true } - er := store.Object{ - Metadata: store.Metadata{ + er := database.Object{ + Metadata: database.Metadata{ ID: mocks.testEnv.ID, }, Data: env, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&er, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&er, nil) } func Test_Deploy(t *testing.T) { t.Run("Verify deploy success", func(t *testing.T) { ctx := testcontext.New(t) mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() testRendererOutput := getTestRendererOutput() @@ -837,7 +837,7 @@ func Test_Deploy(t *testing.T) { t.Run("Verify deploy success with simulated env", func(t *testing.T) { ctx := testcontext.New(t) mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() testRendererOutput := getTestRendererOutput() @@ -855,7 +855,7 @@ func Test_Deploy(t *testing.T) { t.Run("Verify deploy failure", func(t *testing.T) { ctx := testcontext.New(t) mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() testRendererOutput := getTestRendererOutput() @@ -872,7 +872,7 @@ func Test_Deploy(t *testing.T) { t.Run("Output resource dependency missing local ID", func(t *testing.T) { ctx := testcontext.New(t) mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() testRendererOutput := getTestRendererOutput() @@ -890,7 +890,7 @@ func Test_Deploy(t *testing.T) { t.Run("Invalid output resource type", func(t *testing.T) { ctx := testcontext.New(t) mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() testRendererOutput := getTestRendererOutput() @@ -908,7 +908,7 @@ func Test_Deploy(t *testing.T) { t.Run("Missing output resource identity", func(t *testing.T) { ctx := testcontext.New(t) mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() testRendererOutput := getTestRendererOutput() @@ -934,7 +934,7 @@ func Test_Delete(t *testing.T) { t.Run("Verify delete success", func(t *testing.T) { ctx := testcontext.New(t) mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() resourceID := getTestResourceID(testResource.ID) @@ -948,7 +948,7 @@ func Test_Delete(t *testing.T) { t.Run("Verify delete failure", func(t *testing.T) { ctx := testcontext.New(t) mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() resourceID := getTestResourceID(testResource.ID) @@ -962,7 +962,7 @@ func Test_Delete(t *testing.T) { t.Run("Verify delete with no output resources", func(t *testing.T) { ctx := testcontext.New(t) mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} testResource := getTestResource() resourceID := getTestResourceID(testResource.ID) @@ -1037,20 +1037,20 @@ func Test_getEnvOptions_PublicEndpointOverride(t *testing.T) { func Test_getResourceDataByID(t *testing.T) { ctx := testcontext.New(t) mocks := setup(t) - dp := deploymentProcessor{mocks.model, mocks.storageClient, nil, nil} + dp := deploymentProcessor{mocks.model, mocks.databaseClient, nil, nil} t.Run("Get recipe data from connected mongoDB resources", func(t *testing.T) { depId, _ := resources.ParseResource("/subscriptions/test-subscription/resourceGroups/test-resource-group/providers/Applications.Datastores/mongoDatabases/test-mongo") mongoResource := buildMongoDBWithRecipe() mongoResource.PortableResourceMetadata.RecipeData = portableresources.RecipeData{} - mr := store.Object{ - Metadata: store.Metadata{ + mr := database.Object{ + Metadata: database.Metadata{ ID: mongoResource.ID, }, Data: mongoResource, } - mocks.storageClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&mr, nil) + mocks.databaseClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).Return(&mr, nil) resourceData, err := dp.getResourceDataByID(ctx, depId) require.NoError(t, err) diff --git a/pkg/corerp/frontend/controller/applications/getgraph_test.go b/pkg/corerp/frontend/controller/applications/getgraph_test.go index a7bf5752b4..d859cf5d31 100644 --- a/pkg/corerp/frontend/controller/applications/getgraph_test.go +++ b/pkg/corerp/frontend/controller/applications/getgraph_test.go @@ -25,7 +25,7 @@ import ( ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/sdk" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) @@ -34,7 +34,7 @@ func TestGetGraphRun_20231001Preview(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() - mStorageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) req, err := rpctest.NewHTTPRequestWithContent( context.Background(), v1.OperationPost.HTTPMethod(), @@ -43,13 +43,13 @@ func TestGetGraphRun_20231001Preview(t *testing.T) { require.NoError(t, err) t.Run("resource not found", func(t *testing.T) { - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - Return(nil, &store.ErrNotFound{}) + Return(nil, &database.ErrNotFound{}) ctx := rpctest.NewARMRequestContext(req) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } conn, err := sdk.NewDirectConnection("http://localhost:9000/apis/api.ucp.dev/v1alpha3") diff --git a/pkg/corerp/frontend/controller/applications/updatefilter.go b/pkg/corerp/frontend/controller/applications/updatefilter.go index 2c254f98aa..80efb97f37 100644 --- a/pkg/corerp/frontend/controller/applications/updatefilter.go +++ b/pkg/corerp/frontend/controller/applications/updatefilter.go @@ -63,7 +63,7 @@ func CreateAppScopedNamespace(ctx context.Context, newResource, oldResource *dat kubeNamespace = ext.KubernetesNamespace.Namespace } else { // Construct namespace using the namespace specified by environment resource. - envNamespace, err := rp_kube.FindNamespaceByEnvID(ctx, opt.StorageClient, newResource.Properties.Environment) + envNamespace, err := rp_kube.FindNamespaceByEnvID(ctx, opt.DatabaseClient, newResource.Properties.Environment) if err != nil { return rest.NewBadRequestResponse(fmt.Sprintf("Environment %s could not be constructed: %s", newResource.Properties.Environment, err.Error())), nil @@ -84,7 +84,7 @@ func CreateAppScopedNamespace(ctx context.Context, newResource, oldResource *dat return rest.NewBadRequestResponse(fmt.Sprintf("Environment %s for application %s could not be found", envID.Name(), serviceCtx.ResourceID.Name())), nil } - result, err := util.FindResources(ctx, envID.RootScope(), envID.Type(), envNamespaceQuery, kubeNamespace, opt.StorageClient) + result, err := util.FindResources(ctx, envID.RootScope(), envID.Type(), envNamespaceQuery, kubeNamespace, opt.DatabaseClient) if err != nil { return nil, err } @@ -93,7 +93,7 @@ func CreateAppScopedNamespace(ctx context.Context, newResource, oldResource *dat } // Check if another application resource is using namespace - result, err = util.FindResources(ctx, serviceCtx.ResourceID.RootScope(), serviceCtx.ResourceID.Type(), appNamespaceQuery, kubeNamespace, opt.StorageClient) + result, err = util.FindResources(ctx, serviceCtx.ResourceID.RootScope(), serviceCtx.ResourceID.Type(), appNamespaceQuery, kubeNamespace, opt.DatabaseClient) if err != nil { return nil, err } diff --git a/pkg/corerp/frontend/controller/applications/updatefilter_test.go b/pkg/corerp/frontend/controller/applications/updatefilter_test.go index 0e33bbc401..7145de92f7 100644 --- a/pkg/corerp/frontend/controller/applications/updatefilter_test.go +++ b/pkg/corerp/frontend/controller/applications/updatefilter_test.go @@ -26,8 +26,8 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/corerp/datamodel" rpv1 "github.com/radius-project/radius/pkg/rp/v1" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/test/k8sutil" v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" @@ -44,8 +44,8 @@ func TestCreateAppScopedNamespace_valid_namespace(t *testing.T) { tCtx := rpctest.NewControllerContext(t) opts := ctrl.Options{ - StorageClient: tCtx.MockSC, - KubeClient: k8sutil.NewFakeKubeClient(nil), + DatabaseClient: tCtx.MockSC, + KubeClient: k8sutil.NewFakeKubeClient(nil), } t.Run("override namespace", func(t *testing.T) { @@ -68,9 +68,9 @@ func TestCreateAppScopedNamespace_valid_namespace(t *testing.T) { tCtx.MockSC. EXPECT(). Query(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { - return &store.ObjectQueryResult{ - Items: []store.Object{}, + DoAndReturn(func(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { + return &database.ObjectQueryResult{ + Items: []database.Object{}, }, nil }).Times(2) @@ -104,9 +104,9 @@ func TestCreateAppScopedNamespace_valid_namespace(t *testing.T) { tCtx.MockSC. EXPECT(). Query(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { - return &store.ObjectQueryResult{ - Items: []store.Object{}, + DoAndReturn(func(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { + return &database.ObjectQueryResult{ + Items: []database.Object{}, }, nil }).Times(2) @@ -151,8 +151,8 @@ func TestCreateAppScopedNamespace_invalid_property(t *testing.T) { tCtx := rpctest.NewControllerContext(t) opts := ctrl.Options{ - StorageClient: tCtx.MockSC, - KubeClient: k8sutil.NewFakeKubeClient(nil), + DatabaseClient: tCtx.MockSC, + KubeClient: k8sutil.NewFakeKubeClient(nil), } t.Run("generated namespace is invalid", func(t *testing.T) { @@ -195,9 +195,9 @@ func TestCreateAppScopedNamespace_invalid_property(t *testing.T) { t.Run("invalid namespace", func(t *testing.T) { tCtx.MockSC.EXPECT(). Query(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { - return &store.ObjectQueryResult{ - Items: []store.Object{}, + DoAndReturn(func(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { + return &database.ObjectQueryResult{ + Items: []database.Object{}, }, nil }).Times(2) @@ -240,9 +240,9 @@ func TestCreateAppScopedNamespace_invalid_property(t *testing.T) { tCtx.MockSC.EXPECT(). Query(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { - return &store.ObjectQueryResult{ - Items: []store.Object{*rpctest.FakeStoreObject(envdm)}, + DoAndReturn(func(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { + return &database.ObjectQueryResult{ + Items: []database.Object{*rpctest.FakeStoreObject(envdm)}, }, nil }).Times(1) @@ -293,10 +293,10 @@ func TestCreateAppScopedNamespace_invalid_property(t *testing.T) { tCtx.MockSC.EXPECT(). Query(gomock.Any(), gomock.Any()). - Return(&store.ObjectQueryResult{}, nil).Times(1) + Return(&database.ObjectQueryResult{}, nil).Times(1) tCtx.MockSC.EXPECT(). Query(gomock.Any(), gomock.Any()). - Return(&store.ObjectQueryResult{Items: []store.Object{*rpctest.FakeStoreObject(newResource)}}, nil).Times(1) + Return(&database.ObjectQueryResult{Items: []database.Object{*rpctest.FakeStoreObject(newResource)}}, nil).Times(1) id, err := resources.ParseResource(testAppID) require.NoError(t, err) @@ -347,7 +347,7 @@ func TestCreateAppScopedNamespace_invalid_property(t *testing.T) { tCtx.MockSC.EXPECT(). Query(gomock.Any(), gomock.Any()). - Return(&store.ObjectQueryResult{}, nil).Times(2) + Return(&database.ObjectQueryResult{}, nil).Times(2) id, err := resources.ParseResource(testAppID) require.NoError(t, err) diff --git a/pkg/corerp/frontend/controller/environments/createorupdateenvironment.go b/pkg/corerp/frontend/controller/environments/createorupdateenvironment.go index c011b2675d..4c291ca8ed 100644 --- a/pkg/corerp/frontend/controller/environments/createorupdateenvironment.go +++ b/pkg/corerp/frontend/controller/environments/createorupdateenvironment.go @@ -71,7 +71,7 @@ func (e *CreateOrUpdateEnvironment) Run(ctx context.Context, w http.ResponseWrit // Create Query filter to query kubernetes namespace used by the other environment resources. namespace := newResource.Properties.Compute.KubernetesCompute.Namespace - result, err := util.FindResources(ctx, serviceCtx.ResourceID.RootScope(), serviceCtx.ResourceID.Type(), "properties.compute.kubernetes.namespace", namespace, e.StorageClient()) + result, err := util.FindResources(ctx, serviceCtx.ResourceID.RootScope(), serviceCtx.ResourceID.Type(), "properties.compute.kubernetes.namespace", namespace, e.DatabaseClient()) if err != nil { return nil, err } diff --git a/pkg/corerp/frontend/controller/environments/createorupdateenvironment_test.go b/pkg/corerp/frontend/controller/environments/createorupdateenvironment_test.go index 3854012b2f..13e12d07ce 100644 --- a/pkg/corerp/frontend/controller/environments/createorupdateenvironment_test.go +++ b/pkg/corerp/frontend/controller/environments/createorupdateenvironment_test.go @@ -27,7 +27,7 @@ import ( ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/corerp/api/v20231001preview" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/google/uuid" "github.com/stretchr/testify/require" @@ -38,7 +38,7 @@ func TestCreateOrUpdateEnvironmentRun_20231001Preview(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() - mStorageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) ctx := context.Background() createNewResourceCases := []struct { @@ -64,20 +64,20 @@ func TestCreateOrUpdateEnvironmentRun_20231001Preview(t *testing.T) { req.Header.Set(tt.headerKey, tt.headerValue) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }) if !tt.shouldFail { - mStorageClient. + databaseClient. EXPECT(). Query(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { - return &store.ObjectQueryResult{ - Items: []store.Object{}, + DoAndReturn(func(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { + return &database.ObjectQueryResult{ + Items: []database.Object{}, }, nil }) } @@ -87,10 +87,10 @@ func TestCreateOrUpdateEnvironmentRun_20231001Preview(t *testing.T) { expectedOutput.SystemData.CreatedByType = expectedOutput.SystemData.LastModifiedByType if !tt.shouldFail { - mStorageClient. + databaseClient. EXPECT(). Save(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, obj *store.Object, opts ...store.SaveOptions) error { + DoAndReturn(func(ctx context.Context, obj *database.Object, opts ...database.SaveOptions) error { obj.ETag = "new-resource-etag" obj.Data = envDataModel return nil @@ -98,7 +98,7 @@ func TestCreateOrUpdateEnvironmentRun_20231001Preview(t *testing.T) { } opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewCreateOrUpdateEnvironment(opts) @@ -142,32 +142,32 @@ func TestCreateOrUpdateEnvironmentRun_20231001Preview(t *testing.T) { req.Header.Set(tt.headerKey, tt.headerValue) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id, ETag: tt.resourceETag}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id, ETag: tt.resourceETag}, Data: envDataModel, }, nil }) if !tt.shouldFail { - mStorageClient. + databaseClient. EXPECT(). Query(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { - return &store.ObjectQueryResult{ - Items: []store.Object{}, + DoAndReturn(func(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { + return &database.ObjectQueryResult{ + Items: []database.Object{}, }, nil }) } if !tt.shouldFail { - mStorageClient. + databaseClient. EXPECT(). Save(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, obj *store.Object, opts ...store.SaveOptions) error { + DoAndReturn(func(ctx context.Context, obj *database.Object, opts ...database.SaveOptions) error { obj.ETag = "updated-resource-etag" obj.Data = envDataModel return nil @@ -175,7 +175,7 @@ func TestCreateOrUpdateEnvironmentRun_20231001Preview(t *testing.T) { } opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewCreateOrUpdateEnvironment(opts) @@ -219,26 +219,26 @@ func TestCreateOrUpdateEnvironmentRun_20231001Preview(t *testing.T) { req.Header.Set(tt.headerKey, tt.headerValue) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }) if !tt.shouldFail { - mStorageClient. + databaseClient. EXPECT(). Query(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { - return &store.ObjectQueryResult{ - Items: []store.Object{}, + DoAndReturn(func(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { + return &database.ObjectQueryResult{ + Items: []database.Object{}, }, nil }) } opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewCreateOrUpdateEnvironment(opts) @@ -273,33 +273,33 @@ func TestCreateOrUpdateEnvironmentRun_20231001Preview(t *testing.T) { req.Header.Set(tt.headerKey, tt.headerValue) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id, ETag: tt.resourceEtag}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id, ETag: tt.resourceEtag}, Data: envDataModel, }, nil }) if !tt.shouldFail { - mStorageClient. + databaseClient. EXPECT(). Query(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { - return &store.ObjectQueryResult{ - Items: []store.Object{}, + DoAndReturn(func(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { + return &database.ObjectQueryResult{ + Items: []database.Object{}, }, nil }) } if !tt.shouldFail { - mStorageClient. + databaseClient. EXPECT(). Save(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, obj *store.Object, opts ...store.SaveOptions) error { - cfg := store.NewSaveConfig(opts...) + DoAndReturn(func(ctx context.Context, obj *database.Object, opts ...database.SaveOptions) error { + cfg := database.NewSaveConfig(opts...) obj.ETag = cfg.ETag obj.Data = envDataModel return nil @@ -307,7 +307,7 @@ func TestCreateOrUpdateEnvironmentRun_20231001Preview(t *testing.T) { } opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewCreateOrUpdateEnvironment(opts) @@ -352,43 +352,43 @@ func TestCreateOrUpdateEnvironmentRun_20231001Preview(t *testing.T) { req.Header.Set(tt.headerKey, tt.headerValue) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id, ETag: tt.resourceEtag}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id, ETag: tt.resourceEtag}, Data: envDataModel, }, nil }) paginationToken := "nextLink" - items := []store.Object{ + items := []database.Object{ { - Metadata: store.Metadata{ + Metadata: database.Metadata{ ID: uuid.New().String(), }, Data: conflictDataModel, }, } - mStorageClient. + databaseClient. EXPECT(). Query(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { - return &store.ObjectQueryResult{ + DoAndReturn(func(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { + return &database.ObjectQueryResult{ Items: items, PaginationToken: paginationToken, }, nil }) if !tt.shouldFail { - mStorageClient. + databaseClient. EXPECT(). Save(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, obj *store.Object, opts ...store.SaveOptions) error { - cfg := store.NewSaveConfig(opts...) + DoAndReturn(func(ctx context.Context, obj *database.Object, opts ...database.SaveOptions) error { + cfg := database.NewSaveConfig(opts...) obj.ETag = cfg.ETag obj.Data = envDataModel return nil @@ -396,7 +396,7 @@ func TestCreateOrUpdateEnvironmentRun_20231001Preview(t *testing.T) { } opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewCreateOrUpdateEnvironment(opts) diff --git a/pkg/corerp/frontend/controller/environments/getrecipemetadata_test.go b/pkg/corerp/frontend/controller/environments/getrecipemetadata_test.go index ae08874f91..4d33f65af7 100644 --- a/pkg/corerp/frontend/controller/environments/getrecipemetadata_test.go +++ b/pkg/corerp/frontend/controller/environments/getrecipemetadata_test.go @@ -30,7 +30,7 @@ import ( "github.com/radius-project/radius/pkg/corerp/api/v20231001preview" "github.com/radius-project/radius/pkg/recipes" "github.com/radius-project/radius/pkg/recipes/engine" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/test/testutil" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -39,7 +39,7 @@ import ( func TestGetRecipeMetadataRun_20231001Preview(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() - mStorageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) mEngine := engine.NewMockEngine(mctrl) ctx := context.Background() t.Parallel() @@ -49,12 +49,12 @@ func TestGetRecipeMetadataRun_20231001Preview(t *testing.T) { req, err := rpctest.NewHTTPRequestFromJSON(ctx, v1.OperationPost.HTTPMethod(), testHeaderfilegetrecipemetadata, envInput) require.NoError(t, err) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id, ETag: "etag"}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id, ETag: "etag"}, Data: envDataModel, }, nil }) @@ -84,7 +84,7 @@ func TestGetRecipeMetadataRun_20231001Preview(t *testing.T) { }).Return(recipeData, nil) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewGetRecipeMetadata(opts, mEngine) require.NoError(t, err) @@ -104,12 +104,12 @@ func TestGetRecipeMetadataRun_20231001Preview(t *testing.T) { req, err := rpctest.NewHTTPRequestFromJSON(ctx, v1.OperationPost.HTTPMethod(), testHeaderfilegetrecipemetadata, envInput) require.NoError(t, err) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id, ETag: "etag"}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id, ETag: "etag"}, Data: envDataModel, }, nil }) @@ -139,7 +139,7 @@ func TestGetRecipeMetadataRun_20231001Preview(t *testing.T) { }).Return(recipeData, nil) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewGetRecipeMetadata(opts, mEngine) require.NoError(t, err) @@ -159,14 +159,14 @@ func TestGetRecipeMetadataRun_20231001Preview(t *testing.T) { require.NoError(t, err) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewGetRecipeMetadata(opts, mEngine) require.NoError(t, err) @@ -196,18 +196,18 @@ func TestGetRecipeMetadataRun_20231001Preview(t *testing.T) { require.NoError(t, err) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id, ETag: "etag"}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id, ETag: "etag"}, Data: envDataModel, }, nil }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewGetRecipeMetadata(opts, mEngine) require.NoError(t, err) @@ -235,12 +235,12 @@ func TestGetRecipeMetadataRun_20231001Preview(t *testing.T) { req, err := rpctest.NewHTTPRequestFromJSON(ctx, v1.OperationPost.HTTPMethod(), testHeaderfilegetrecipemetadata, envInput) require.NoError(t, err) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id, ETag: "etag"}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id, ETag: "etag"}, Data: envDataModel, }, nil }) @@ -264,7 +264,7 @@ func TestGetRecipeMetadataRun_20231001Preview(t *testing.T) { }).Return(nil, engineErr) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewGetRecipeMetadata(opts, mEngine) require.NoError(t, err) diff --git a/pkg/corerp/frontend/controller/extenders/listsecretsextender_test.go b/pkg/corerp/frontend/controller/extenders/listsecretsextender_test.go index bb8ccdfcb5..8dfd721f9a 100644 --- a/pkg/corerp/frontend/controller/extenders/listsecretsextender_test.go +++ b/pkg/corerp/frontend/controller/extenders/listsecretsextender_test.go @@ -27,16 +27,16 @@ import ( "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rpctest" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) func TestListSecrets_20231001Preview(t *testing.T) { - setupTest := func() (func(tb testing.TB), *store.MockStorageClient, *statusmanager.MockStatusManager) { + setupTest := func() (func(tb testing.TB), *database.MockClient, *statusmanager.MockStatusManager) { mctrl := gomock.NewController(t) - mds := store.NewMockStorageClient(mctrl) + mds := database.NewMockClient(mctrl) msm := statusmanager.NewMockStatusManager(mctrl) return func(tb testing.TB) { @@ -62,13 +62,13 @@ func TestListSecrets_20231001Preview(t *testing.T) { mds. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }) opts := ctrl.Options{ - StorageClient: mds, - StatusManager: msm, + DatabaseClient: mds, + StatusManager: msm, } ctl, err := NewListSecretsExtender(opts) @@ -91,16 +91,16 @@ func TestListSecrets_20231001Preview(t *testing.T) { mds. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id}, Data: extenderDataModel, }, nil }) opts := ctrl.Options{ - StorageClient: mds, - StatusManager: msm, + DatabaseClient: mds, + StatusManager: msm, } ctl, err := NewListSecretsExtender(opts) @@ -129,13 +129,13 @@ func TestListSecrets_20231001Preview(t *testing.T) { mds. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { return nil, errors.New("failed to get the resource from data store") }) opts := ctrl.Options{ - StorageClient: mds, - StatusManager: msm, + DatabaseClient: mds, + StatusManager: msm, } ctl, err := NewListSecretsExtender(opts) diff --git a/pkg/corerp/frontend/controller/secretstores/kubernetes.go b/pkg/corerp/frontend/controller/secretstores/kubernetes.go index 62296b5ec6..a5b8448e46 100644 --- a/pkg/corerp/frontend/controller/secretstores/kubernetes.go +++ b/pkg/corerp/frontend/controller/secretstores/kubernetes.go @@ -30,9 +30,9 @@ import ( "github.com/radius-project/radius/pkg/kubeutil" rpv1 "github.com/radius-project/radius/pkg/rp/v1" "github.com/radius-project/radius/pkg/to" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/resources" resources_kubernetes "github.com/radius-project/radius/pkg/ucp/resources/kubernetes" - "github.com/radius-project/radius/pkg/ucp/store" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -141,7 +141,7 @@ func ValidateAndMutateRequest(ctx context.Context, newResource *datamodel.Secret func getNamespace(ctx context.Context, res *datamodel.SecretStore, options *controller.Options) (string, error) { prop := res.Properties if prop.Application != "" { - app, err := store.GetResource[datamodel.Application](ctx, options.StorageClient, prop.Application) + app, err := database.GetResource[datamodel.Application](ctx, options.DatabaseClient, prop.Application) if err != nil { return "", err } @@ -152,7 +152,7 @@ func getNamespace(ctx context.Context, res *datamodel.SecretStore, options *cont } if prop.Environment != "" { - env, err := store.GetResource[datamodel.Environment](ctx, options.StorageClient, prop.Environment) + env, err := database.GetResource[datamodel.Environment](ctx, options.DatabaseClient, prop.Environment) if err != nil { return "", err } diff --git a/pkg/corerp/frontend/controller/secretstores/kubernetes_test.go b/pkg/corerp/frontend/controller/secretstores/kubernetes_test.go index 676107a91b..6ead89f9fc 100644 --- a/pkg/corerp/frontend/controller/secretstores/kubernetes_test.go +++ b/pkg/corerp/frontend/controller/secretstores/kubernetes_test.go @@ -27,8 +27,8 @@ import ( "github.com/radius-project/radius/pkg/corerp/datamodel" "github.com/radius-project/radius/pkg/kubernetes" rpv1 "github.com/radius-project/radius/pkg/rp/v1" + "github.com/radius-project/radius/pkg/ucp/database" resources_kubernetes "github.com/radius-project/radius/pkg/ucp/resources/kubernetes" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/test/k8sutil" "github.com/radius-project/radius/test/testutil" "github.com/stretchr/testify/require" @@ -60,10 +60,10 @@ const ( func TestGetNamespace(t *testing.T) { ctrl := gomock.NewController(t) - sc := store.NewMockStorageClient(ctrl) + sc := database.NewMockClient(ctrl) opt := &controller.Options{ - StorageClient: sc, + DatabaseClient: sc, } t.Run("application-scoped", func(t *testing.T) { @@ -71,7 +71,7 @@ func TestGetNamespace(t *testing.T) { secret.Properties.Application = testAppID appData := testutil.MustGetTestData[any]("app_datamodel.json") - sc.EXPECT().Get(gomock.Any(), testAppID, gomock.Any()).Return(&store.Object{ + sc.EXPECT().Get(gomock.Any(), testAppID, gomock.Any()).Return(&database.Object{ Data: *appData, }, nil) @@ -88,7 +88,7 @@ func TestGetNamespace(t *testing.T) { envData := testutil.MustGetTestData[any]("env_datamodel.json") - sc.EXPECT().Get(gomock.Any(), testEnvID, gomock.Any()).Return(&store.Object{ + sc.EXPECT().Get(gomock.Any(), testEnvID, gomock.Any()).Return(&database.Object{ Data: *envData, }, nil) @@ -103,7 +103,7 @@ func TestGetNamespace(t *testing.T) { secret.Properties.Environment = testEnvID envData := testutil.MustGetTestData[any]("env_nonk8s_datamodel.json") - sc.EXPECT().Get(gomock.Any(), testEnvID, gomock.Any()).Return(&store.Object{ + sc.EXPECT().Get(gomock.Any(), testEnvID, gomock.Any()).Return(&database.Object{ Data: *envData, }, nil) @@ -429,11 +429,11 @@ func TestUpsertSecret(t *testing.T) { t.Run("create new generic resource", func(t *testing.T) { ctrl := gomock.NewController(t) - sc := store.NewMockStorageClient(ctrl) + sc := database.NewMockClient(ctrl) appData := testutil.MustGetTestData[any]("app_datamodel.json") - sc.EXPECT().Get(gomock.Any(), testAppID, gomock.Any()).Return(&store.Object{ + sc.EXPECT().Get(gomock.Any(), testAppID, gomock.Any()).Return(&database.Object{ Data: *appData, }, nil) @@ -441,8 +441,8 @@ func TestUpsertSecret(t *testing.T) { newResource.Properties.Resource = "" opt := &controller.Options{ - StorageClient: sc, - KubeClient: k8sutil.NewFakeKubeClient(nil), + DatabaseClient: sc, + KubeClient: k8sutil.NewFakeKubeClient(nil), } _, err := ValidateAndMutateRequest(context.TODO(), newResource, nil, opt) @@ -473,11 +473,11 @@ func TestUpsertSecret(t *testing.T) { t.Run("create new resource when namespace is missing", func(t *testing.T) { ctrl := gomock.NewController(t) - sc := store.NewMockStorageClient(ctrl) + sc := database.NewMockClient(ctrl) appData := testutil.MustGetTestData[any]("app_datamodel.json") - sc.EXPECT().Get(gomock.Any(), testAppID, gomock.Any()).Return(&store.Object{ + sc.EXPECT().Get(gomock.Any(), testAppID, gomock.Any()).Return(&database.Object{ Data: *appData, }, nil) @@ -487,8 +487,8 @@ func TestUpsertSecret(t *testing.T) { newResource.Properties.Resource = "secret0" opt := &controller.Options{ - StorageClient: sc, - KubeClient: k8sutil.NewFakeKubeClient(nil), + DatabaseClient: sc, + KubeClient: k8sutil.NewFakeKubeClient(nil), } _, err := ValidateAndMutateRequest(context.TODO(), newResource, nil, opt) @@ -502,11 +502,11 @@ func TestUpsertSecret(t *testing.T) { t.Run("unmatched resource when namespace is missing in new resource", func(t *testing.T) { ctrl := gomock.NewController(t) - sc := store.NewMockStorageClient(ctrl) + sc := database.NewMockClient(ctrl) appData := testutil.MustGetTestData[any]("app_datamodel.json") - sc.EXPECT().Get(gomock.Any(), testAppID, gomock.Any()).Return(&store.Object{ + sc.EXPECT().Get(gomock.Any(), testAppID, gomock.Any()).Return(&database.Object{ Data: *appData, }, nil) @@ -516,8 +516,8 @@ func TestUpsertSecret(t *testing.T) { newResource.Properties.Resource = "secret1" opt := &controller.Options{ - StorageClient: sc, - KubeClient: k8sutil.NewFakeKubeClient(nil), + DatabaseClient: sc, + KubeClient: k8sutil.NewFakeKubeClient(nil), } _, err := ValidateAndMutateRequest(context.TODO(), newResource, nil, opt) @@ -532,13 +532,13 @@ func TestUpsertSecret(t *testing.T) { t.Run("create a new secret resource with global scope", func(t *testing.T) { ctrl := gomock.NewController(t) - sc := store.NewMockStorageClient(ctrl) + sc := database.NewMockClient(ctrl) newResource := testutil.MustGetTestData[datamodel.SecretStore](testFileGenericValueGlobalScope) opt := &controller.Options{ - StorageClient: sc, - KubeClient: k8sutil.NewFakeKubeClient(nil), + DatabaseClient: sc, + KubeClient: k8sutil.NewFakeKubeClient(nil), } _, err := ValidateAndMutateRequest(context.TODO(), newResource, nil, opt) @@ -569,13 +569,13 @@ func TestUpsertSecret(t *testing.T) { t.Run("create a new secret resource with invalid resource", func(t *testing.T) { ctrl := gomock.NewController(t) - sc := store.NewMockStorageClient(ctrl) + sc := database.NewMockClient(ctrl) newResource := testutil.MustGetTestData[datamodel.SecretStore](testFileGenericValueInvalidResource) opt := &controller.Options{ - StorageClient: sc, - KubeClient: k8sutil.NewFakeKubeClient(nil), + DatabaseClient: sc, + KubeClient: k8sutil.NewFakeKubeClient(nil), } _, err := ValidateAndMutateRequest(context.TODO(), newResource, nil, opt) @@ -587,13 +587,13 @@ func TestUpsertSecret(t *testing.T) { t.Run("create a new secret resource with empty resource", func(t *testing.T) { ctrl := gomock.NewController(t) - sc := store.NewMockStorageClient(ctrl) + sc := database.NewMockClient(ctrl) newResource := testutil.MustGetTestData[datamodel.SecretStore](testFileGenericValueEmptyResource) opt := &controller.Options{ - StorageClient: sc, - KubeClient: k8sutil.NewFakeKubeClient(nil), + DatabaseClient: sc, + KubeClient: k8sutil.NewFakeKubeClient(nil), } _, err := ValidateAndMutateRequest(context.TODO(), newResource, nil, opt) diff --git a/pkg/corerp/frontend/controller/secretstores/listsecrets_test.go b/pkg/corerp/frontend/controller/secretstores/listsecrets_test.go index 99b7770afa..df1551d4d4 100644 --- a/pkg/corerp/frontend/controller/secretstores/listsecrets_test.go +++ b/pkg/corerp/frontend/controller/secretstores/listsecrets_test.go @@ -28,7 +28,7 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/corerp/api/v20231001preview" "github.com/radius-project/radius/pkg/corerp/datamodel" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/test/k8sutil" "github.com/radius-project/radius/test/testutil" "github.com/stretchr/testify/require" @@ -41,7 +41,7 @@ func TestListSecrets_20231001Preview(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() - mStorageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) req, err := rpctest.NewHTTPRequestWithContent( context.Background(), v1.OperationPost.HTTPMethod(), @@ -49,13 +49,13 @@ func TestListSecrets_20231001Preview(t *testing.T) { require.NoError(t, err) t.Run("not found the resource", func(t *testing.T) { - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - Return(nil, &store.ErrNotFound{}) + Return(nil, &database.ErrNotFound{}) ctx := rpctest.NewARMRequestContext(req) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecrets(opts) @@ -71,12 +71,12 @@ func TestListSecrets_20231001Preview(t *testing.T) { t.Run("return secrets successfully", func(t *testing.T) { secretdm := testutil.MustGetTestData[datamodel.SecretStore](testFileCertValueFrom) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id, ETag: "etag"}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id, ETag: "etag"}, Data: secretdm, }, nil }) @@ -92,8 +92,8 @@ func TestListSecrets_20231001Preview(t *testing.T) { }, } opts := ctrl.Options{ - StorageClient: mStorageClient, - KubeClient: k8sutil.NewFakeKubeClient(nil, ksecret), + DatabaseClient: databaseClient, + KubeClient: k8sutil.NewFakeKubeClient(nil, ksecret), } ctl, err := NewListSecrets(opts) @@ -115,7 +115,7 @@ func TestListSecrets_InvalidKubernetesSecret(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() - mStorageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) req, err := rpctest.NewHTTPRequestWithContent( context.Background(), v1.OperationPost.HTTPMethod(), @@ -172,19 +172,19 @@ func TestListSecrets_InvalidKubernetesSecret(t *testing.T) { for _, tc := range kubeSecretTests { t.Run(tc.name, func(t *testing.T) { - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id, ETag: "etag"}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id, ETag: "etag"}, Data: secretdm, }, nil }) ctx := rpctest.NewARMRequestContext(req) opts := ctrl.Options{ - StorageClient: mStorageClient, - KubeClient: k8sutil.NewFakeKubeClient(nil, tc.in), + DatabaseClient: databaseClient, + KubeClient: k8sutil.NewFakeKubeClient(nil, tc.in), } ctl, err := NewListSecrets(opts) diff --git a/pkg/corerp/frontend/controller/util/query.go b/pkg/corerp/frontend/controller/util/query.go index a6a8c76f94..1ed1209bab 100644 --- a/pkg/corerp/frontend/controller/util/query.go +++ b/pkg/corerp/frontend/controller/util/query.go @@ -19,20 +19,20 @@ package util import ( "context" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" ) // FindResources searches for resources of a given type with a given filter key and value, and returns the query result. -func FindResources(ctx context.Context, rootScope, resourceType, filterKey, filterValue string, storageClient store.StorageClient) (*store.ObjectQueryResult, error) { - query := store.Query{ +func FindResources(ctx context.Context, rootScope, resourceType, filterKey, filterValue string, databaseClient database.Client) (*database.ObjectQueryResult, error) { + query := database.Query{ RootScope: rootScope, ResourceType: resourceType, - Filters: []store.QueryFilter{ + Filters: []database.QueryFilter{ { Field: filterKey, Value: filterValue, }, }, } - return storageClient.Query(ctx, query) + return databaseClient.Query(ctx, query) } diff --git a/pkg/corerp/setup/setup_test.go b/pkg/corerp/setup/setup_test.go index 203ef7681a..fa970df43f 100644 --- a/pkg/corerp/setup/setup_test.go +++ b/pkg/corerp/setup/setup_test.go @@ -32,7 +32,7 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/recipes/controllerconfig" "github.com/radius-project/radius/pkg/sdk" - "github.com/radius-project/radius/pkg/ucp/store/inmemory" + "github.com/radius-project/radius/pkg/ucp/database/inmemory" app_ctrl "github.com/radius-project/radius/pkg/corerp/frontend/controller/applications" ctr_ctrl "github.com/radius-project/radius/pkg/corerp/frontend/controller/containers" @@ -225,10 +225,10 @@ func TestRouter(t *testing.T) { require.NoError(t, err) options := apictrl.Options{ - Address: "localhost:9000", - PathBase: "/api.ucp.dev", - StorageClient: inmemory.NewClient(), - StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), + Address: "localhost:9000", + PathBase: "/api.ucp.dev", + DatabaseClient: inmemory.NewClient(), + StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), } return r, nsBuilder.ApplyAPIHandlers(ctx, r, options, validator) diff --git a/pkg/daprrp/setup/setup_test.go b/pkg/daprrp/setup/setup_test.go index b55cd010d6..d12e79dee4 100644 --- a/pkg/daprrp/setup/setup_test.go +++ b/pkg/daprrp/setup/setup_test.go @@ -32,7 +32,7 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rpctest" dapr_ctrl "github.com/radius-project/radius/pkg/daprrp/frontend/controller" "github.com/radius-project/radius/pkg/recipes/controllerconfig" - "github.com/radius-project/radius/pkg/ucp/store/inmemory" + "github.com/radius-project/radius/pkg/ucp/database/inmemory" ) var handlerTests = []rpctest.HandlerTestSpec{ @@ -147,10 +147,10 @@ func TestRouter(t *testing.T) { require.NoError(t, err) options := apictrl.Options{ - Address: "localhost:9000", - PathBase: "/api.ucp.dev", - StorageClient: inmemory.NewClient(), - StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), + Address: "localhost:9000", + PathBase: "/api.ucp.dev", + DatabaseClient: inmemory.NewClient(), + StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), } return r, nsBuilder.ApplyAPIHandlers(ctx, r, options, validator) diff --git a/pkg/datastoresrp/frontend/controller/mongodatabases/listsecretsmongodatabase_test.go b/pkg/datastoresrp/frontend/controller/mongodatabases/listsecretsmongodatabase_test.go index c339139442..938b08d255 100644 --- a/pkg/datastoresrp/frontend/controller/mongodatabases/listsecretsmongodatabase_test.go +++ b/pkg/datastoresrp/frontend/controller/mongodatabases/listsecretsmongodatabase_test.go @@ -29,7 +29,7 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/datastoresrp/api/v20231001preview" "github.com/radius-project/radius/pkg/portableresources/renderers" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -39,7 +39,7 @@ func TestListSecrets_20231001Preview(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() - mStorageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) ctx := context.Background() _, mongoDataModel, _ := getTestModels20231001preview() @@ -50,15 +50,15 @@ func TestListSecrets_20231001Preview(t *testing.T) { require.NoError(t, err) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsMongoDatabase(opts) @@ -82,18 +82,18 @@ func TestListSecrets_20231001Preview(t *testing.T) { renderers.ConnectionStringValue: "mongodb://testUser:testPassword@testAccount1.mongo.cosmos.azure.com:10255", } - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id}, Data: mongoDataModel, }, nil }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsMongoDatabase(opts) @@ -122,18 +122,18 @@ func TestListSecrets_20231001Preview(t *testing.T) { renderers.ConnectionStringValue: "mongodb://testUser:testPassword@testAccount1.mongo.cosmos.azure.com:10255", } - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id}, Data: mongoDataModel, }, nil }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsMongoDatabase(opts) @@ -157,15 +157,15 @@ func TestListSecrets_20231001Preview(t *testing.T) { ctx := rpctest.NewARMRequestContext(req) w := httptest.NewRecorder() - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { return nil, errors.New("failed to get the resource from data store") }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsMongoDatabase(opts) @@ -183,18 +183,18 @@ func TestListSecrets_20231001Preview(t *testing.T) { sCtx := v1.ARMRequestContextFromContext(ctx) sCtx.APIVersion = "invalid-api-version" - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id}, Data: mongoDataModel, }, nil }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsMongoDatabase(opts) diff --git a/pkg/datastoresrp/frontend/controller/rediscaches/listsecretsrediscache.go b/pkg/datastoresrp/frontend/controller/rediscaches/listsecretsrediscache.go index 69e17a838d..89cd7a91ec 100644 --- a/pkg/datastoresrp/frontend/controller/rediscaches/listsecretsrediscache.go +++ b/pkg/datastoresrp/frontend/controller/rediscaches/listsecretsrediscache.go @@ -27,7 +27,7 @@ import ( "github.com/radius-project/radius/pkg/datastoresrp/datamodel" "github.com/radius-project/radius/pkg/datastoresrp/datamodel/converter" "github.com/radius-project/radius/pkg/portableresources/renderers" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" ) var _ ctrl.Controller = (*ListSecretsRedisCache)(nil) @@ -57,7 +57,7 @@ func (ctrl *ListSecretsRedisCache) Run(ctx context.Context, w http.ResponseWrite parsedResourceID := sCtx.ResourceID.Truncate() resource, _, err := ctrl.GetResource(ctx, parsedResourceID) if err != nil { - if errors.Is(&store.ErrNotFound{ID: parsedResourceID.String()}, err) { + if errors.Is(&database.ErrNotFound{ID: parsedResourceID.String()}, err) { return rest.NewNotFoundResponse(sCtx.ResourceID), nil } return nil, err diff --git a/pkg/datastoresrp/frontend/controller/rediscaches/listsecretsrediscache_test.go b/pkg/datastoresrp/frontend/controller/rediscaches/listsecretsrediscache_test.go index ffe90e4421..903baac905 100644 --- a/pkg/datastoresrp/frontend/controller/rediscaches/listsecretsrediscache_test.go +++ b/pkg/datastoresrp/frontend/controller/rediscaches/listsecretsrediscache_test.go @@ -29,7 +29,7 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/datastoresrp/api/v20231001preview" "github.com/radius-project/radius/pkg/portableresources/renderers" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -39,7 +39,7 @@ func TestListSecrets_20231001Preview(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() - mStorageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) ctx := context.Background() _, redisDataModel, _ := getTestModels20231001preview() @@ -50,15 +50,15 @@ func TestListSecrets_20231001Preview(t *testing.T) { require.NoError(t, err) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsRedisCache(opts) require.NoError(t, err) @@ -81,18 +81,18 @@ func TestListSecrets_20231001Preview(t *testing.T) { renderers.ConnectionStringValue: "test-connection-string", } - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id}, Data: redisDataModel, }, nil }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsRedisCache(opts) @@ -120,18 +120,18 @@ func TestListSecrets_20231001Preview(t *testing.T) { renderers.PasswordStringHolder: "testPassword", } - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id}, Data: redisDataModel, }, nil }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsRedisCache(opts) @@ -155,15 +155,15 @@ func TestListSecrets_20231001Preview(t *testing.T) { ctx := rpctest.NewARMRequestContext(req) w := httptest.NewRecorder() - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { return nil, errors.New("failed to get the resource from data store") }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsRedisCache(opts) @@ -181,18 +181,18 @@ func TestListSecrets_20231001Preview(t *testing.T) { sCtx := v1.ARMRequestContextFromContext(ctx) sCtx.APIVersion = "invalid-api-version" - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id}, Data: redisDataModel, }, nil }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsRedisCache(opts) diff --git a/pkg/datastoresrp/frontend/controller/sqldatabases/listsecretssqldatabase_test.go b/pkg/datastoresrp/frontend/controller/sqldatabases/listsecretssqldatabase_test.go index d43e6fb9eb..cdd3e8bfeb 100644 --- a/pkg/datastoresrp/frontend/controller/sqldatabases/listsecretssqldatabase_test.go +++ b/pkg/datastoresrp/frontend/controller/sqldatabases/listsecretssqldatabase_test.go @@ -28,7 +28,7 @@ import ( ctrl "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/datastoresrp/api/v20231001preview" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -43,7 +43,7 @@ func TestListSecrets_20231001Preview(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() - mStorageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) ctx := context.Background() _, sqlDataModel, _ := getTestModels20231001preview() @@ -54,15 +54,15 @@ func TestListSecrets_20231001Preview(t *testing.T) { require.NoError(t, err) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsSqlDatabase(opts) @@ -84,18 +84,18 @@ func TestListSecrets_20231001Preview(t *testing.T) { connectionStringValue: "Data Source=tcp:testAccount1.sql.cosmos.azure.com,1433;Initial Catalog=testDatabase;User Id=testUser;Password=testPassword;Encrypt=True;TrustServerCertificate=True", } - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id}, Data: sqlDataModel, }, nil }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsSqlDatabase(opts) @@ -122,18 +122,18 @@ func TestListSecrets_20231001Preview(t *testing.T) { connectionStringValue: "Data Source=tcp:testAccount1.sql.cosmos.azure.com,1433;Initial Catalog=testDatabase;User Id=testUser;Password=testPassword;Encrypt=True;TrustServerCertificate=True", } - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id}, Data: sqlDataModel, }, nil }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsSqlDatabase(opts) @@ -156,15 +156,15 @@ func TestListSecrets_20231001Preview(t *testing.T) { ctx := rpctest.NewARMRequestContext(req) w := httptest.NewRecorder() - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { return nil, errors.New("failed to get the resource from data store") }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsSqlDatabase(opts) @@ -182,18 +182,18 @@ func TestListSecrets_20231001Preview(t *testing.T) { sCtx := v1.ARMRequestContextFromContext(ctx) sCtx.APIVersion = "invalid-api-version" - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id}, Data: sqlDataModel, }, nil }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsSqlDatabase(opts) diff --git a/pkg/datastoresrp/setup/setup_test.go b/pkg/datastoresrp/setup/setup_test.go index d834cc6fbe..918e98e79e 100644 --- a/pkg/datastoresrp/setup/setup_test.go +++ b/pkg/datastoresrp/setup/setup_test.go @@ -32,7 +32,7 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rpctest" ds_ctrl "github.com/radius-project/radius/pkg/datastoresrp/frontend/controller" "github.com/radius-project/radius/pkg/recipes/controllerconfig" - "github.com/radius-project/radius/pkg/ucp/store/inmemory" + "github.com/radius-project/radius/pkg/ucp/database/inmemory" ) var handlerTests = []rpctest.HandlerTestSpec{ @@ -134,10 +134,10 @@ func TestRouter(t *testing.T) { require.NoError(t, err) options := apictrl.Options{ - Address: "localhost:9000", - PathBase: "/api.ucp.dev", - StorageClient: inmemory.NewClient(), - StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), + Address: "localhost:9000", + PathBase: "/api.ucp.dev", + DatabaseClient: inmemory.NewClient(), + StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), } return r, nsBuilder.ApplyAPIHandlers(ctx, r, options, validator) diff --git a/pkg/dynamicrp/backend/service.go b/pkg/dynamicrp/backend/service.go index 370563c80b..bbbd33955f 100644 --- a/pkg/dynamicrp/backend/service.go +++ b/pkg/dynamicrp/backend/service.go @@ -39,10 +39,10 @@ func NewService(options *dynamicrp.Options) *Service { ProviderName: "dynamic-rp", Options: hostoptions.HostOptions{ Config: &hostoptions.ProviderConfig{ - Env: options.Config.Environment, - StorageProvider: options.Config.Storage, - SecretProvider: options.Config.Secrets, - QueueProvider: options.Config.Queue, + Env: options.Config.Environment, + DatabaseProvider: options.Config.Database, + SecretProvider: options.Config.Secrets, + QueueProvider: options.Config.Queue, }, }, }, diff --git a/pkg/dynamicrp/config.go b/pkg/dynamicrp/config.go index 084c469c21..41ffacdbe8 100644 --- a/pkg/dynamicrp/config.go +++ b/pkg/dynamicrp/config.go @@ -24,9 +24,9 @@ import ( profilerprovider "github.com/radius-project/radius/pkg/profiler/provider" "github.com/radius-project/radius/pkg/trace" ucpconfig "github.com/radius-project/radius/pkg/ucp/config" - "github.com/radius-project/radius/pkg/ucp/dataprovider" - queueprovider "github.com/radius-project/radius/pkg/ucp/queue/provider" - secretprovider "github.com/radius-project/radius/pkg/ucp/secret/provider" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" + "github.com/radius-project/radius/pkg/ucp/queue/queueprovider" + "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" "github.com/radius-project/radius/pkg/ucp/ucplog" "gopkg.in/yaml.v3" ) @@ -36,6 +36,9 @@ type Config struct { // Bicep configures properties for the Bicep recipe driver. Bicep hostoptions.BicepOptions `yaml:"bicep"` + // Database is the configuration for the database. + Database databaseprovider.Options `yaml:"storageProvider"` + // Environment is the configuration for the hosting environment. Environment hostoptions.EnvironmentOptions `yaml:"environment"` @@ -57,9 +60,6 @@ type Config struct { // Server is the configuration for the HTTP server. Server hostoptions.ServerOptions `yaml:"server"` - // Storage is the configuration for the database used for storage. - Storage dataprovider.StorageProviderOptions `yaml:"storageProvider"` - // Terraform configures properties for the Terraform recipe driver. Terraform hostoptions.TerraformOptions `yaml:"terraform"` diff --git a/pkg/dynamicrp/frontend/service.go b/pkg/dynamicrp/frontend/service.go index f5bee9dbd9..73518751b5 100644 --- a/pkg/dynamicrp/frontend/service.go +++ b/pkg/dynamicrp/frontend/service.go @@ -48,7 +48,7 @@ func (s *Service) Name() string { return "dynamic-rp api" } -// Initialize sets up the router, storage provider, secret provider, status manager, AWS config, AWS clients, +// Initialize sets up the router, database provider, secret provider, status manager, AWS config, AWS clients, // registers the routes, configures the default planes, and sets up the http server with the appropriate middleware. It // returns an http server and an error if one occurs. func (s *Service) initialize(ctx context.Context) (*http.Server, error) { diff --git a/pkg/dynamicrp/options.go b/pkg/dynamicrp/options.go index 109c1a00e8..8d046c9132 100644 --- a/pkg/dynamicrp/options.go +++ b/pkg/dynamicrp/options.go @@ -26,9 +26,9 @@ import ( "github.com/radius-project/radius/pkg/recipes/controllerconfig" "github.com/radius-project/radius/pkg/sdk" ucpconfig "github.com/radius-project/radius/pkg/ucp/config" - "github.com/radius-project/radius/pkg/ucp/dataprovider" - queueprovider "github.com/radius-project/radius/pkg/ucp/queue/provider" - secretprovider "github.com/radius-project/radius/pkg/ucp/secret/provider" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" + "github.com/radius-project/radius/pkg/ucp/queue/queueprovider" + "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" kube_rest "k8s.io/client-go/rest" ) @@ -37,6 +37,9 @@ type Options struct { // Config is the configuration for the server. Config *Config + // DatabaseProvider provides access to the database. + DatabaseProvider *databaseprovider.DatabaseProvider + // QueueProvider provides access to the message queue client. QueueProvider *queueprovider.QueueProvider @@ -49,9 +52,6 @@ type Options struct { // StatusManager implements operations on async operation statuses. StatusManager statusmanager.StatusManager - // StorageProvider provides access to the data storage system. - StorageProvider *dataprovider.DataStorageProvider - // UCP is the connection to UCP UCP sdk.Connection } @@ -65,9 +65,9 @@ func NewOptions(ctx context.Context, config *Config) (*Options, error) { options.QueueProvider = queueprovider.New(config.Queue) options.SecretProvider = secretprovider.NewSecretProvider(config.Secrets) - options.StorageProvider = dataprovider.DataStorageProviderFromOptions(config.Storage) + options.DatabaseProvider = databaseprovider.FromOptions(config.Database) - storageClient, err := options.StorageProvider.GetClient(ctx) + databaseClient, err := options.DatabaseProvider.GetClient(ctx) if err != nil { return nil, err } @@ -77,7 +77,7 @@ func NewOptions(ctx context.Context, config *Config) (*Options, error) { return nil, err } - options.StatusManager = statusmanager.New(storageClient, queueClient, config.Environment.RoleLocation) + options.StatusManager = statusmanager.New(databaseClient, queueClient, config.Environment.RoleLocation) var cfg *kube_rest.Config cfg, err = kubeutil.NewClientConfig(&kubeutil.ConfigOptions{ diff --git a/pkg/dynamicrp/server/server.go b/pkg/dynamicrp/server/server.go index bb7e97963e..288737c780 100644 --- a/pkg/dynamicrp/server/server.go +++ b/pkg/dynamicrp/server/server.go @@ -26,7 +26,7 @@ import ( profilerservice "github.com/radius-project/radius/pkg/profiler/service" "github.com/radius-project/radius/pkg/trace" "github.com/radius-project/radius/pkg/ucp/data" - "github.com/radius-project/radius/pkg/ucp/dataprovider" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" "github.com/radius-project/radius/pkg/ucp/hosting" ) @@ -43,9 +43,9 @@ func NewServer(options *dynamicrp.Options) (*hosting.Host, error) { services := []hosting.Service{} // In-memory ETCD requires a service running in the process. - if options.Config.Storage.Provider == dataprovider.TypeETCD && - options.Config.Storage.ETCD.InMemory { - services = append(services, data.NewEmbeddedETCDService(data.EmbeddedETCDServiceOptions{ClientConfigSink: options.Config.Storage.ETCD.Client})) + if options.Config.Database.Provider == databaseprovider.TypeETCD && + options.Config.Database.ETCD.InMemory { + services = append(services, data.NewEmbeddedETCDService(data.EmbeddedETCDServiceOptions{ClientConfigSink: options.Config.Database.ETCD.Client})) } // Metrics is provided via a service. diff --git a/pkg/messagingrp/frontend/controller/rabbitmqqueues/listsecretsrabbitmq_test.go b/pkg/messagingrp/frontend/controller/rabbitmqqueues/listsecretsrabbitmq_test.go index 73746ca847..de0bf25c2d 100644 --- a/pkg/messagingrp/frontend/controller/rabbitmqqueues/listsecretsrabbitmq_test.go +++ b/pkg/messagingrp/frontend/controller/rabbitmqqueues/listsecretsrabbitmq_test.go @@ -28,7 +28,7 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/messagingrp/api/v20231001preview" "github.com/radius-project/radius/pkg/portableresources/renderers" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) @@ -37,7 +37,7 @@ func TestListSecrets_20231001Preview(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() - mStorageClient := store.NewMockStorageClient(mctrl) + databaseClient := database.NewMockClient(mctrl) ctx := context.Background() _, rabbitMQDataModel, _ := getTest_Model20231001preview() @@ -48,15 +48,15 @@ func TestListSecrets_20231001Preview(t *testing.T) { require.NoError(t, err) ctx := rpctest.NewARMRequestContext(req) - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{} + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{} }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsRabbitMQQueue(opts) @@ -78,18 +78,18 @@ func TestListSecrets_20231001Preview(t *testing.T) { renderers.URI: "connection://string", } - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ID: id}, + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ID: id}, Data: rabbitMQDataModel, }, nil }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsRabbitMQQueue(opts) @@ -113,15 +113,15 @@ func TestListSecrets_20231001Preview(t *testing.T) { ctx := rpctest.NewARMRequestContext(req) w := httptest.NewRecorder() - mStorageClient. + databaseClient. EXPECT(). Get(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { + DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { return nil, errors.New("failed to get the resource from data store") }) opts := ctrl.Options{ - StorageClient: mStorageClient, + DatabaseClient: databaseClient, } ctl, err := NewListSecretsRabbitMQQueue(opts) diff --git a/pkg/messagingrp/setup/setup_test.go b/pkg/messagingrp/setup/setup_test.go index 0aa5af07bb..48573e2e62 100644 --- a/pkg/messagingrp/setup/setup_test.go +++ b/pkg/messagingrp/setup/setup_test.go @@ -29,7 +29,7 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rpctest" msg_ctrl "github.com/radius-project/radius/pkg/messagingrp/frontend/controller" "github.com/radius-project/radius/pkg/recipes/controllerconfig" - "github.com/radius-project/radius/pkg/ucp/store/inmemory" + "github.com/radius-project/radius/pkg/ucp/database/inmemory" ) var handlerTests = []rpctest.HandlerTestSpec{ @@ -76,10 +76,10 @@ func TestRouter(t *testing.T) { require.NoError(t, err) options := apictrl.Options{ - Address: "localhost:9000", - PathBase: "/api.ucp.dev", - StorageClient: inmemory.NewClient(), - StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), + Address: "localhost:9000", + PathBase: "/api.ucp.dev", + DatabaseClient: inmemory.NewClient(), + StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), } return r, nsBuilder.ApplyAPIHandlers(ctx, r, options, validator) diff --git a/pkg/portableresources/backend/controller/createorupdateresource.go b/pkg/portableresources/backend/controller/createorupdateresource.go index 6e338356a8..028933421a 100644 --- a/pkg/portableresources/backend/controller/createorupdateresource.go +++ b/pkg/portableresources/backend/controller/createorupdateresource.go @@ -29,7 +29,7 @@ import ( "github.com/radius-project/radius/pkg/recipes/engine" "github.com/radius-project/radius/pkg/recipes/util" rpv1 "github.com/radius-project/radius/pkg/rp/v1" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/ucplog" ) @@ -64,8 +64,8 @@ func NewCreateOrUpdateResource[P interface { // processes the resource, cleans up any obsolete output resources, and saves the updated resource. func (c *CreateOrUpdateResource[P, T]) Run(ctx context.Context, req *ctrl.Request) (ctrl.Result, error) { logger := ucplog.FromContextOrDiscard(ctx) - obj, err := c.StorageClient().Get(ctx, req.ResourceID) - if errors.Is(&store.ErrNotFound{ID: req.ResourceID}, err) { + obj, err := c.DatabaseClient().Get(ctx, req.ResourceID) + if errors.Is(&database.ErrNotFound{ID: req.ResourceID}, err) { return ctrl.Result{}, err } else if err != nil { return ctrl.Result{}, err @@ -100,14 +100,14 @@ func (c *CreateOrUpdateResource[P, T]) Run(ctx context.Context, req *ctrl.Reques logger.Error(err, fmt.Sprintf("failed to execute recipe. Encountered error while processing %s ", recipeError.ErrorDetails.Target)) // Set the deployment status to the recipe error code. recipeDataModel.Recipe().DeploymentStatus = util.RecipeDeploymentStatus(recipeError.DeploymentStatus) - update := &store.Object{ - Metadata: store.Metadata{ + update := &database.Object{ + Metadata: database.Metadata{ ID: req.ResourceID, }, Data: recipeDataModel.(rpv1.RadiusResourceModel), } // Save portable resource with updated deployment status to track errors during deletion. - err = c.StorageClient().Save(ctx, update, store.WithETag(obj.ETag)) + err = c.DatabaseClient().Save(ctx, update, database.WithETag(obj.ETag)) if err != nil { return ctrl.Result{}, err } @@ -129,13 +129,13 @@ func (c *CreateOrUpdateResource[P, T]) Run(ctx context.Context, req *ctrl.Reques recipeDataModel.Recipe().DeploymentStatus = util.Success } - update := &store.Object{ - Metadata: store.Metadata{ + update := &database.Object{ + Metadata: database.Metadata{ ID: req.ResourceID, }, Data: recipeDataModel.(rpv1.RadiusResourceModel), } - err = c.StorageClient().Save(ctx, update, store.WithETag(obj.ETag)) + err = c.DatabaseClient().Save(ctx, update, database.WithETag(obj.ETag)) if err != nil { return ctrl.Result{}, err } diff --git a/pkg/portableresources/backend/controller/createorupdateresource_test.go b/pkg/portableresources/backend/controller/createorupdateresource_test.go index 0adf153b75..584ddd3632 100644 --- a/pkg/portableresources/backend/controller/createorupdateresource_test.go +++ b/pkg/portableresources/backend/controller/createorupdateresource_test.go @@ -37,8 +37,8 @@ import ( "github.com/radius-project/radius/pkg/recipes/controllerconfig" "github.com/radius-project/radius/pkg/recipes/engine" rpv1 "github.com/radius-project/radius/pkg/rp/v1" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" ) const ( @@ -129,10 +129,10 @@ var newOutputResourceResourceID = "/subscriptions/test-sub/resourceGroups/test-r var newOutputResource = rpv1.OutputResource{ID: resources.MustParse(newOutputResourceResourceID)} func TestCreateOrUpdateResource_Run(t *testing.T) { - setupTest := func() (*store.MockStorageClient, *engine.MockEngine, *processors.MockResourceClient, *configloader.MockConfigurationLoader) { + setupTest := func() (*database.MockClient, *engine.MockEngine, *processors.MockResourceClient, *configloader.MockConfigurationLoader) { mctrl := gomock.NewController(t) - msc := store.NewMockStorageClient(mctrl) + msc := database.NewMockClient(mctrl) eng := engine.NewMockEngine(mctrl) cfg := configloader.NewMockConfigurationLoader(mctrl) client := processors.NewMockResourceClient(mctrl) @@ -156,28 +156,28 @@ func TestCreateOrUpdateResource_Run(t *testing.T) { func(recipeCfg *controllerconfig.RecipeControllerConfig, options ctrl.Options) (ctrl.Controller, error) { return NewCreateOrUpdateResource(options, errorProcessorReference, recipeCfg.Engine, recipeCfg.ResourceClient, recipeCfg.ConfigLoader) }, - &store.ErrNotFound{ID: TestResourceID}, + &database.ErrNotFound{ID: TestResourceID}, false, nil, nil, nil, nil, nil, - &store.ErrNotFound{ID: TestResourceID}, + &database.ErrNotFound{ID: TestResourceID}, }, { "get-error", func(recipeCfg *controllerconfig.RecipeControllerConfig, options ctrl.Options) (ctrl.Controller, error) { return NewCreateOrUpdateResource(options, errorProcessorReference, recipeCfg.Engine, recipeCfg.ResourceClient, recipeCfg.ConfigLoader) }, - &store.ErrInvalid{}, + &database.ErrInvalid{}, false, nil, nil, nil, nil, nil, - &store.ErrInvalid{}, + &database.ErrInvalid{}, }, { "conversion-failure", @@ -314,12 +314,12 @@ func TestCreateOrUpdateResource_Run(t *testing.T) { stillPassing = false msc.EXPECT(). Get(gomock.Any(), TestResourceID). - Return(&store.Object{Data: nil}, tt.getErr). + Return(&database.Object{Data: nil}, tt.getErr). Times(1) } else if stillPassing { msc.EXPECT(). Get(gomock.Any(), TestResourceID). - Return(&store.Object{Data: data}, nil). + Return(&database.Object{Data: data}, nil). Times(1) } @@ -412,7 +412,7 @@ func TestCreateOrUpdateResource_Run(t *testing.T) { } opts := ctrl.Options{ - StorageClient: msc, + DatabaseClient: msc, } recipeCfg := &controllerconfig.RecipeControllerConfig{ diff --git a/pkg/portableresources/backend/controller/deleteresource.go b/pkg/portableresources/backend/controller/deleteresource.go index 4cdc54a04d..a509bff720 100644 --- a/pkg/portableresources/backend/controller/deleteresource.go +++ b/pkg/portableresources/backend/controller/deleteresource.go @@ -55,10 +55,10 @@ func NewDeleteResource[P interface { }, nil } -// Run retrieves a resource from storage, parses the resource ID, gets the data model, deletes the output -// resources, and deletes the resource from storage. It returns an error if any of these steps fail. +// Run retrieves a resource from the database, parses the resource ID, gets the data model, deletes the output +// resources, and deletes the resource from the database. It returns an error if any of these steps fail. func (c *DeleteResource[P, T]) Run(ctx context.Context, request *ctrl.Request) (ctrl.Result, error) { - obj, err := c.StorageClient().Get(ctx, request.ResourceID) + obj, err := c.DatabaseClient().Get(ctx, request.ResourceID) if err != nil { return ctrl.NewFailedResult(v1.ErrorDetails{Message: err.Error()}), err } @@ -114,7 +114,7 @@ func (c *DeleteResource[P, T]) Run(ctx context.Context, request *ctrl.Request) ( return ctrl.Result{}, err } - err = c.StorageClient().Delete(ctx, request.ResourceID) + err = c.DatabaseClient().Delete(ctx, request.ResourceID) if err != nil { return ctrl.Result{}, err } diff --git a/pkg/portableresources/backend/controller/deleteresource_test.go b/pkg/portableresources/backend/controller/deleteresource_test.go index d2da3b3359..ec1c021918 100644 --- a/pkg/portableresources/backend/controller/deleteresource_test.go +++ b/pkg/portableresources/backend/controller/deleteresource_test.go @@ -30,8 +30,8 @@ import ( "github.com/radius-project/radius/pkg/recipes/engine" rpv1 "github.com/radius-project/radius/pkg/rp/v1" "github.com/radius-project/radius/pkg/to" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) @@ -44,9 +44,9 @@ var outputResource = rpv1.OutputResource{ func TestDeleteResourceRun_20231001Preview(t *testing.T) { resourceID := "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/radius-test-rg/providers/Applications.Datastores/mongoDatabases/mongo0" - setupTest := func() (func(tb testing.TB), *store.MockStorageClient, *ctrl.Request, *engine.MockEngine, *configloader.MockConfigurationLoader) { + setupTest := func() (func(tb testing.TB), *database.MockClient, *ctrl.Request, *engine.MockEngine, *configloader.MockConfigurationLoader) { mctrl := gomock.NewController(t) - msc := store.NewMockStorageClient(mctrl) + msc := database.NewMockClient(mctrl) eng := engine.NewMockEngine(mctrl) cfg := configloader.NewMockConfigurationLoader(mctrl) @@ -72,7 +72,7 @@ func TestDeleteResourceRun_20231001Preview(t *testing.T) { scDelErr error }{ {"delete-existing-resource", nil, nil, nil}, - {"delete-non-existing-resource", &store.ErrNotFound{ID: resourceID}, nil, nil}, + {"delete-non-existing-resource", &database.ErrNotFound{ID: resourceID}, nil, nil}, {"delete-resource-engine-delete-error", nil, errors.New("engine delete error"), nil}, {"delete-resource-delete-from-db-error", nil, nil, errors.New("delete from db error")}, } @@ -117,7 +117,7 @@ func TestDeleteResourceRun_20231001Preview(t *testing.T) { msc.EXPECT(). Get(gomock.Any(), gomock.Any()). - Return(&store.Object{Data: data}, tt.getErr). + Return(&database.Object{Data: data}, tt.getErr). Times(1) if tt.getErr == nil { @@ -153,7 +153,7 @@ func TestDeleteResourceRun_20231001Preview(t *testing.T) { } } opts := ctrl.Options{ - StorageClient: msc, + DatabaseClient: msc, } ctrl, err := NewDeleteResource(opts, successProcessorReference, eng, configLoader) diff --git a/pkg/recipes/controllerconfig/config.go b/pkg/recipes/controllerconfig/config.go index 6ddeb1ef19..a6ca537506 100644 --- a/pkg/recipes/controllerconfig/config.go +++ b/pkg/recipes/controllerconfig/config.go @@ -29,7 +29,7 @@ import ( "github.com/radius-project/radius/pkg/recipes/engine" "github.com/radius-project/radius/pkg/sdk" "github.com/radius-project/radius/pkg/sdk/clients" - "github.com/radius-project/radius/pkg/ucp/secret/provider" + "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" ) // RecipeControllerConfig is the configuration for the controllers which uses recipe. @@ -100,7 +100,7 @@ func New(options hostoptions.HostOptions) (*RecipeControllerConfig, error) { DeleteRetryDelaySeconds: bicepDeleteRetryDeleteSeconds, }, ), - recipes.TemplateKindTerraform: driver.NewTerraformDriver(options.UCPConnection, provider.NewSecretProvider(options.Config.SecretProvider), + recipes.TemplateKindTerraform: driver.NewTerraformDriver(options.UCPConnection, secretprovider.NewSecretProvider(options.Config.SecretProvider), driver.TerraformOptions{ Path: options.Config.Terraform.Path, }, cfg.K8sClients.ClientSet), diff --git a/pkg/recipes/driver/terraform.go b/pkg/recipes/driver/terraform.go index 645dafb3d1..109af10211 100644 --- a/pkg/recipes/driver/terraform.go +++ b/pkg/recipes/driver/terraform.go @@ -38,7 +38,7 @@ import ( resources "github.com/radius-project/radius/pkg/ucp/resources" awsresources "github.com/radius-project/radius/pkg/ucp/resources/aws" kubernetesresources "github.com/radius-project/radius/pkg/ucp/resources/kubernetes" - ucp_provider "github.com/radius-project/radius/pkg/ucp/secret/provider" + ucp_provider "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" "github.com/radius-project/radius/pkg/ucp/ucplog" "github.com/radius-project/radius/pkg/ucp/util" diff --git a/pkg/recipes/terraform/config/providers/aws.go b/pkg/recipes/terraform/config/providers/aws.go index 98fe67bcf0..228ee7263c 100644 --- a/pkg/recipes/terraform/config/providers/aws.go +++ b/pkg/recipes/terraform/config/providers/aws.go @@ -32,7 +32,7 @@ import ( "github.com/radius-project/radius/pkg/ucp/resources" resources_aws "github.com/radius-project/radius/pkg/ucp/resources/aws" "github.com/radius-project/radius/pkg/ucp/secret" - ucp_provider "github.com/radius-project/radius/pkg/ucp/secret/provider" + ucp_provider "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" "github.com/radius-project/radius/pkg/ucp/ucplog" ) diff --git a/pkg/recipes/terraform/config/providers/azure.go b/pkg/recipes/terraform/config/providers/azure.go index e039ac03d0..5ac32cef3d 100644 --- a/pkg/recipes/terraform/config/providers/azure.go +++ b/pkg/recipes/terraform/config/providers/azure.go @@ -30,7 +30,7 @@ import ( "github.com/radius-project/radius/pkg/ucp/resources" resources_azure "github.com/radius-project/radius/pkg/ucp/resources/azure" "github.com/radius-project/radius/pkg/ucp/secret" - ucp_provider "github.com/radius-project/radius/pkg/ucp/secret/provider" + ucp_provider "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" "github.com/radius-project/radius/pkg/ucp/ucplog" ) diff --git a/pkg/recipes/terraform/config/providers/types.go b/pkg/recipes/terraform/config/providers/types.go index d870f57936..349d93839c 100644 --- a/pkg/recipes/terraform/config/providers/types.go +++ b/pkg/recipes/terraform/config/providers/types.go @@ -23,7 +23,7 @@ import ( "github.com/radius-project/radius/pkg/corerp/datamodel" "github.com/radius-project/radius/pkg/recipes" "github.com/radius-project/radius/pkg/sdk" - ucp_provider "github.com/radius-project/radius/pkg/ucp/secret/provider" + ucp_provider "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" ) //go:generate mockgen -typed -destination=./mock_provider.go -package=providers -self_package github.com/radius-project/radius/pkg/recipes/terraform/config/providers github.com/radius-project/radius/pkg/recipes/terraform/config/providers Provider diff --git a/pkg/recipes/terraform/execute.go b/pkg/recipes/terraform/execute.go index 4fd6709e2f..9e0c88d7e2 100644 --- a/pkg/recipes/terraform/execute.go +++ b/pkg/recipes/terraform/execute.go @@ -33,7 +33,7 @@ import ( "github.com/radius-project/radius/pkg/recipes/terraform/config/backends" "github.com/radius-project/radius/pkg/recipes/terraform/config/providers" "github.com/radius-project/radius/pkg/sdk" - ucp_provider "github.com/radius-project/radius/pkg/ucp/secret/provider" + ucp_provider "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" "github.com/radius-project/radius/pkg/ucp/ucplog" "go.opentelemetry.io/otel/attribute" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/rp/kube/resources.go b/pkg/rp/kube/resources.go index e55cf914ed..85c7e94ce7 100644 --- a/pkg/rp/kube/resources.go +++ b/pkg/rp/kube/resources.go @@ -25,13 +25,13 @@ import ( "github.com/radius-project/radius/pkg/corerp/api/v20231001preview" cdm "github.com/radius-project/radius/pkg/corerp/datamodel" rpv1 "github.com/radius-project/radius/pkg/rp/v1" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" ) // FindNamespaceByEnvID finds the environment-scope Kubernetes namespace. If the environment ID is invalid or the environment is not a Kubernetes // environment, an error is returned. -func FindNamespaceByEnvID(ctx context.Context, storageClient store.StorageClient, envID string) (namespace string, err error) { +func FindNamespaceByEnvID(ctx context.Context, databaseClient database.Client, envID string) (namespace string, err error) { id, err := resources.ParseResource(envID) if err != nil { return @@ -43,7 +43,7 @@ func FindNamespaceByEnvID(ctx context.Context, storageClient store.StorageClient } env := &cdm.Environment{} - res, err := storageClient.Get(ctx, id.String()) + res, err := databaseClient.Get(ctx, id.String()) if err != nil { return } diff --git a/pkg/rp/kube/resources_test.go b/pkg/rp/kube/resources_test.go index 738cd318e3..2c69d6d9a1 100644 --- a/pkg/rp/kube/resources_test.go +++ b/pkg/rp/kube/resources_test.go @@ -26,7 +26,7 @@ import ( "github.com/radius-project/radius/pkg/corerp/datamodel" rpv1 "github.com/radius-project/radius/pkg/rp/v1" "github.com/radius-project/radius/pkg/to" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) @@ -37,7 +37,7 @@ const ( appNamespace = "app-default" ) -func fakeStoreObject(dm v1.DataModelInterface) *store.Object { +func fakeStoreObject(dm v1.DataModelInterface) *database.Object { b, err := json.Marshal(dm) if err != nil { return nil @@ -47,7 +47,7 @@ func fakeStoreObject(dm v1.DataModelInterface) *store.Object { if err != nil { return nil } - return &store.Object{Data: r} + return &database.Object{Data: r} } func TestFindNamespaceByEnvID(t *testing.T) { @@ -86,7 +86,7 @@ func TestFindNamespaceByEnvID(t *testing.T) { }, } - mockSC := store.NewMockStorageClient(mctrl) + mockSC := database.NewMockClient(mctrl) mockSC.EXPECT().Get(gomock.Any(), tc.id, gomock.Any()).Return(fakeStoreObject(envdm), nil).Times(1) ns, err := FindNamespaceByEnvID(context.Background(), mockSC, testEnvID) diff --git a/pkg/rp/util/datastore.go b/pkg/rp/util/datastore.go index e0ca7f317b..82ce79afd2 100644 --- a/pkg/rp/util/datastore.go +++ b/pkg/rp/util/datastore.go @@ -23,13 +23,13 @@ import ( "strings" v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" + "github.com/radius-project/radius/pkg/ucp/database" resources "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" ) // FetchScopeResource checks if the given scopeID is a valid resource ID for the given resource type, fetches the resource -// from the storage client and returns an error if the resource does not exist. -func FetchScopeResource(ctx context.Context, storageClient store.StorageClient, scopeID string, resource v1.DataModelInterface) error { +// from the database client and returns an error if the resource does not exist. +func FetchScopeResource(ctx context.Context, databaseClient database.Client, scopeID string, resource v1.DataModelInterface) error { id, err := resources.ParseResource(scopeID) if err != nil { return v1.NewClientErrInvalidRequest(fmt.Sprintf("%s is not a valid resource id for %s.", scopeID, resource.ResourceTypeName())) @@ -39,8 +39,8 @@ func FetchScopeResource(ctx context.Context, storageClient store.StorageClient, return v1.NewClientErrInvalidRequest(fmt.Sprintf("linked %q has invalid %s resource type.", scopeID, resource.ResourceTypeName())) } - res, err := storageClient.Get(ctx, id.String()) - if errors.Is(&store.ErrNotFound{ID: id.String()}, err) { + res, err := databaseClient.Get(ctx, id.String()) + if errors.Is(&database.ErrNotFound{ID: id.String()}, err) { return v1.NewClientErrInvalidRequest(fmt.Sprintf("linked resource %s does not exist", scopeID)) } if err != nil { diff --git a/pkg/server/apiservice.go b/pkg/server/apiservice.go index 698f935ba8..12730c8ac4 100644 --- a/pkg/server/apiservice.go +++ b/pkg/server/apiservice.go @@ -57,7 +57,7 @@ func (s *APIService) Run(ctx context.Context) error { return err } - storageClient, err := s.StorageProvider.GetClient(ctx) + databaseClient, err := s.DatabaseProvider.GetClient(ctx) if err != nil { return err } @@ -70,11 +70,11 @@ func (s *APIService) Run(ctx context.Context) error { Configure: func(r chi.Router) error { for _, b := range s.handlerBuilder { opts := apictrl.Options{ - Address: address, - PathBase: s.Options.Config.Server.PathBase, - StorageClient: storageClient, - KubeClient: s.KubeClient, - StatusManager: s.OperationStatusManager, + Address: address, + PathBase: s.Options.Config.Server.PathBase, + DatabaseClient: databaseClient, + KubeClient: s.KubeClient, + StatusManager: s.OperationStatusManager, } validator, err := builder.NewOpenAPIValidator(ctx, opts.PathBase, b.Namespace()) diff --git a/pkg/server/asyncworker.go b/pkg/server/asyncworker.go index fd8a162c3e..2531c6b0a9 100644 --- a/pkg/server/asyncworker.go +++ b/pkg/server/asyncworker.go @@ -68,17 +68,17 @@ func (w *AsyncWorker) Run(ctx context.Context) error { return fmt.Errorf("failed to initialize application model: %w", err) } - storageClient, err := w.StorageProvider.GetClient(ctx) + databaseClient, err := w.DatabaseProvider.GetClient(ctx) if err != nil { return err } for _, b := range w.handlerBuilder { opts := ctrl.Options{ - StorageClient: storageClient, - KubeClient: k8s.RuntimeClient, + DatabaseClient: databaseClient, + KubeClient: k8s.RuntimeClient, GetDeploymentProcessor: func() deployment.DeploymentProcessor { - return deployment.NewDeploymentProcessor(appModel, storageClient, k8s.RuntimeClient, k8s.ClientSet) + return deployment.NewDeploymentProcessor(appModel, databaseClient, k8s.RuntimeClient, k8s.ClientSet) }, } diff --git a/pkg/ucp/backend/controller/resourcegroups/trackedresourceprocess.go b/pkg/ucp/backend/controller/resourcegroups/trackedresourceprocess.go index bb2fa2b3d0..3f7ba1c87b 100644 --- a/pkg/ucp/backend/controller/resourcegroups/trackedresourceprocess.go +++ b/pkg/ucp/backend/controller/resourcegroups/trackedresourceprocess.go @@ -25,10 +25,10 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" ctrl "github.com/radius-project/radius/pkg/armrpc/asyncoperation/controller" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/frontend/controller/resourcegroups" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/trackedresource" "github.com/radius-project/radius/pkg/ucp/ucplog" ) @@ -54,15 +54,15 @@ type TrackedResourceProcessController struct { func NewTrackedResourceProcessController(opts ctrl.Options, transport http.RoundTripper, defaultDownstream *url.URL) (ctrl.Controller, error) { return &TrackedResourceProcessController{ BaseController: ctrl.NewBaseAsyncController(opts), - updater: trackedresource.NewUpdater(opts.StorageClient, &http.Client{Transport: transport}), + updater: trackedresource.NewUpdater(opts.DatabaseClient, &http.Client{Transport: transport}), defaultDownstream: defaultDownstream, }, nil } -// Run retrieves a resource from storage, parses the resource ID, and updates our tracked resource entry in the background. +// Run retrieves a resource from the database, parses the resource ID, and updates our tracked resource entry in the background. func (c *TrackedResourceProcessController) Run(ctx context.Context, request *ctrl.Request) (ctrl.Result, error) { - resource, err := store.GetResource[datamodel.GenericResource](ctx, c.StorageClient(), request.ResourceID) - if errors.Is(err, &store.ErrNotFound{}) { + resource, err := database.GetResource[datamodel.GenericResource](ctx, c.DatabaseClient(), request.ResourceID) + if errors.Is(err, &database.ErrNotFound{}) { return ctrl.NewFailedResult(v1.ErrorDetails{Code: v1.CodeNotFound, Message: fmt.Sprintf("resource %q not found", request.ResourceID), Target: request.ResourceID}), nil } else if err != nil { return ctrl.Result{}, err @@ -73,7 +73,7 @@ func (c *TrackedResourceProcessController) Run(ctx context.Context, request *ctr return ctrl.Result{}, err } - downstreamURL, err := resourcegroups.ValidateDownstream(ctx, c.StorageClient(), originalID, v1.LocationGlobal, resource.Properties.APIVersion) + downstreamURL, err := resourcegroups.ValidateDownstream(ctx, c.DatabaseClient(), originalID, v1.LocationGlobal, resource.Properties.APIVersion) if errors.Is(err, &resourcegroups.NotFoundError{}) { return ctrl.NewFailedResult(v1.ErrorDetails{Code: v1.CodeNotFound, Message: err.Error(), Target: request.ResourceID}), nil } else if errors.Is(err, &resourcegroups.InvalidError{}) { diff --git a/pkg/ucp/backend/controller/resourcegroups/trackedresourceprocess_test.go b/pkg/ucp/backend/controller/resourcegroups/trackedresourceprocess_test.go index c4db345daf..aaee56c4ca 100644 --- a/pkg/ucp/backend/controller/resourcegroups/trackedresourceprocess_test.go +++ b/pkg/ucp/backend/controller/resourcegroups/trackedresourceprocess_test.go @@ -23,9 +23,9 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" "github.com/radius-project/radius/pkg/armrpc/asyncoperation/controller" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/trackedresource" "github.com/radius-project/radius/test/testcontext" "github.com/stretchr/testify/require" @@ -33,16 +33,16 @@ import ( ) func Test_Run(t *testing.T) { - setup := func(t *testing.T) (*TrackedResourceProcessController, *mockUpdater, *store.MockStorageClient) { + setup := func(t *testing.T) (*TrackedResourceProcessController, *mockUpdater, *database.MockClient) { ctrl := gomock.NewController(t) - storageClient := store.NewMockStorageClient(ctrl) + databaseClient := database.NewMockClient(ctrl) - pc, err := NewTrackedResourceProcessController(controller.Options{StorageClient: storageClient}, nil, nil) + pc, err := NewTrackedResourceProcessController(controller.Options{DatabaseClient: databaseClient}, nil, nil) require.NoError(t, err) updater := mockUpdater{} pc.(*TrackedResourceProcessController).updater = &updater - return pc.(*TrackedResourceProcessController), &updater, storageClient + return pc.(*TrackedResourceProcessController), &updater, databaseClient } id := resources.MustParse("/planes/test/local/resourceGroups/test-rg/providers/Applications.Test/testResources/my-resource") @@ -63,23 +63,23 @@ func Test_Run(t *testing.T) { // Most of the heavy lifting is done by the updater. We just need to test that we're calling it correctly. t.Run("Success", func(t *testing.T) { - pc, _, storageClient := setup(t) + pc, _, databaseClient := setup(t) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), trackingID.String(), gomock.Any()). - Return(&store.Object{Data: data}, nil).Times(1) + Return(&database.Object{Data: data}, nil).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), "/planes/"+trackingID.PlaneNamespace(), gomock.Any()). - Return(&store.Object{Data: plane}, nil).Times(1) + Return(&database.Object{Data: plane}, nil).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), resourceTypeID.String(), gomock.Any()). - Return(nil, &store.ErrNotFound{}).Times(1) + Return(nil, &database.ErrNotFound{}).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), trackingID.RootScope(), gomock.Any()). - Return(&store.Object{Data: resourceGroup}, nil).Times(1) + Return(&database.Object{Data: resourceGroup}, nil).Times(1) result, err := pc.Run(testcontext.New(t), &controller.Request{ResourceID: trackingID.String()}) require.Equal(t, controller.Result{}, result) @@ -87,23 +87,23 @@ func Test_Run(t *testing.T) { }) t.Run("retry", func(t *testing.T) { - pc, updater, storageClient := setup(t) + pc, updater, databaseClient := setup(t) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), trackingID.String(), gomock.Any()). - Return(&store.Object{Data: data}, nil).Times(1) + Return(&database.Object{Data: data}, nil).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), "/planes/"+trackingID.PlaneNamespace(), gomock.Any()). - Return(&store.Object{Data: plane}, nil).Times(1) + Return(&database.Object{Data: plane}, nil).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), resourceTypeID.String(), gomock.Any()). - Return(nil, &store.ErrNotFound{}).Times(1) + Return(nil, &database.ErrNotFound{}).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), trackingID.RootScope(), gomock.Any()). - Return(&store.Object{Data: resourceGroup}, nil).Times(1) + Return(&database.Object{Data: resourceGroup}, nil).Times(1) // Force a retry. updater.Result = &trackedresource.InProgressErr{} @@ -117,11 +117,11 @@ func Test_Run(t *testing.T) { }) t.Run("Failure (resource not found)", func(t *testing.T) { - pc, _, storageClient := setup(t) + pc, _, databaseClient := setup(t) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), trackingID.String(), gomock.Any()). - Return(nil, &store.ErrNotFound{}).Times(1) + Return(nil, &database.ErrNotFound{}).Times(1) expected := controller.NewFailedResult(v1.ErrorDetails{ Code: v1.CodeNotFound, @@ -135,15 +135,15 @@ func Test_Run(t *testing.T) { }) t.Run("Failure (validate downstream: not found)", func(t *testing.T) { - pc, _, storageClient := setup(t) + pc, _, databaseClient := setup(t) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), trackingID.String(), gomock.Any()). - Return(&store.Object{Data: data}, nil).Times(1) + Return(&database.Object{Data: data}, nil).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), "/planes/"+trackingID.PlaneNamespace(), gomock.Any()). - Return(nil, &store.ErrNotFound{}).Times(1) + Return(nil, &database.ErrNotFound{}).Times(1) expected := controller.NewFailedResult(v1.ErrorDetails{ Code: v1.CodeNotFound, diff --git a/pkg/ucp/backend/controller/resourceproviders/apiversion_delete.go b/pkg/ucp/backend/controller/resourceproviders/apiversion_delete.go index 4cf969d673..e2efad47a5 100644 --- a/pkg/ucp/backend/controller/resourceproviders/apiversion_delete.go +++ b/pkg/ucp/backend/controller/resourceproviders/apiversion_delete.go @@ -38,12 +38,12 @@ func (c *APIVersionDeleteController) Run(ctx context.Context, request *ctrl.Requ return ctrl.Result{}, err } - err = updateResourceProviderSummaryWithETag(ctx, c.StorageClient(), summaryID, summaryNotFoundIgnore, c.updateSummary(id)) + err = updateResourceProviderSummaryWithETag(ctx, c.DatabaseClient(), summaryID, summaryNotFoundIgnore, c.updateSummary(id)) if err != nil { return ctrl.Result{}, err } - err = c.StorageClient().Delete(ctx, request.ResourceID) + err = c.DatabaseClient().Delete(ctx, request.ResourceID) if err != nil { return ctrl.Result{}, err } diff --git a/pkg/ucp/backend/controller/resourceproviders/apiversion_put.go b/pkg/ucp/backend/controller/resourceproviders/apiversion_put.go index ca97bfe308..7891ccb5d2 100644 --- a/pkg/ucp/backend/controller/resourceproviders/apiversion_put.go +++ b/pkg/ucp/backend/controller/resourceproviders/apiversion_put.go @@ -39,7 +39,7 @@ func (c *APIVersionPutController) Run(ctx context.Context, request *ctrl.Request return ctrl.Result{}, err } - err = updateResourceProviderSummaryWithETag(ctx, c.StorageClient(), summaryID, summaryNotFoundFail, c.updateSummary(id)) + err = updateResourceProviderSummaryWithETag(ctx, c.DatabaseClient(), summaryID, summaryNotFoundFail, c.updateSummary(id)) if err != nil { return ctrl.Result{}, err } diff --git a/pkg/ucp/backend/controller/resourceproviders/location_delete.go b/pkg/ucp/backend/controller/resourceproviders/location_delete.go index 987ab21439..434396e9f1 100644 --- a/pkg/ucp/backend/controller/resourceproviders/location_delete.go +++ b/pkg/ucp/backend/controller/resourceproviders/location_delete.go @@ -38,12 +38,12 @@ func (c *LocationDeleteController) Run(ctx context.Context, request *ctrl.Reques return ctrl.Result{}, err } - err = updateResourceProviderSummaryWithETag(ctx, c.StorageClient(), summaryID, summaryNotFoundIgnore, c.updateSummary(id)) + err = updateResourceProviderSummaryWithETag(ctx, c.DatabaseClient(), summaryID, summaryNotFoundIgnore, c.updateSummary(id)) if err != nil { return ctrl.Result{}, err } - err = c.StorageClient().Delete(ctx, request.ResourceID) + err = c.DatabaseClient().Delete(ctx, request.ResourceID) if err != nil { return ctrl.Result{}, err } diff --git a/pkg/ucp/backend/controller/resourceproviders/location_put.go b/pkg/ucp/backend/controller/resourceproviders/location_put.go index 7ff0e3a130..7c118a2b4c 100644 --- a/pkg/ucp/backend/controller/resourceproviders/location_put.go +++ b/pkg/ucp/backend/controller/resourceproviders/location_put.go @@ -38,7 +38,7 @@ func (c *LocationPutController) Run(ctx context.Context, request *ctrl.Request) return ctrl.Result{}, err } - err = updateResourceProviderSummaryWithETag(ctx, c.StorageClient(), summaryID, summaryNotFoundFail, c.updateSummary(id)) + err = updateResourceProviderSummaryWithETag(ctx, c.DatabaseClient(), summaryID, summaryNotFoundFail, c.updateSummary(id)) if err != nil { return ctrl.Result{}, err } diff --git a/pkg/ucp/backend/controller/resourceproviders/resourceprovider_delete.go b/pkg/ucp/backend/controller/resourceproviders/resourceprovider_delete.go index 0984c4d2f7..450aa29261 100644 --- a/pkg/ucp/backend/controller/resourceproviders/resourceprovider_delete.go +++ b/pkg/ucp/backend/controller/resourceproviders/resourceprovider_delete.go @@ -25,9 +25,9 @@ import ( aztoken "github.com/radius-project/radius/pkg/azure/tokencredentials" "github.com/radius-project/radius/pkg/sdk" "github.com/radius-project/radius/pkg/ucp/api/v20231001preview" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/resources" resources_radius "github.com/radius-project/radius/pkg/ucp/resources/radius" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/ucplog" ) @@ -53,7 +53,7 @@ func (c *ResourceProviderDeleteController) Run(ctx context.Context, request *ctr return ctrl.Result{}, fmt.Errorf("failed to delete resource provider summary: %w", err) } - err = c.StorageClient().Delete(ctx, request.ResourceID) + err = c.DatabaseClient().Delete(ctx, request.ResourceID) if err != nil { return ctrl.Result{}, err } @@ -222,8 +222,8 @@ func (c *ResourceProviderDeleteController) deleteSummary(ctx context.Context, re return err } - err = c.StorageClient().Delete(ctx, summaryID.String()) - if errors.Is(err, &store.ErrNotFound{}) { + err = c.DatabaseClient().Delete(ctx, summaryID.String()) + if errors.Is(err, &database.ErrNotFound{}) { // It's OK if the summary was already deleted. return nil } else if err != nil { diff --git a/pkg/ucp/backend/controller/resourceproviders/resourceprovider_put.go b/pkg/ucp/backend/controller/resourceproviders/resourceprovider_put.go index de416896fa..16dc046fef 100644 --- a/pkg/ucp/backend/controller/resourceproviders/resourceprovider_put.go +++ b/pkg/ucp/backend/controller/resourceproviders/resourceprovider_put.go @@ -37,7 +37,7 @@ func (c *ResourceProviderPutController) Run(ctx context.Context, request *ctrl.R return ctrl.Result{}, err } - err = updateResourceProviderSummaryWithETag(ctx, c.StorageClient(), summaryID, summaryNotFoundCreate, c.updateSummary()) + err = updateResourceProviderSummaryWithETag(ctx, c.DatabaseClient(), summaryID, summaryNotFoundCreate, c.updateSummary()) if err != nil { return ctrl.Result{}, err } diff --git a/pkg/ucp/backend/controller/resourceproviders/resourcetype_delete.go b/pkg/ucp/backend/controller/resourceproviders/resourcetype_delete.go index 76758b0b6f..72575b7e80 100644 --- a/pkg/ucp/backend/controller/resourceproviders/resourcetype_delete.go +++ b/pkg/ucp/backend/controller/resourceproviders/resourcetype_delete.go @@ -53,12 +53,12 @@ func (c *ResourceTypeDeleteController) Run(ctx context.Context, request *ctrl.Re return ctrl.Result{}, err } - err = updateResourceProviderSummaryWithETag(ctx, c.StorageClient(), summaryID, summaryNotFoundIgnore, c.updateSummary(id)) + err = updateResourceProviderSummaryWithETag(ctx, c.DatabaseClient(), summaryID, summaryNotFoundIgnore, c.updateSummary(id)) if err != nil { return ctrl.Result{}, err } - err = c.StorageClient().Delete(ctx, request.ResourceID) + err = c.DatabaseClient().Delete(ctx, request.ResourceID) if err != nil { return ctrl.Result{}, err } diff --git a/pkg/ucp/backend/controller/resourceproviders/resourcetype_put.go b/pkg/ucp/backend/controller/resourceproviders/resourcetype_put.go index 890be9748e..ee1c02eae1 100644 --- a/pkg/ucp/backend/controller/resourceproviders/resourcetype_put.go +++ b/pkg/ucp/backend/controller/resourceproviders/resourcetype_put.go @@ -43,7 +43,7 @@ func (c *ResourceTypePutController) Run(ctx context.Context, request *ctrl.Reque return ctrl.Result{}, err } - err = updateResourceProviderSummaryWithETag(ctx, c.StorageClient(), summaryID, summaryNotFoundFail, c.updateSummary(id, resourceType)) + err = updateResourceProviderSummaryWithETag(ctx, c.DatabaseClient(), summaryID, summaryNotFoundFail, c.updateSummary(id, resourceType)) if err != nil { return ctrl.Result{}, err } @@ -52,7 +52,7 @@ func (c *ResourceTypePutController) Run(ctx context.Context, request *ctrl.Reque } func (c *ResourceTypePutController) fetchResourceType(ctx context.Context, id resources.ID) (*datamodel.ResourceType, error) { - obj, err := c.StorageClient().Get(ctx, id.String()) + obj, err := c.DatabaseClient().Get(ctx, id.String()) if err != nil { return nil, err } diff --git a/pkg/ucp/backend/controller/resourceproviders/util.go b/pkg/ucp/backend/controller/resourceproviders/util.go index e6c7ccafb5..4e1ea46ccd 100644 --- a/pkg/ucp/backend/controller/resourceproviders/util.go +++ b/pkg/ucp/backend/controller/resourceproviders/util.go @@ -23,9 +23,9 @@ import ( "strings" ctrl "github.com/radius-project/radius/pkg/armrpc/asyncoperation/controller" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/ucplog" ) @@ -63,8 +63,8 @@ func resourceProviderSummaryIDFromRequest(request *ctrl.Request) (resources.ID, return id, summaryID, nil } -// updateResourceProviderSummaryWithETag updates the summary with the provided function and saves it to the storage client. -func updateResourceProviderSummaryWithETag(ctx context.Context, client store.StorageClient, summaryID resources.ID, policy summaryNotFoundPolicy, update func(summary *datamodel.ResourceProviderSummary) error) error { +// updateResourceProviderSummaryWithETag updates the summary with the provided function and saves it to the database client. +func updateResourceProviderSummaryWithETag(ctx context.Context, client database.Client, summaryID resources.ID, policy summaryNotFoundPolicy, update func(summary *datamodel.ResourceProviderSummary) error) error { // There are a few cases here: // 1. The summary does not exist and we are allowed to create it (in the resource provider). // 2. The summary does not exist and we are not allowed to create it (in the child-types of resource provider). @@ -72,20 +72,20 @@ func updateResourceProviderSummaryWithETag(ctx context.Context, client store.Sto summary := &datamodel.ResourceProviderSummary{} obj, err := client.Get(ctx, summaryID.String()) - if errors.Is(err, &store.ErrNotFound{}) && policy == summaryNotFoundCreate { + if errors.Is(err, &database.ErrNotFound{}) && policy == summaryNotFoundCreate { // This is fine. We will create a new summary. summary.ID = summaryID.String() summary.Name = summaryID.Name() summary.Type = summaryID.Type() - obj = &store.Object{ - Metadata: store.Metadata{ + obj = &database.Object{ + Metadata: database.Metadata{ ID: summary.ID, }, } - } else if errors.Is(err, &store.ErrNotFound{}) && policy == summaryNotFoundIgnore { + } else if errors.Is(err, &database.ErrNotFound{}) && policy == summaryNotFoundIgnore { return nil - } else if errors.Is(err, &store.ErrNotFound{}) { + } else if errors.Is(err, &database.ErrNotFound{}) { return err } else if err != nil { return err @@ -104,9 +104,9 @@ func updateResourceProviderSummaryWithETag(ctx context.Context, client store.Sto } // Now we can save. Use the ETag if the resource already existed. - options := []store.SaveOptions{} + options := []database.SaveOptions{} if obj.ETag != "" { - options = append(options, store.WithETag(obj.ETag)) + options = append(options, database.WithETag(obj.ETag)) } obj.Data = summary diff --git a/pkg/ucp/backend/controller/resourceproviders/util_test.go b/pkg/ucp/backend/controller/resourceproviders/util_test.go index 874076ca3e..656be012f4 100644 --- a/pkg/ucp/backend/controller/resourceproviders/util_test.go +++ b/pkg/ucp/backend/controller/resourceproviders/util_test.go @@ -21,9 +21,9 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" ctrl "github.com/radius-project/radius/pkg/armrpc/asyncoperation/controller" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/util/etag" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -151,11 +151,11 @@ func Test_UpdateResourceProviderSummaryWithETag(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ctrl := gomock.NewController(t) - client := store.NewMockStorageClient(ctrl) + client := database.NewMockClient(ctrl) expectedETag := "" if tt.existing == nil { - client.EXPECT().Get(gomock.Any(), tt.summaryID.String()).Return(nil, &store.ErrNotFound{}) + client.EXPECT().Get(gomock.Any(), tt.summaryID.String()).Return(nil, &database.ErrNotFound{}) } else { bs, err := json.Marshal(tt.existing) require.NoError(t, err) @@ -165,8 +165,8 @@ func Test_UpdateResourceProviderSummaryWithETag(t *testing.T) { require.NoError(t, err) expectedETag = etag.New(bs) - obj := store.Object{ - Metadata: store.Metadata{ + obj := database.Object{ + Metadata: database.Metadata{ ID: tt.summaryID.String(), ETag: expectedETag, }, @@ -176,9 +176,9 @@ func Test_UpdateResourceProviderSummaryWithETag(t *testing.T) { } if tt.expectedSave { - client.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, o *store.Object, so ...store.SaveOptions) error { + client.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, o *database.Object, so ...database.SaveOptions) error { - config := store.NewSaveConfig(so...) + config := database.NewSaveConfig(so...) require.Equal(t, expectedETag, config.ETag) expectedResourceTypes := map[string]datamodel.ResourceProviderSummaryPropertiesResourceType{ diff --git a/pkg/ucp/backend/service.go b/pkg/ucp/backend/service.go index 708dca726b..c61ed873b6 100644 --- a/pkg/ucp/backend/service.go +++ b/pkg/ucp/backend/service.go @@ -80,13 +80,13 @@ func (w *Service) Run(ctx context.Context) error { } } - storageClient, err := w.StorageProvider.GetClient(ctx) + databaseClient, err := w.DatabaseProvider.GetClient(ctx) if err != nil { return err } opts := ctrl.Options{ - StorageClient: storageClient, + DatabaseClient: databaseClient, } defaultDownstream, err := url.Parse(w.config.Routing.DefaultDownstreamEndpoint) diff --git a/pkg/ucp/credentials/aws.go b/pkg/ucp/credentials/aws.go index 3750062608..1fa8e52e95 100644 --- a/pkg/ucp/credentials/aws.go +++ b/pkg/ucp/credentials/aws.go @@ -26,20 +26,20 @@ import ( "github.com/radius-project/radius/pkg/to" ucpapi "github.com/radius-project/radius/pkg/ucp/api/v20231001preview" "github.com/radius-project/radius/pkg/ucp/secret" - "github.com/radius-project/radius/pkg/ucp/secret/provider" + "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" ) var _ CredentialProvider[AWSCredential] = (*AWSCredentialProvider)(nil) // AWSCredentialProvider is UCP credential provider for Azure. type AWSCredentialProvider struct { - secretProvider *provider.SecretProvider + secretProvider *secretprovider.SecretProvider client *ucpapi.AwsCredentialsClient } // NewAWSCredentialProvider creates a new AWSCredentialProvider struct using the given SecretProvider, UCP connection and // TokenCredential, and returns it or an error if one occurs. -func NewAWSCredentialProvider(provider *provider.SecretProvider, ucpConn sdk.Connection, credential azcore.TokenCredential) (*AWSCredentialProvider, error) { +func NewAWSCredentialProvider(provider *secretprovider.SecretProvider, ucpConn sdk.Connection, credential azcore.TokenCredential) (*AWSCredentialProvider, error) { cli, err := ucpapi.NewAwsCredentialsClient(credential, sdk.NewClientOptions(ucpConn)) if err != nil { return nil, err diff --git a/pkg/ucp/credentials/azure.go b/pkg/ucp/credentials/azure.go index 2712c00fa6..4d9e773564 100644 --- a/pkg/ucp/credentials/azure.go +++ b/pkg/ucp/credentials/azure.go @@ -26,20 +26,20 @@ import ( "github.com/radius-project/radius/pkg/to" ucpapi "github.com/radius-project/radius/pkg/ucp/api/v20231001preview" "github.com/radius-project/radius/pkg/ucp/secret" - "github.com/radius-project/radius/pkg/ucp/secret/provider" + "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" ) var _ CredentialProvider[AzureCredential] = (*AzureCredentialProvider)(nil) // AzureCredentialProvider is UCP credential provider for Azure. type AzureCredentialProvider struct { - secretProvider *provider.SecretProvider + secretProvider *secretprovider.SecretProvider client *ucpapi.AzureCredentialsClient } // NewAzureCredentialProvider creates a new AzureCredentialProvider by creating a new AzureCredentialClient with the given // credential and connection, and returns an error if one occurs. -func NewAzureCredentialProvider(provider *provider.SecretProvider, ucpConn sdk.Connection, credential azcore.TokenCredential) (*AzureCredentialProvider, error) { +func NewAzureCredentialProvider(provider *secretprovider.SecretProvider, ucpConn sdk.Connection, credential azcore.TokenCredential) (*AzureCredentialProvider, error) { cli, err := ucpapi.NewAzureCredentialsClient(credential, sdk.NewClientOptions(ucpConn)) if err != nil { return nil, err diff --git a/pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1/groupversion_info.go b/pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1/groupversion_info.go similarity index 100% rename from pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1/groupversion_info.go rename to pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1/groupversion_info.go diff --git a/pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1/queuemessage_types.go b/pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1/queuemessage_types.go similarity index 100% rename from pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1/queuemessage_types.go rename to pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1/queuemessage_types.go diff --git a/pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1/resource_types.go b/pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1/resource_types.go similarity index 100% rename from pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1/resource_types.go rename to pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1/resource_types.go diff --git a/pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1/zz_generated.deepcopy.go b/pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1/zz_generated.deepcopy.go similarity index 100% rename from pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1/zz_generated.deepcopy.go rename to pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1/zz_generated.deepcopy.go diff --git a/pkg/ucp/store/apiserverstore/apiserverclient.go b/pkg/ucp/database/apiserverstore/apiserverclient.go similarity index 83% rename from pkg/ucp/store/apiserverstore/apiserverclient.go rename to pkg/ucp/database/apiserverstore/apiserverclient.go index d684a2b2b5..6976bcfb71 100644 --- a/pkg/ucp/store/apiserverstore/apiserverclient.go +++ b/pkg/ucp/database/apiserverstore/apiserverclient.go @@ -48,10 +48,10 @@ import ( "strings" "unicode" + "github.com/radius-project/radius/pkg/ucp/database" + ucpv1alpha1 "github.com/radius-project/radius/pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1" + "github.com/radius-project/radius/pkg/ucp/database/databaseutil" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" - ucpv1alpha1 "github.com/radius-project/radius/pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1" - "github.com/radius-project/radius/pkg/ucp/store/storeutil" "github.com/radius-project/radius/pkg/ucp/ucplog" "github.com/radius-project/radius/pkg/ucp/util/etag" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -87,7 +87,7 @@ func NewAPIServerClient(client runtimeclient.Client, namespace string) *APIServe return &APIServerClient{client: client, namespace: namespace} } -var _ store.StorageClient = (*APIServerClient)(nil) +var _ database.Client = (*APIServerClient)(nil) type APIServerClient struct { client runtimeclient.Client @@ -101,13 +101,13 @@ type APIServerClient struct { } // Query searches for objects in the store that match the given query and returns them. -func (c *APIServerClient) Query(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { +func (c *APIServerClient) Query(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { if ctx == nil { - return nil, &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } err := query.Validate() if err != nil { - return nil, &store.ErrInvalid{Message: fmt.Sprintf("invalid argument. Query is invalid: %s", err.Error())} + return nil, &database.ErrInvalid{Message: fmt.Sprintf("invalid argument. Query is invalid: %s", err.Error())} } selector, err := createLabelSelector(query) @@ -121,7 +121,7 @@ func (c *APIServerClient) Query(ctx context.Context, query store.Query, options return nil, err } - results := store.ObjectQueryResult{} + results := database.ObjectQueryResult{} for _, resource := range rs.Items { for _, entry := range resource.Entries { id, err := resources.Parse(entry.ID) @@ -133,7 +133,7 @@ func (c *APIServerClient) Query(ctx context.Context, query store.Query, options continue } - if storeutil.IDMatchesQuery(id, query) { + if databaseutil.IDMatchesQuery(id, query) { converted, err := readEntry(&entry) if err != nil { return nil, err @@ -155,19 +155,19 @@ func (c *APIServerClient) Query(ctx context.Context, query store.Query, options } // Get retrieves an object from the store given its ID, or returns an error if the object does not exist or if an error occurs. -func (c *APIServerClient) Get(ctx context.Context, id string, options ...store.GetOptions) (*store.Object, error) { +func (c *APIServerClient) Get(ctx context.Context, id string, options ...database.GetOptions) (*database.Object, error) { if ctx == nil { - return nil, &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } parsed, err := resources.Parse(id) if err != nil { - return nil, &store.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} } if parsed.IsEmpty() { - return nil, &store.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} } if parsed.IsResourceCollection() || parsed.IsScopeCollection() { - return nil, &store.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} } resourceName := resourceName(parsed) @@ -175,7 +175,7 @@ func (c *APIServerClient) Get(ctx context.Context, id string, options ...store.G resource := ucpv1alpha1.Resource{} err = c.client.Get(ctx, runtimeclient.ObjectKey{Namespace: c.namespace, Name: resourceName}, &resource) if err != nil && apierrors.IsNotFound(err) { - return nil, &store.ErrNotFound{ID: id} + return nil, &database.ErrNotFound{ID: id} } else if err != nil { return nil, err } @@ -184,50 +184,50 @@ func (c *APIServerClient) Get(ctx context.Context, id string, options ...store.G if err != nil { return nil, err } else if obj == nil { - return nil, &store.ErrNotFound{ID: id} + return nil, &database.ErrNotFound{ID: id} } return obj, nil } // Delete deletes a resource from the store, returning an error if the resource does not exist or if there is a concurrency conflict. -func (c *APIServerClient) Delete(ctx context.Context, id string, options ...store.DeleteOptions) error { +func (c *APIServerClient) Delete(ctx context.Context, id string, options ...database.DeleteOptions) error { if ctx == nil { - return &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } parsed, err := resources.Parse(id) if err != nil { - return &store.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} + return &database.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} } if parsed.IsEmpty() { - return &store.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} + return &database.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} } if parsed.IsResourceCollection() || parsed.IsScopeCollection() { - return &store.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} + return &database.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} } resourceName := resourceName(parsed) - config := store.NewDeleteConfig(options...) + config := database.NewDeleteConfig(options...) err = c.doWithRetry(func() (bool, error) { resource := ucpv1alpha1.Resource{} err := c.client.Get(ctx, runtimeclient.ObjectKey{Namespace: c.namespace, Name: resourceName}, &resource) if err != nil && apierrors.IsNotFound(err) && config.ETag != "" { - return false, &store.ErrConcurrency{} + return false, &database.ErrConcurrency{} } else if err != nil && apierrors.IsNotFound(err) { - return false, &store.ErrNotFound{ID: id} + return false, &database.ErrNotFound{ID: id} } else if err != nil { return false, err } index := findIndex(&resource, parsed) if index == nil { - return false, &store.ErrNotFound{ID: id} + return false, &database.ErrNotFound{ID: id} } if config.ETag != "" && config.ETag != resource.Entries[*index].ETag { - return false, &store.ErrConcurrency{} + return false, &database.ErrConcurrency{} } c.synchronize() @@ -242,7 +242,7 @@ func (c *APIServerClient) Delete(ctx context.Context, id string, options ...stor } err := c.client.Delete(ctx, &resource, &options) if err != nil && apierrors.IsNotFound(err) { - return false, &store.ErrNotFound{ID: id} + return false, &database.ErrNotFound{ID: id} } else if apierrors.IsConflict(err) { return true, err // RETRY this! } else if err != nil { @@ -256,7 +256,7 @@ func (c *APIServerClient) Delete(ctx context.Context, id string, options ...stor err := c.client.Update(ctx, &resource) if err != nil && apierrors.IsNotFound(err) { - return false, &store.ErrNotFound{ID: id} + return false, &database.ErrNotFound{ID: id} } else if apierrors.IsConflict(err) { return true, err // RETRY this! } else if err != nil { @@ -271,12 +271,12 @@ func (c *APIServerClient) Delete(ctx context.Context, id string, options ...stor } // Save saves an object to the store, or updates an existing object if it already exists, and returns an error if the operation fails. -func (c *APIServerClient) Save(ctx context.Context, obj *store.Object, options ...store.SaveOptions) error { +func (c *APIServerClient) Save(ctx context.Context, obj *database.Object, options ...database.SaveOptions) error { if ctx == nil { - return &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } if obj == nil { - return &store.ErrInvalid{Message: "invalid argument. 'obj' is required"} + return &database.ErrInvalid{Message: "invalid argument. 'obj' is required"} } id, err := resources.Parse(obj.ID) @@ -286,7 +286,7 @@ func (c *APIServerClient) Save(ctx context.Context, obj *store.Object, options . resourceName := resourceName(id) - config := store.NewSaveConfig(options...) + config := database.NewSaveConfig(options...) err = c.doWithRetry(func() (bool, error) { found := true @@ -314,12 +314,12 @@ func (c *APIServerClient) Save(ctx context.Context, obj *store.Object, options . if index == nil && config.ETag != "" { // The ETag is only meaning for a replace/update operation not a create. We treat // the absence of the resource as a match failure. - return false, &store.ErrConcurrency{} + return false, &database.ErrConcurrency{} } else if index == nil { resource.Entries = append(resource.Entries, *converted) } else { if config.ETag != "" && config.ETag != resource.Entries[*index].ETag { - return false, &store.ErrConcurrency{} + return false, &database.ErrConcurrency{} } resource.Entries[*index] = *converted @@ -368,7 +368,7 @@ func (c *APIServerClient) doWithRetry(action func() (bool, error)) error { } // If we get here then we ran out of retries. - return &store.ErrConcurrency{} + return &database.ErrConcurrency{} } // synchronize is used for testing concurrency behavior. The client can be configured by tests to pause between reading and writing @@ -406,9 +406,9 @@ func resourceName(id resources.ID) string { _, _ = hasher.Write([]byte(strings.ToLower(id.String()))) hash := hasher.Sum(nil) - prefix := store.UCPResourcePrefix + prefix := database.UCPResourcePrefix if id.IsScope() { - prefix = store.UCPScopePrefix + prefix = database.UCPScopePrefix } noramlizedName := normalizeName(id.Name()) @@ -432,7 +432,7 @@ func assignLabels(resource *ucpv1alpha1.Resource) labels.Set { continue } - prefix, rootScope, _, resourceType := storeutil.ExtractStorageParts(id) + prefix, rootScope, _, resourceType := databaseutil.ExtractStorageParts(id) set[LabelKind] = prefix // We need to take apart the root scope so we can turn it into key-value-pairs. @@ -465,7 +465,7 @@ func assignLabels(resource *ucpv1alpha1.Resource) labels.Set { return set } -func createLabelSelector(query store.Query) (labels.Selector, error) { +func createLabelSelector(query database.Query) (labels.Selector, error) { id, err := resources.Parse(query.RootScope) if err != nil { return nil, err @@ -473,14 +473,14 @@ func createLabelSelector(query store.Query) (labels.Selector, error) { selector := labels.NewSelector() if query.IsScopeQuery { - requirement, err := labels.NewRequirement(LabelKind, selection.Equals, []string{storeutil.ScopePrefix}) + requirement, err := labels.NewRequirement(LabelKind, selection.Equals, []string{databaseutil.ScopePrefix}) if err != nil { return nil, err } selector = selector.Add(*requirement) } else { - requirement, err := labels.NewRequirement(LabelKind, selection.Equals, []string{storeutil.ResourcePrefix}) + requirement, err := labels.NewRequirement(LabelKind, selection.Equals, []string{databaseutil.ResourcePrefix}) if err != nil { return nil, err } @@ -524,15 +524,15 @@ func findIndex(resource *ucpv1alpha1.Resource, id resources.ID) *int { return nil } -func readEntry(entry *ucpv1alpha1.ResourceEntry) (*store.Object, error) { +func readEntry(entry *ucpv1alpha1.ResourceEntry) (*database.Object, error) { var data any err := json.Unmarshal(entry.Data.Raw, &data) if err != nil { return nil, err } - obj := store.Object{ - Metadata: store.Metadata{ + obj := database.Object{ + Metadata: database.Metadata{ ID: entry.ID, ETag: entry.ETag, }, @@ -542,7 +542,7 @@ func readEntry(entry *ucpv1alpha1.ResourceEntry) (*store.Object, error) { return &obj, nil } -func read(resource *ucpv1alpha1.Resource, id resources.ID) (*store.Object, error) { +func read(resource *ucpv1alpha1.Resource, id resources.ID) (*database.Object, error) { for _, entry := range resource.Entries { if strings.EqualFold(entry.ID, id.String()) { return readEntry(&entry) @@ -552,7 +552,7 @@ func read(resource *ucpv1alpha1.Resource, id resources.ID) (*store.Object, error return nil, nil } -func convert(obj *store.Object) (*ucpv1alpha1.ResourceEntry, error) { +func convert(obj *database.Object) (*ucpv1alpha1.ResourceEntry, error) { raw, err := json.Marshal(obj.Data) if err != nil { return nil, err diff --git a/pkg/ucp/store/apiserverstore/apiserverclient_test.go b/pkg/ucp/database/apiserverstore/apiserverclient_test.go similarity index 97% rename from pkg/ucp/store/apiserverstore/apiserverclient_test.go rename to pkg/ucp/database/apiserverstore/apiserverclient_test.go index ffcec75416..cdc28fbda1 100644 --- a/pkg/ucp/store/apiserverstore/apiserverclient_test.go +++ b/pkg/ucp/database/apiserverstore/apiserverclient_test.go @@ -28,9 +28,9 @@ import ( "k8s.io/apimachinery/pkg/runtime" runtimeclient "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/radius-project/radius/pkg/ucp/database" + ucpv1alpha1 "github.com/radius-project/radius/pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" - ucpv1alpha1 "github.com/radius-project/radius/pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1" "github.com/radius-project/radius/pkg/ucp/util/etag" "github.com/radius-project/radius/test/testcontext" "github.com/radius-project/radius/test/ucp/kubeenv" @@ -137,8 +137,8 @@ func Test_APIServer_Client(t *testing.T) { t.Run("save_resource_and_validate_kubernetes_object", func(t *testing.T) { clear(t) - obj1 := store.Object{ - Metadata: store.Metadata{ + obj1 := database.Object{ + Metadata: database.Metadata{ ID: shared.Resource1ID.String(), }, Data: shared.Data1, @@ -166,8 +166,8 @@ func Test_APIServer_Client(t *testing.T) { t.Run("save_resource_and_validate_kubernetes_object_uppercase_name", func(t *testing.T) { clear(t) - obj1 := store.Object{ - Metadata: store.Metadata{ + obj1 := database.Object{ + Metadata: database.Metadata{ ID: shared.Resource3ID.String(), }, Data: shared.Data1, @@ -195,8 +195,8 @@ func Test_APIServer_Client(t *testing.T) { t.Run("save_scope_and_validate_kubernetes_object", func(t *testing.T) { clear(t) - obj1 := store.Object{ - Metadata: store.Metadata{ + obj1 := database.Object{ + Metadata: database.Metadata{ ID: shared.ResourceGroup1ID.String(), }, Data: shared.ResourceGroup1Data, @@ -243,8 +243,8 @@ func Test_APIServer_Client(t *testing.T) { err := rc.Create(ctx, &resource) require.NoError(t, err) - obj2 := store.Object{ - Metadata: store.Metadata{ + obj2 := database.Object{ + Metadata: database.Metadata{ ID: shared.Resource2ID.String(), }, Data: shared.Data2, @@ -288,12 +288,12 @@ func Test_APIServer_Client(t *testing.T) { require.Equal(t, shared.Data2, obj.Data) // We can query it though... - objs, err := client.Query(ctx, store.Query{RootScope: shared.RadiusScope, ScopeRecursive: true, ResourceType: shared.ResourceType2}) + objs, err := client.Query(ctx, database.Query{RootScope: shared.RadiusScope, ScopeRecursive: true, ResourceType: shared.ResourceType2}) require.NoError(t, err) - expected := []store.Object{ + expected := []database.Object{ *obj, { - Metadata: store.Metadata{ + Metadata: database.Metadata{ ID: shared.Resource3ID.String(), ETag: etag.New(shared.MarshalOrPanic(shared.Data3)), }, @@ -322,8 +322,8 @@ func Test_APIServer_Client(t *testing.T) { // Start an operation to "save" resource 1 go func() { - obj1 := store.Object{ - Metadata: store.Metadata{ + obj1 := database.Object{ + Metadata: database.Metadata{ ID: shared.Resource1ID.String(), }, Data: shared.Data1, @@ -427,8 +427,8 @@ func Test_APIServer_Client(t *testing.T) { // Start an operation to "save" resource 1 go func() { - obj1 := store.Object{ - Metadata: store.Metadata{ + obj1 := database.Object{ + Metadata: database.Metadata{ ID: shared.Resource1ID.String(), }, Data: shared.Data1, @@ -729,7 +729,7 @@ func Test_AssignLabels_AllConflict(t *testing.T) { } func Test_CreateLabelSelector_UCPID(t *testing.T) { - query := store.Query{ + query := database.Query{ RootScope: "/planes/radius/local/resourceGroups/cool-group", ResourceType: "Applications.Core/containers", } @@ -772,7 +772,7 @@ func Test_CreateLabelSelector_UCPID(t *testing.T) { } func Test_CreateLabelSelector_ResourceQuery(t *testing.T) { - query := store.Query{ + query := database.Query{ RootScope: "/planes/radius/local/resourceGroups/cool-group", ResourceType: "Applications.Core/containers", } @@ -815,7 +815,7 @@ func Test_CreateLabelSelector_ResourceQuery(t *testing.T) { } func Test_CreateLabelSelector_ScopeQuery(t *testing.T) { - query := store.Query{ + query := database.Query{ RootScope: "/planes/radius/local", ResourceType: "resourceGroups", IsScopeQuery: true, diff --git a/pkg/ucp/store/client.go b/pkg/ucp/database/client.go similarity index 91% rename from pkg/ucp/store/client.go rename to pkg/ucp/database/client.go index 471e45a577..32c1a7b76b 100644 --- a/pkg/ucp/store/client.go +++ b/pkg/ucp/database/client.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package store +package database import ( "context" @@ -31,18 +31,18 @@ var jsonPropertyPattern = "[a-zA-Z$_][a-zA-Z0-9$_]*" // - Multople properties separated by a '.' var fieldRegex = regexp.MustCompile(fmt.Sprintf(`^(%s)(\.%s)*$`, jsonPropertyPattern, jsonPropertyPattern)) -//go:generate mockgen -typed -destination=./mock_storageClient.go -package=store -self_package github.com/radius-project/radius/pkg/ucp/store github.com/radius-project/radius/pkg/ucp/store StorageClient +//go:generate mockgen -typed -destination=./mock_client.go -package=database -self_package github.com/radius-project/radius/pkg/ucp/database github.com/radius-project/radius/pkg/ucp/database Client -// StorageClient is the interface for persisting and querying resource data. +// Client is the interface for persisting and querying resource data. // -// The StorageClient is purpose-built to work with resource data and understands concepts like +// The Client is purpose-built to work with resource data and understands concepts like // scopes, resource types, and resource ids. This is a higher level abstraction than a generic // key-value store, but low-level enough to support multiple implementation strategies. // -// The StorageClient provides a optimistic concurrency control using ETags. Callers that want +// The Client provides a optimistic concurrency control using ETags. Callers that want // to enforce OCC should provide the ETag value in the options when calling Save or Delete. // -// The StorageClient may return the errors ErrNotFound, ErrInvalid, and ErrConcurrency. +// The Client may return the errors ErrNotFound, ErrInvalid, and ErrConcurrency. // // - Callers should handle ErrNotFound on Get, Save, and Delete operations. // - Callers should handle ErrConcurrency when using ETags. @@ -50,7 +50,7 @@ var fieldRegex = regexp.MustCompile(fmt.Sprintf(`^(%s)(\.%s)*$`, jsonPropertyPat // // When using ETags, the Save or Delete operation will fail with ErrConcurrency (rather than ErrNotFound) // if the underlying resource has been deleted. -type StorageClient interface { +type Client interface { // Query executes a query against the data store and returns the results. // // Queries must provide a root scope and a resource type. Other fields are optional. diff --git a/pkg/ucp/store/client_test.go b/pkg/ucp/database/client_test.go similarity index 99% rename from pkg/ucp/store/client_test.go rename to pkg/ucp/database/client_test.go index 580fe2b9b7..10e4352582 100644 --- a/pkg/ucp/store/client_test.go +++ b/pkg/ucp/database/client_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package store +package database import ( "testing" diff --git a/pkg/ucp/store/storeutil/doc.go b/pkg/ucp/database/databaseutil/doc.go similarity index 84% rename from pkg/ucp/store/storeutil/doc.go rename to pkg/ucp/database/databaseutil/doc.go index 2733db3279..e465360de3 100644 --- a/pkg/ucp/store/storeutil/doc.go +++ b/pkg/ucp/database/databaseutil/doc.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// storeutil contains utility functions for implementing storage backends. The store package only +// storeutil contains utility functions for implementing database backends. The store package only // has dependencies on the std library (intentionally) so that clients of the store are easy to // reference. -package storeutil +package databaseutil diff --git a/pkg/ucp/store/storeutil/id.go b/pkg/ucp/database/databaseutil/id.go similarity index 97% rename from pkg/ucp/store/storeutil/id.go rename to pkg/ucp/database/databaseutil/id.go index 4b72a54624..a2f953abcb 100644 --- a/pkg/ucp/store/storeutil/id.go +++ b/pkg/ucp/database/databaseutil/id.go @@ -14,14 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -package storeutil +package databaseutil import ( "fmt" "strings" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" ) const ( @@ -59,7 +59,7 @@ func ExtractStorageParts(id resources.ID) (string, string, string, string) { } // IDMatchesQuery checks if the given ID matches the given query. -func IDMatchesQuery(id resources.ID, query store.Query) bool { +func IDMatchesQuery(id resources.ID, query database.Query) bool { prefix, rootScope, routingScope, resourceType := ExtractStorageParts(id) if query.IsScopeQuery && !strings.EqualFold(prefix, ScopePrefix) { return false diff --git a/pkg/ucp/store/storeutil/id_test.go b/pkg/ucp/database/databaseutil/id_test.go similarity index 95% rename from pkg/ucp/store/storeutil/id_test.go rename to pkg/ucp/database/databaseutil/id_test.go index 7fe40de4cb..4b2a13d3b1 100644 --- a/pkg/ucp/store/storeutil/id_test.go +++ b/pkg/ucp/database/databaseutil/id_test.go @@ -14,13 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -package storeutil +package databaseutil import ( "testing" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/stretchr/testify/require" ) @@ -109,7 +109,7 @@ func Test_ExtractStorageParts(t *testing.T) { func Test_IDMatchesQuery(t *testing.T) { type testcase struct { ID string - Query store.Query + Query database.Query IsMatch bool } @@ -117,26 +117,26 @@ func Test_IDMatchesQuery(t *testing.T) { // Tests in this section target block-coverage of all of our negative cases. { ID: "/planes/radius/local", - Query: store.Query{ + Query: database.Query{ IsScopeQuery: false, // mismatched query type }, }, { ID: "/planes/radius/local/resourceGroups/cool-group/providers/Applications.Core/applications/cool-app", - Query: store.Query{ + Query: database.Query{ IsScopeQuery: true, // mismatched query type }, }, { ID: "/planes/radius/local/resourceGroups/cool-group", - Query: store.Query{ + Query: database.Query{ RootScope: "/planes/radius/local/resourceGroups/cool-group", // mismatched root scope IsScopeQuery: true, }, }, { ID: "/planes/radius/local/resourceGroups/cool-group", - Query: store.Query{ + Query: database.Query{ RootScope: "/planes/radius/another-plane", // mismatched root scope ScopeRecursive: true, IsScopeQuery: true, @@ -144,7 +144,7 @@ func Test_IDMatchesQuery(t *testing.T) { }, { ID: "/subscriptions/cool-sub/resourceGroups/cool-group/providers/Applications.Core/applications/cool-app/nested/cool-nested", - Query: store.Query{ + Query: database.Query{ RootScope: "/subscriptions/cool-sub/resourceGroups/cool-group", RoutingScopePrefix: "Applications.Core/applications/different-app", // mismatched routing scope prefix IsScopeQuery: false, @@ -152,7 +152,7 @@ func Test_IDMatchesQuery(t *testing.T) { }, { ID: "/planes/radius/local/resourceGroups/cool-group/providers/Applications.Core/applications/cool-app", - Query: store.Query{ + Query: database.Query{ RootScope: "/planes/radius/local/resourceGroups", ResourceType: "Applications.Core/containers", // mismatched resource type IsScopeQuery: false, @@ -162,7 +162,7 @@ func Test_IDMatchesQuery(t *testing.T) { // Tests in this section target our main use-cases for the query logic. { ID: "/planes/radius/local", - Query: store.Query{ + Query: database.Query{ RootScope: "/planes", // list all planes (regardless of type) IsScopeQuery: true, }, @@ -170,7 +170,7 @@ func Test_IDMatchesQuery(t *testing.T) { }, { ID: "/planes/radius/local", - Query: store.Query{ + Query: database.Query{ RootScope: "/planes", // list all planes (specific type) ResourceType: "radius", IsScopeQuery: true, @@ -179,7 +179,7 @@ func Test_IDMatchesQuery(t *testing.T) { }, { ID: "/planes/radius/local/resourceGroups/cool-group", - Query: store.Query{ + Query: database.Query{ RootScope: "/planes/radius/local/", // list all resource groups ResourceType: "resourceGroups", IsScopeQuery: true, @@ -188,7 +188,7 @@ func Test_IDMatchesQuery(t *testing.T) { }, { ID: "/planes/radius/local/resourceGroups/cool-group", - Query: store.Query{ + Query: database.Query{ RootScope: "/planes", // list all resource groups across planes ResourceType: "resourceGroups", ScopeRecursive: true, @@ -198,7 +198,7 @@ func Test_IDMatchesQuery(t *testing.T) { }, { ID: "/planes/radius/local/resourceGroups/cool-group/providers/Applications.Core/applications/cool-app", - Query: store.Query{ + Query: database.Query{ RootScope: "/planes/radius/local", // list all resources in plane ScopeRecursive: true, IsScopeQuery: false, @@ -207,7 +207,7 @@ func Test_IDMatchesQuery(t *testing.T) { }, { ID: "/planes/radius/local/resourceGroups/cool-group/providers/Applications.Core/applications/cool-app", - Query: store.Query{ + Query: database.Query{ RootScope: "/planes/radius/local/resourceGroups/cool-group", // list all resources in resource group ScopeRecursive: false, IsScopeQuery: false, @@ -216,7 +216,7 @@ func Test_IDMatchesQuery(t *testing.T) { }, { ID: "/planes/radius/local/resourceGroups/cool-group/providers/Applications.Core/applications/cool-app", - Query: store.Query{ + Query: database.Query{ RootScope: "/planes/radius/local/resourceGroups/cool-group", // list all applications in resource group ResourceType: "Applications.Core/applications", ScopeRecursive: false, @@ -226,7 +226,7 @@ func Test_IDMatchesQuery(t *testing.T) { }, { ID: "/planes/radius/local/resourceGroups/cool-group/providers/Applications.Core/applications/cool-app", - Query: store.Query{ + Query: database.Query{ RootScope: "/planes/radius/local/", // list all applications in plane ResourceType: "Applications.Core/applications", ScopeRecursive: true, @@ -236,7 +236,7 @@ func Test_IDMatchesQuery(t *testing.T) { }, { ID: "/planes/radius/local/resourceGroups/cool-group/providers/Applications.Core/applications/cool-app/nested/cool-nested", - Query: store.Query{ + Query: database.Query{ RootScope: "/planes/radius/local/resourceGroups/cool-group", // list nested resources RoutingScopePrefix: "/Applications.Core/applications/cool-app", ResourceType: "Applications.Core/applications/nested", diff --git a/pkg/ucp/store/err.go b/pkg/ucp/database/err.go similarity index 99% rename from pkg/ucp/store/err.go rename to pkg/ucp/database/err.go index c0c0613a55..a38ce56562 100644 --- a/pkg/ucp/store/err.go +++ b/pkg/ucp/database/err.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package store +package database import "fmt" diff --git a/pkg/ucp/store/etcdstore/etcdclient.go b/pkg/ucp/database/etcdstore/etcdclient.go similarity index 76% rename from pkg/ucp/store/etcdstore/etcdclient.go rename to pkg/ucp/database/etcdstore/etcdclient.go index 4f5d1e8857..ed3c7a1a76 100644 --- a/pkg/ucp/store/etcdstore/etcdclient.go +++ b/pkg/ucp/database/etcdstore/etcdclient.go @@ -52,9 +52,9 @@ import ( "fmt" "strings" + "github.com/radius-project/radius/pkg/ucp/database" + "github.com/radius-project/radius/pkg/ucp/database/databaseutil" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" - "github.com/radius-project/radius/pkg/ucp/store/storeutil" "github.com/radius-project/radius/pkg/ucp/util/etag" etcdclient "go.etcd.io/etcd/client/v3" ) @@ -68,21 +68,21 @@ func NewETCDClient(c *etcdclient.Client) *ETCDClient { return &ETCDClient{client: c} } -var _ store.StorageClient = (*ETCDClient)(nil) +var _ database.Client = (*ETCDClient)(nil) type ETCDClient struct { client *etcdclient.Client } // Query retrieves objects from the store that match the given query and filters, and returns them in a store.ObjectQueryResult. -func (c *ETCDClient) Query(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { +func (c *ETCDClient) Query(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { if ctx == nil { - return nil, &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } - + err := query.Validate() if err != nil { - return nil, &store.ErrInvalid{Message: fmt.Sprintf("invalid argument. Query is invalid: %s", err.Error())} + return nil, &database.ErrInvalid{Message: fmt.Sprintf("invalid argument. Query is invalid: %s", err.Error())} } key := keyFromQuery(query) @@ -96,10 +96,10 @@ func (c *ETCDClient) Query(ctx context.Context, query store.Query, options ...st return nil, err } - results := store.ObjectQueryResult{} + results := database.ObjectQueryResult{} for _, kv := range response.Kvs { if keyMatchesQuery(kv.Key, query) { - value := store.Object{} + value := database.Object{} err = json.Unmarshal(kv.Value, &value) if err != nil { return nil, err @@ -122,19 +122,19 @@ func (c *ETCDClient) Query(ctx context.Context, query store.Query, options ...st // Get checks if the provided context, id and options are valid, then retrieves the corresponding object from // the store and returns it, or an error if the object is not found or an error occurs. -func (c *ETCDClient) Get(ctx context.Context, id string, options ...store.GetOptions) (*store.Object, error) { +func (c *ETCDClient) Get(ctx context.Context, id string, options ...database.GetOptions) (*database.Object, error) { if ctx == nil { - return nil, &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } parsed, err := resources.Parse(id) if err != nil { - return nil, &store.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} } if parsed.IsEmpty() { - return nil, &store.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} } if parsed.IsResourceCollection() || parsed.IsScopeCollection() { - return nil, &store.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} } key := keyFromID(parsed) @@ -144,10 +144,10 @@ func (c *ETCDClient) Get(ctx context.Context, id string, options ...store.GetOpt } if response.Count == 0 { - return nil, &store.ErrNotFound{ID: id} + return nil, &database.ErrNotFound{ID: id} } - value := store.Object{} + value := database.Object{} err = json.Unmarshal(response.Kvs[0].Value, &value) if err != nil { return nil, err @@ -160,30 +160,30 @@ func (c *ETCDClient) Get(ctx context.Context, id string, options ...store.GetOpt // Delete checks if the given resource ID is valid, and if so, deletes it from the store, returning an error if the // resource does not exist or if an ETag is provided and does not match. -func (c *ETCDClient) Delete(ctx context.Context, id string, options ...store.DeleteOptions) error { +func (c *ETCDClient) Delete(ctx context.Context, id string, options ...database.DeleteOptions) error { if ctx == nil { - return &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } parsed, err := resources.Parse(id) if err != nil { - return &store.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} + return &database.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} } if parsed.IsEmpty() { - return &store.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} + return &database.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} } if parsed.IsResourceCollection() || parsed.IsScopeCollection() { - return &store.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} + return &database.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} } key := keyFromID(parsed) - config := store.NewDeleteConfig(options...) + config := database.NewDeleteConfig(options...) // If we have an ETag then we do to execute a transaction. if config.ETag != "" { revision, err := etag.ParseRevision(config.ETag) if err != nil { // Treat an invalid ETag as a concurrency failure, since it will never match. - return &store.ErrConcurrency{} + return &database.ErrConcurrency{} } txn, err := c.client.Txn(ctx). @@ -195,12 +195,12 @@ func (c *ETCDClient) Delete(ctx context.Context, id string, options ...store.Del } if !txn.Succeeded { - return &store.ErrConcurrency{} + return &database.ErrConcurrency{} } response := txn.Responses[0].GetResponseDeleteRange() if response.Deleted == 0 { - return &store.ErrNotFound{ID: id} + return &database.ErrNotFound{ID: id} } else { return nil } @@ -213,7 +213,7 @@ func (c *ETCDClient) Delete(ctx context.Context, id string, options ...store.Del } if response.Deleted == 0 { - return &store.ErrNotFound{ID: id} + return &database.ErrNotFound{ID: id} } return nil @@ -221,12 +221,12 @@ func (c *ETCDClient) Delete(ctx context.Context, id string, options ...store.Del // Save checks the context and object parameters, parses the object ID, marshals the object into JSON, saves the object to // the store, and sets the object's ETag. If an ETag is provided, a transaction is executed to ensure concurrency. -func (c *ETCDClient) Save(ctx context.Context, obj *store.Object, options ...store.SaveOptions) error { +func (c *ETCDClient) Save(ctx context.Context, obj *database.Object, options ...database.SaveOptions) error { if ctx == nil { - return &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } if obj == nil { - return &store.ErrInvalid{Message: "invalid argument. 'obj' is required"} + return &database.ErrInvalid{Message: "invalid argument. 'obj' is required"} } id := obj.Metadata.ID @@ -241,14 +241,14 @@ func (c *ETCDClient) Save(ctx context.Context, obj *store.Object, options ...sto } key := keyFromID(parsed) - config := store.NewSaveConfig(options...) + config := database.NewSaveConfig(options...) // If we have an ETag then we do to execute a transaction. if config.ETag != "" { revision, err := etag.ParseRevision(config.ETag) if err != nil { // Treat an invalid ETag as a concurrency failure, since it will never match. - return &store.ErrConcurrency{} + return &database.ErrConcurrency{} } txn, err := c.client.Txn(ctx). @@ -260,7 +260,7 @@ func (c *ETCDClient) Save(ctx context.Context, obj *store.Object, options ...sto } if !txn.Succeeded { - return &store.ErrConcurrency{} + return &database.ErrConcurrency{} } response := txn.Responses[0].GetResponsePut() @@ -293,12 +293,12 @@ func idFromKey(key []byte) (resources.ID, error) { } switch parts[0] { - case storeutil.ScopePrefix: + case databaseutil.ScopePrefix: // The key might look like: // scope|/planes/radius/local/|/resourceGroups/cool-group/ return resources.Parse(parts[1] + strings.TrimPrefix(parts[2], resources.SegmentSeparator)) - case storeutil.ResourcePrefix: + case databaseutil.ResourcePrefix: // The key might look like: // resource|/subscriptions/{guid}/resourceGroups/cool-group/|/Applications.Core/applications/cool-app/ return resources.Parse(parts[1] + resources.ProvidersSegment + parts[2]) @@ -310,34 +310,34 @@ func idFromKey(key []byte) (resources.ID, error) { // keyFromID returns the key to use for an ID. They key should be used as an exact match. func keyFromID(id resources.ID) string { - prefix, rootScope, routingScope, _ := storeutil.ExtractStorageParts(id) + prefix, rootScope, routingScope, _ := databaseutil.ExtractStorageParts(id) return prefix + SectionSeparator + rootScope + SectionSeparator + routingScope } // keyFromQuery returns the key to use for an for executing a query. The key should be used as a prefix. -func keyFromQuery(query store.Query) string { +func keyFromQuery(query database.Query) string { // These patterns require a prefix match for us in ETCd. // // A recursive query will not be able to consider anything in the routing scope, so it // always requires client-side filtering. - prefix := storeutil.ResourcePrefix + prefix := databaseutil.ResourcePrefix if query.IsScopeQuery { - prefix = storeutil.ScopePrefix + prefix = databaseutil.ScopePrefix } if query.ScopeRecursive { - return prefix + SectionSeparator + storeutil.NormalizePart(query.RootScope) + return prefix + SectionSeparator + databaseutil.NormalizePart(query.RootScope) } else { - return prefix + SectionSeparator + storeutil.NormalizePart(query.RootScope) + SectionSeparator + storeutil.NormalizePart(query.RoutingScopePrefix) + return prefix + SectionSeparator + databaseutil.NormalizePart(query.RootScope) + SectionSeparator + databaseutil.NormalizePart(query.RoutingScopePrefix) } } -func keyMatchesQuery(key []byte, query store.Query) bool { +func keyMatchesQuery(key []byte, query database.Query) bool { // Ignore invalid keys, we don't expect to find them. id, err := idFromKey(key) if err != nil { return false } - return storeutil.IDMatchesQuery(id, query) + return databaseutil.IDMatchesQuery(id, query) } diff --git a/pkg/ucp/store/etcdstore/etcdclient_test.go b/pkg/ucp/database/etcdstore/etcdclient_test.go similarity index 100% rename from pkg/ucp/store/etcdstore/etcdclient_test.go rename to pkg/ucp/database/etcdstore/etcdclient_test.go diff --git a/pkg/ucp/store/filter.go b/pkg/ucp/database/filter.go similarity index 99% rename from pkg/ucp/store/filter.go rename to pkg/ucp/database/filter.go index 7288aba2c9..7a99ada2e6 100644 --- a/pkg/ucp/store/filter.go +++ b/pkg/ucp/database/filter.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package store +package database import ( "reflect" diff --git a/pkg/ucp/store/filter_test.go b/pkg/ucp/database/filter_test.go similarity index 99% rename from pkg/ucp/store/filter_test.go rename to pkg/ucp/database/filter_test.go index c31aa7fcac..0c80924193 100644 --- a/pkg/ucp/store/filter_test.go +++ b/pkg/ucp/database/filter_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package store +package database import ( "testing" diff --git a/pkg/ucp/store/inmemory/client.go b/pkg/ucp/database/inmemory/client.go similarity index 63% rename from pkg/ucp/store/inmemory/client.go rename to pkg/ucp/database/inmemory/client.go index 97adc07337..9b9ac141e9 100644 --- a/pkg/ucp/store/inmemory/client.go +++ b/pkg/ucp/database/inmemory/client.go @@ -23,16 +23,16 @@ import ( "strings" "sync" + "github.com/radius-project/radius/pkg/ucp/database" + "github.com/radius-project/radius/pkg/ucp/database/databaseutil" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" - "github.com/radius-project/radius/pkg/ucp/store/storeutil" "github.com/radius-project/radius/pkg/ucp/util/etag" "golang.org/x/exp/maps" ) -var _ store.StorageClient = (*Client)(nil) +var _ database.Client = (*Client)(nil) -// Client is an in-memory implementation of store.StorageClient. +// Client is an in-memory implementation of database.Client. type Client struct { // mutex is used to synchronize access to the resources map. mutex sync.Mutex @@ -67,7 +67,7 @@ type Client struct { // All fields are compared case-insensitively. type entry struct { // obj stores the object data. - obj store.Object + obj database.Object // rootScope is the root scope of the resource ID. rootScope string @@ -87,23 +87,23 @@ func NewClient() *Client { } } -// Get implements store.StorageClient. -func (c *Client) Get(ctx context.Context, id string, options ...store.GetOptions) (*store.Object, error) { +// Get implements database.Client. +func (c *Client) Get(ctx context.Context, id string, options ...database.GetOptions) (*database.Object, error) { if ctx == nil { - return nil, &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } parsed, err := resources.Parse(id) if err != nil { - return nil, &store.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} } if parsed.IsEmpty() { - return nil, &store.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} } if parsed.IsResourceCollection() || parsed.IsScopeCollection() { - return nil, &store.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} } - converted, err := storeutil.ConvertScopeIDToResourceID(parsed) + converted, err := databaseutil.ConvertScopeIDToResourceID(parsed) if err != nil { return nil, err } @@ -113,7 +113,7 @@ func (c *Client) Get(ctx context.Context, id string, options ...store.GetOptions entry, ok := c.resources[strings.ToLower(converted.String())] if !ok { - return nil, &store.ErrNotFound{ID: id} + return nil, &database.ErrNotFound{ID: id} } // Make a defensive copy so users can't modify the data in the store. @@ -125,23 +125,23 @@ func (c *Client) Get(ctx context.Context, id string, options ...store.GetOptions return copy, nil } -// Delete implements store.StorageClient. -func (c *Client) Delete(ctx context.Context, id string, options ...store.DeleteOptions) error { +// Delete implements database.Client. +func (c *Client) Delete(ctx context.Context, id string, options ...database.DeleteOptions) error { if ctx == nil { - return &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } parsed, err := resources.Parse(id) if err != nil { - return &store.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} + return &database.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} } if parsed.IsEmpty() { - return &store.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} + return &database.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} } if parsed.IsResourceCollection() || parsed.IsScopeCollection() { - return &store.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} + return &database.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} } - converted, err := storeutil.ConvertScopeIDToResourceID(parsed) + converted, err := databaseutil.ConvertScopeIDToResourceID(parsed) if err != nil { return err } @@ -149,15 +149,15 @@ func (c *Client) Delete(ctx context.Context, id string, options ...store.DeleteO c.mutex.Lock() defer c.mutex.Unlock() - config := store.NewDeleteConfig(options...) + config := database.NewDeleteConfig(options...) entry, ok := c.resources[strings.ToLower(converted.String())] if !ok && config.ETag != "" { - return &store.ErrConcurrency{} + return &database.ErrConcurrency{} } else if !ok { - return &store.ErrNotFound{ID: id} + return &database.ErrNotFound{ID: id} } else if config.ETag != "" && config.ETag != entry.obj.ETag { - return &store.ErrConcurrency{} + return &database.ErrConcurrency{} } delete(c.resources, strings.ToLower(converted.String())) @@ -165,40 +165,40 @@ func (c *Client) Delete(ctx context.Context, id string, options ...store.DeleteO return nil } -// Query implements store.StorageClient. -func (c *Client) Query(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { +// Query implements database.Client. +func (c *Client) Query(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { if ctx == nil { - return nil, &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } err := query.Validate() if err != nil { - return nil, &store.ErrInvalid{Message: fmt.Sprintf("invalid argument. Query is invalid: %s", err.Error())} + return nil, &database.ErrInvalid{Message: fmt.Sprintf("invalid argument. Query is invalid: %s", err.Error())} } c.mutex.Lock() defer c.mutex.Unlock() - result := &store.ObjectQueryResult{} + result := &database.ObjectQueryResult{} for _, entry := range c.resources { // Check root scope. - if query.ScopeRecursive && !strings.HasPrefix(entry.rootScope, storeutil.NormalizePart(query.RootScope)) { + if query.ScopeRecursive && !strings.HasPrefix(entry.rootScope, databaseutil.NormalizePart(query.RootScope)) { continue - } else if !query.ScopeRecursive && entry.rootScope != storeutil.NormalizePart(query.RootScope) { + } else if !query.ScopeRecursive && entry.rootScope != databaseutil.NormalizePart(query.RootScope) { continue } // Check resource type. - resourceType, err := storeutil.ConvertScopeTypeToResourceType(query.ResourceType) + resourceType, err := databaseutil.ConvertScopeTypeToResourceType(query.ResourceType) if err != nil { return nil, err } - if entry.resourceType != storeutil.NormalizePart(resourceType) { + if entry.resourceType != databaseutil.NormalizePart(resourceType) { continue } // Check routing scope prefix (optional). - if query.RoutingScopePrefix != "" && !strings.HasPrefix(entry.routingScope, storeutil.NormalizePart(query.RoutingScopePrefix)) { + if query.RoutingScopePrefix != "" && !strings.HasPrefix(entry.routingScope, databaseutil.NormalizePart(query.RoutingScopePrefix)) { continue } @@ -223,21 +223,21 @@ func (c *Client) Query(ctx context.Context, query store.Query, options ...store. return result, nil } -// Save implements store.StorageClient. -func (c *Client) Save(ctx context.Context, obj *store.Object, options ...store.SaveOptions) error { +// Save implements database.Client. +func (c *Client) Save(ctx context.Context, obj *database.Object, options ...database.SaveOptions) error { if ctx == nil { - return &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } if obj == nil { - return &store.ErrInvalid{Message: "invalid argument. 'obj' is required"} + return &database.ErrInvalid{Message: "invalid argument. 'obj' is required"} } parsed, err := resources.Parse(obj.ID) if err != nil { - return &store.ErrInvalid{Message: "invalid argument. 'obj.ID' must be a valid resource id"} + return &database.ErrInvalid{Message: "invalid argument. 'obj.ID' must be a valid resource id"} } - converted, err := storeutil.ConvertScopeIDToResourceID(parsed) + converted, err := databaseutil.ConvertScopeIDToResourceID(parsed) if err != nil { return err } @@ -245,18 +245,18 @@ func (c *Client) Save(ctx context.Context, obj *store.Object, options ...store.S c.mutex.Lock() defer c.mutex.Unlock() - config := store.NewSaveConfig(options...) + config := database.NewSaveConfig(options...) entry, ok := c.resources[strings.ToLower(converted.String())] if !ok && config.ETag != "" { - return &store.ErrConcurrency{} + return &database.ErrConcurrency{} } else if ok && config.ETag != "" && config.ETag != entry.obj.ETag { - return &store.ErrConcurrency{} + return &database.ErrConcurrency{} } else if !ok { // New entry, initialize it. - entry.rootScope = storeutil.NormalizePart(converted.RootScope()) - entry.resourceType = storeutil.NormalizePart(converted.Type()) - entry.routingScope = storeutil.NormalizePart(converted.RoutingScope()) + entry.rootScope = databaseutil.NormalizePart(converted.RootScope()) + entry.resourceType = databaseutil.NormalizePart(converted.Type()) + entry.routingScope = databaseutil.NormalizePart(converted.RoutingScope()) } raw, err := json.Marshal(obj.Data) diff --git a/pkg/ucp/store/inmemory/client_test.go b/pkg/ucp/database/inmemory/client_test.go similarity index 100% rename from pkg/ucp/store/inmemory/client_test.go rename to pkg/ucp/database/inmemory/client_test.go diff --git a/pkg/ucp/store/inmemory/doc.go b/pkg/ucp/database/inmemory/doc.go similarity index 100% rename from pkg/ucp/store/inmemory/doc.go rename to pkg/ucp/database/inmemory/doc.go diff --git a/pkg/ucp/store/map.go b/pkg/ucp/database/map.go similarity index 98% rename from pkg/ucp/store/map.go rename to pkg/ucp/database/map.go index ab236e8f3f..b0578ed6e8 100644 --- a/pkg/ucp/store/map.go +++ b/pkg/ucp/database/map.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package store +package database import ( "reflect" diff --git a/pkg/ucp/store/map_test.go b/pkg/ucp/database/map_test.go similarity index 99% rename from pkg/ucp/store/map_test.go rename to pkg/ucp/database/map_test.go index fd99198bcd..b1c1918786 100644 --- a/pkg/ucp/store/map_test.go +++ b/pkg/ucp/database/map_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package store +package database import ( "encoding/json" diff --git a/pkg/ucp/database/mock_client.go b/pkg/ucp/database/mock_client.go new file mode 100644 index 0000000000..5a3a7b3939 --- /dev/null +++ b/pkg/ucp/database/mock_client.go @@ -0,0 +1,214 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/radius-project/radius/pkg/ucp/database (interfaces: Client) +// +// Generated by this command: +// +// mockgen -typed -destination=./mock_client.go -package=database -self_package github.com/radius-project/radius/pkg/ucp/database github.com/radius-project/radius/pkg/ucp/database Client +// + +// Package database is a generated GoMock package. +package database + +import ( + context "context" + reflect "reflect" + + gomock "go.uber.org/mock/gomock" +) + +// MockClient is a mock of Client interface. +type MockClient struct { + ctrl *gomock.Controller + recorder *MockClientMockRecorder +} + +// MockClientMockRecorder is the mock recorder for MockClient. +type MockClientMockRecorder struct { + mock *MockClient +} + +// NewMockClient creates a new mock instance. +func NewMockClient(ctrl *gomock.Controller) *MockClient { + mock := &MockClient{ctrl: ctrl} + mock.recorder = &MockClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockClient) EXPECT() *MockClientMockRecorder { + return m.recorder +} + +// Delete mocks base method. +func (m *MockClient) Delete(arg0 context.Context, arg1 string, arg2 ...DeleteOptions) error { + m.ctrl.T.Helper() + varargs := []any{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Delete", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// Delete indicates an expected call of Delete. +func (mr *MockClientMockRecorder) Delete(arg0, arg1 any, arg2 ...any) *MockClientDeleteCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{arg0, arg1}, arg2...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockClient)(nil).Delete), varargs...) + return &MockClientDeleteCall{Call: call} +} + +// MockClientDeleteCall wrap *gomock.Call +type MockClientDeleteCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockClientDeleteCall) Return(arg0 error) *MockClientDeleteCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockClientDeleteCall) Do(f func(context.Context, string, ...DeleteOptions) error) *MockClientDeleteCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockClientDeleteCall) DoAndReturn(f func(context.Context, string, ...DeleteOptions) error) *MockClientDeleteCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Get mocks base method. +func (m *MockClient) Get(arg0 context.Context, arg1 string, arg2 ...GetOptions) (*Object, error) { + m.ctrl.T.Helper() + varargs := []any{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Get", varargs...) + ret0, _ := ret[0].(*Object) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockClientMockRecorder) Get(arg0, arg1 any, arg2 ...any) *MockClientGetCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{arg0, arg1}, arg2...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockClient)(nil).Get), varargs...) + return &MockClientGetCall{Call: call} +} + +// MockClientGetCall wrap *gomock.Call +type MockClientGetCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockClientGetCall) Return(arg0 *Object, arg1 error) *MockClientGetCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockClientGetCall) Do(f func(context.Context, string, ...GetOptions) (*Object, error)) *MockClientGetCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockClientGetCall) DoAndReturn(f func(context.Context, string, ...GetOptions) (*Object, error)) *MockClientGetCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Query mocks base method. +func (m *MockClient) Query(arg0 context.Context, arg1 Query, arg2 ...QueryOptions) (*ObjectQueryResult, error) { + m.ctrl.T.Helper() + varargs := []any{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Query", varargs...) + ret0, _ := ret[0].(*ObjectQueryResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Query indicates an expected call of Query. +func (mr *MockClientMockRecorder) Query(arg0, arg1 any, arg2 ...any) *MockClientQueryCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{arg0, arg1}, arg2...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockClient)(nil).Query), varargs...) + return &MockClientQueryCall{Call: call} +} + +// MockClientQueryCall wrap *gomock.Call +type MockClientQueryCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockClientQueryCall) Return(arg0 *ObjectQueryResult, arg1 error) *MockClientQueryCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockClientQueryCall) Do(f func(context.Context, Query, ...QueryOptions) (*ObjectQueryResult, error)) *MockClientQueryCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockClientQueryCall) DoAndReturn(f func(context.Context, Query, ...QueryOptions) (*ObjectQueryResult, error)) *MockClientQueryCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Save mocks base method. +func (m *MockClient) Save(arg0 context.Context, arg1 *Object, arg2 ...SaveOptions) error { + m.ctrl.T.Helper() + varargs := []any{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Save", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// Save indicates an expected call of Save. +func (mr *MockClientMockRecorder) Save(arg0, arg1 any, arg2 ...any) *MockClientSaveCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{arg0, arg1}, arg2...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Save", reflect.TypeOf((*MockClient)(nil).Save), varargs...) + return &MockClientSaveCall{Call: call} +} + +// MockClientSaveCall wrap *gomock.Call +type MockClientSaveCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockClientSaveCall) Return(arg0 error) *MockClientSaveCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockClientSaveCall) Do(f func(context.Context, *Object, ...SaveOptions) error) *MockClientSaveCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockClientSaveCall) DoAndReturn(f func(context.Context, *Object, ...SaveOptions) error) *MockClientSaveCall { + c.Call = c.Call.DoAndReturn(f) + return c +} diff --git a/pkg/ucp/store/object.go b/pkg/ucp/database/object.go similarity index 87% rename from pkg/ucp/store/object.go rename to pkg/ucp/database/object.go index e006ecfe56..2b9ea08dd5 100644 --- a/pkg/ucp/store/object.go +++ b/pkg/ucp/database/object.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package store +package database import ( "context" @@ -70,11 +70,11 @@ func (o *Object) As(out any) error { return DecodeMap(o.Data, out) } -// GetResource gets the resource data from StorageClient for id. -func GetResource[T any](ctx context.Context, client StorageClient, id string) (*T, error) { +// GetResource gets the resource data for the provided resource id using the provided client. +func GetResource[T any](ctx context.Context, databaseClient Client, id string) (*T, error) { var out T - obj, err := client.Get(ctx, id) + obj, err := databaseClient.Get(ctx, id) if err != nil { return nil, err } diff --git a/pkg/ucp/store/options.go b/pkg/ucp/database/options.go similarity index 77% rename from pkg/ucp/store/options.go rename to pkg/ucp/database/options.go index 4d80eba2a0..35ac3072ae 100644 --- a/pkg/ucp/store/options.go +++ b/pkg/ucp/database/options.go @@ -14,12 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -package store +package database type ( // QueryOptions applies an option to Query(). QueryOptions interface { - ApplyQueryOption(StoreConfig) StoreConfig + ApplyQueryOption(DatabaseOptions) DatabaseOptions // A private method to prevent users implementing the // interface and so future additions to it will not @@ -37,7 +37,7 @@ type ( // DeleteOptions applies an option to Delete(). DeleteOptions interface { - ApplyDeleteOption(StoreConfig) StoreConfig + ApplyDeleteOption(DatabaseOptions) DatabaseOptions // A private method to prevent users implementing the // interface and so future additions to it will not @@ -47,7 +47,7 @@ type ( // SaveOptions applies an option to Save(). SaveOptions interface { - ApplySaveOption(StoreConfig) StoreConfig + ApplySaveOption(DatabaseOptions) DatabaseOptions // A private method to prevent users implementing the // interface and so future additions to it will not @@ -62,8 +62,8 @@ type ( } ) -// Store Config represents the configurations of storageclient APIs. -type StoreConfig struct { +// DatabaseOptions represents the configurations of the underlying database APIs. +type DatabaseOptions struct { // PaginationToken represents pagination token such as continuation token. PaginationToken string @@ -76,11 +76,11 @@ type StoreConfig struct { // Query Options type queryOptions struct { - fn func(StoreConfig) StoreConfig + fn func(DatabaseOptions) DatabaseOptions } // ApplyQueryOption applies a function to the StoreConfig to modify it. -func (q *queryOptions) ApplyQueryOption(cfg StoreConfig) StoreConfig { +func (q *queryOptions) ApplyQueryOption(cfg DatabaseOptions) DatabaseOptions { return q.fn(cfg) } @@ -89,7 +89,7 @@ func (q queryOptions) private() {} // WithPaginationToken sets pagination token for Query(). func WithPaginationToken(token string) QueryOptions { return &queryOptions{ - fn: func(cfg StoreConfig) StoreConfig { + fn: func(cfg DatabaseOptions) DatabaseOptions { cfg.PaginationToken = token return cfg }, @@ -99,7 +99,7 @@ func WithPaginationToken(token string) QueryOptions { // WithMaxQueryItemCount creates a QueryOptions instance that sets the maximum number of items in query result. func WithMaxQueryItemCount(maxcnt int) QueryOptions { return &queryOptions{ - fn: func(cfg StoreConfig) StoreConfig { + fn: func(cfg DatabaseOptions) DatabaseOptions { cfg.MaxQueryItemCount = maxcnt return cfg }, @@ -108,19 +108,19 @@ func WithMaxQueryItemCount(maxcnt int) QueryOptions { // MutatingOptions type mutatingOptions struct { - fn func(StoreConfig) StoreConfig + fn func(DatabaseOptions) DatabaseOptions } var _ DeleteOptions = (*mutatingOptions)(nil) var _ SaveOptions = (*mutatingOptions)(nil) // ApplyDeleteOption applies the delete option to the given StoreConfig and returns the modified StoreConfig. -func (s *mutatingOptions) ApplyDeleteOption(cfg StoreConfig) StoreConfig { +func (s *mutatingOptions) ApplyDeleteOption(cfg DatabaseOptions) DatabaseOptions { return s.fn(cfg) } // ApplySaveOption applies the save option to the given StoreConfig and returns the modified StoreConfig. -func (s *mutatingOptions) ApplySaveOption(cfg StoreConfig) StoreConfig { +func (s *mutatingOptions) ApplySaveOption(cfg DatabaseOptions) DatabaseOptions { return s.fn(cfg) } @@ -128,13 +128,13 @@ func (s mutatingOptions) private() {} // SaveOptions type saveOptions struct { - fn func(StoreConfig) StoreConfig + fn func(DatabaseOptions) DatabaseOptions } var _ SaveOptions = (*saveOptions)(nil) // ApplySaveOption applies a save option to a StoreConfig. -func (s *saveOptions) ApplySaveOption(cfg StoreConfig) StoreConfig { +func (s *saveOptions) ApplySaveOption(cfg DatabaseOptions) DatabaseOptions { return s.fn(cfg) } @@ -143,7 +143,7 @@ func (s saveOptions) private() {} // WithETag sets the ETag field in the StoreConfig struct. func WithETag(etag ETag) MutatingOptions { return &mutatingOptions{ - fn: func(cfg StoreConfig) StoreConfig { + fn: func(cfg DatabaseOptions) DatabaseOptions { cfg.ETag = etag return cfg }, @@ -151,8 +151,8 @@ func WithETag(etag ETag) MutatingOptions { } // NewQueryConfig applies a set of QueryOptions to a StoreConfig and returns the modified StoreConfig for Query(). -func NewQueryConfig(opts ...QueryOptions) StoreConfig { - cfg := StoreConfig{} +func NewQueryConfig(opts ...QueryOptions) DatabaseOptions { + cfg := DatabaseOptions{} for _, opt := range opts { cfg = opt.ApplyQueryOption(cfg) } @@ -160,8 +160,8 @@ func NewQueryConfig(opts ...QueryOptions) StoreConfig { } // NewDeleteConfig applies the given DeleteOptions to a StoreConfig and returns the resulting StoreConfig for Delete(). -func NewDeleteConfig(opts ...DeleteOptions) StoreConfig { - cfg := StoreConfig{} +func NewDeleteConfig(opts ...DeleteOptions) DatabaseOptions { + cfg := DatabaseOptions{} for _, opt := range opts { cfg = opt.ApplyDeleteOption(cfg) } @@ -169,8 +169,8 @@ func NewDeleteConfig(opts ...DeleteOptions) StoreConfig { } // NewSaveConfig applies a set of SaveOptions to a StoreConfig and returns the modified StoreConfig for Save(). -func NewSaveConfig(opts ...SaveOptions) StoreConfig { - cfg := StoreConfig{} +func NewSaveConfig(opts ...SaveOptions) DatabaseOptions { + cfg := DatabaseOptions{} for _, opt := range opts { cfg = opt.ApplySaveOption(cfg) } diff --git a/pkg/ucp/store/postgres/postgresclient.go b/pkg/ucp/database/postgres/postgresclient.go similarity index 70% rename from pkg/ucp/store/postgres/postgresclient.go rename to pkg/ucp/database/postgres/postgresclient.go index bdab94f031..d5dbb681db 100644 --- a/pkg/ucp/store/postgres/postgresclient.go +++ b/pkg/ucp/database/postgres/postgresclient.go @@ -27,9 +27,9 @@ import ( "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgconn" "github.com/radius-project/radius/pkg/to" + "github.com/radius-project/radius/pkg/ucp/database" + "github.com/radius-project/radius/pkg/ucp/database/databaseutil" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" - "github.com/radius-project/radius/pkg/ucp/store/storeutil" "github.com/radius-project/radius/pkg/ucp/util/etag" ) @@ -50,36 +50,36 @@ func NewPostgresClient(api PostgresAPI) *PostgresClient { return &PostgresClient{api: api} } -var _ store.StorageClient = (*PostgresClient)(nil) +var _ database.Client = (*PostgresClient)(nil) -// PostgresClient is a storage client that uses Postgres as the backend. +// PostgresClient is a database client that uses Postgres as the backend. type PostgresClient struct { api PostgresAPI } -// Delete implements store.StorageClient. -func (p *PostgresClient) Delete(ctx context.Context, id string, options ...store.DeleteOptions) error { +// Delete implements database.Client. +func (p *PostgresClient) Delete(ctx context.Context, id string, options ...database.DeleteOptions) error { if ctx == nil { - return &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } parsed, err := resources.Parse(id) if err != nil { - return &store.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} + return &database.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} } if parsed.IsEmpty() { - return &store.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} + return &database.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} } if parsed.IsResourceCollection() || parsed.IsScopeCollection() { - return &store.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} + return &database.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} } - converted, err := storeutil.ConvertScopeIDToResourceID(parsed) + converted, err := databaseutil.ConvertScopeIDToResourceID(parsed) if err != nil { return err } - config := store.NewDeleteConfig(options...) + config := database.NewDeleteConfig(options...) var etag *string if config.ETag != "" { etag = &config.ETag @@ -101,7 +101,7 @@ CASE ELSE 'ErrNotFound' END AS result;` - args := []any{storeutil.NormalizePart(converted.String())} + args := []any{databaseutil.NormalizePart(converted.String())} if config.ETag != "" { // NOTE: we want to report ErrConcurrency for all failure cases here. This is what the tests do. @@ -118,7 +118,7 @@ CASE ELSE 'ErrConcurrency' END AS result;` - args = []any{storeutil.NormalizePart(converted.String()), etag} + args = []any{databaseutil.NormalizePart(converted.String()), etag} } result := "" @@ -126,43 +126,43 @@ END AS result;` if err != nil { return err } else if result == "ErrNotFound" { - return &store.ErrNotFound{ID: id} + return &database.ErrNotFound{ID: id} } else if result == "ErrConcurrency" { - return &store.ErrConcurrency{} + return &database.ErrConcurrency{} } return nil } -// Get implements store.StorageClient. -func (p *PostgresClient) Get(ctx context.Context, id string, options ...store.GetOptions) (*store.Object, error) { +// Get implements database.Client. +func (p *PostgresClient) Get(ctx context.Context, id string, options ...database.GetOptions) (*database.Object, error) { if ctx == nil { - return nil, &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } parsed, err := resources.Parse(id) if err != nil { - return nil, &store.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'id' must be a valid resource id"} } if parsed.IsEmpty() { - return nil, &store.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'id' must not be empty"} } if parsed.IsResourceCollection() || parsed.IsScopeCollection() { - return nil, &store.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'id' must refer to a named resource, not a collection"} } - converted, err := storeutil.ConvertScopeIDToResourceID(parsed) + converted, err := databaseutil.ConvertScopeIDToResourceID(parsed) if err != nil { return nil, err } - obj := store.Object{} + obj := database.Object{} err = p.api.QueryRow( ctx, "SELECT original_id, etag, resource_data FROM resources WHERE id = $1", - storeutil.NormalizePart(converted.String())).Scan(&obj.ID, &obj.ETag, &obj.Data) + databaseutil.NormalizePart(converted.String())).Scan(&obj.ID, &obj.ETag, &obj.Data) if errors.Is(err, pgx.ErrNoRows) { - return nil, &store.ErrNotFound{ID: id} + return nil, &database.ErrNotFound{ID: id} } else if err != nil { return nil, err } @@ -170,41 +170,41 @@ func (p *PostgresClient) Get(ctx context.Context, id string, options ...store.Ge return &obj, nil } -// Query implements store.StorageClient. -func (p *PostgresClient) Query(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { +// Query implements database.Client. +func (p *PostgresClient) Query(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { if ctx == nil { - return nil, &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return nil, &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } err := query.Validate() if err != nil { - return nil, &store.ErrInvalid{Message: fmt.Sprintf("invalid argument. Query is invalid: %s", err.Error())} + return nil, &database.ErrInvalid{Message: fmt.Sprintf("invalid argument. Query is invalid: %s", err.Error())} } - config := store.NewQueryConfig(options...) + config := database.NewQueryConfig(options...) // For a scope query, we need to perform the same normalization as we do for other operations on scopes. - resourceType := storeutil.NormalizePart(query.ResourceType) + resourceType := databaseutil.NormalizePart(query.ResourceType) if query.IsScopeQuery { var err error - resourceType, err = storeutil.ConvertScopeTypeToResourceType(query.ResourceType) + resourceType, err = databaseutil.ConvertScopeTypeToResourceType(query.ResourceType) if err != nil { return nil, err } - resourceType = storeutil.NormalizePart(resourceType) + resourceType = databaseutil.NormalizePart(resourceType) } var routingScopePrefixFilter *string if query.RoutingScopePrefix != "" { - routingScopePrefixFilter = to.Ptr(storeutil.NormalizePart(query.RoutingScopePrefix)) + routingScopePrefixFilter = to.Ptr(databaseutil.NormalizePart(query.RoutingScopePrefix)) } var timestampFilter *string if config.PaginationToken != "" { ts, err := p.parsePaginationToken(config.PaginationToken) if err != nil { - return nil, &store.ErrInvalid{Message: "invalid argument. 'query.PaginationToken' is invalid."} + return nil, &database.ErrInvalid{Message: "invalid argument. 'query.PaginationToken' is invalid."} } timestampFilter = &ts } @@ -217,7 +217,7 @@ func (p *PostgresClient) Query(ctx context.Context, query store.Query, options . // For a scope query, we need to perform the same normalization as we do for other operations on scopes. if query.IsScopeQuery { var err error - query.ResourceType, err = storeutil.ConvertScopeTypeToResourceType(query.ResourceType) + query.ResourceType, err = databaseutil.ConvertScopeTypeToResourceType(query.ResourceType) if err != nil { return nil, err } @@ -239,7 +239,7 @@ LIMIT $6` args := []any{ // If ScopeRecursive is false, the RootScope must match exactly. // If ScopeRecursive is true, the RootScope must be a prefix of the stored RootScope. - storeutil.NormalizePart(query.RootScope), + databaseutil.NormalizePart(query.RootScope), query.ScopeRecursive, resourceType, routingScopePrefixFilter, // RoutingScopePrefix is optional and always treated as as prefix. @@ -256,9 +256,9 @@ LIMIT $6` // Capture the last timestamp so we can use it for pagination. var timestamp *time.Time - result := store.ObjectQueryResult{} + result := database.ObjectQueryResult{} for rows.Next() { - obj := store.Object{} + obj := database.Object{} err := rows.Scan(&obj.ID, &obj.ETag, &obj.Data, ×tamp) if err != nil { return nil, err @@ -300,32 +300,32 @@ LIMIT $6` return &result, nil } -// Save implements store.StorageClient. -func (p *PostgresClient) Save(ctx context.Context, obj *store.Object, options ...store.SaveOptions) error { +// Save implements database.Client. +func (p *PostgresClient) Save(ctx context.Context, obj *database.Object, options ...database.SaveOptions) error { if ctx == nil { - return &store.ErrInvalid{Message: "invalid argument. 'ctx' is required"} + return &database.ErrInvalid{Message: "invalid argument. 'ctx' is required"} } if obj == nil { - return &store.ErrInvalid{Message: "invalid argument. 'obj' is required"} + return &database.ErrInvalid{Message: "invalid argument. 'obj' is required"} } parsed, err := resources.Parse(obj.ID) if err != nil { - return &store.ErrInvalid{Message: "invalid argument. 'obj.ID' must be a valid resource id"} + return &database.ErrInvalid{Message: "invalid argument. 'obj.ID' must be a valid resource id"} } if parsed.IsEmpty() { - return &store.ErrInvalid{Message: "invalid argument. 'obj.ID' must not be empty"} + return &database.ErrInvalid{Message: "invalid argument. 'obj.ID' must not be empty"} } if parsed.IsResourceCollection() || parsed.IsScopeCollection() { - return &store.ErrInvalid{Message: "invalid argument. 'obj.ID' must refer to a named resource, not a collection"} + return &database.ErrInvalid{Message: "invalid argument. 'obj.ID' must refer to a named resource, not a collection"} } - converted, err := storeutil.ConvertScopeIDToResourceID(parsed) + converted, err := databaseutil.ConvertScopeIDToResourceID(parsed) if err != nil { return err } - config := store.NewSaveConfig(options...) + config := database.NewSaveConfig(options...) // Compute ETag for the current state of the object. raw, err := json.Marshal(obj.Data) @@ -356,11 +356,11 @@ CASE END AS result;` args := []any{ - storeutil.NormalizePart(converted.String()), + databaseutil.NormalizePart(converted.String()), obj.ID, // MUST NOT BE NORMALIZED. Preserve the original casing and format. - storeutil.NormalizePart(converted.Type()), - storeutil.NormalizePart(converted.RootScope()), - storeutil.NormalizePart(converted.RoutingScope()), + databaseutil.NormalizePart(converted.Type()), + databaseutil.NormalizePart(converted.RootScope()), + databaseutil.NormalizePart(converted.RoutingScope()), obj.ETag, obj.Data, } @@ -381,7 +381,7 @@ CASE ELSE 'ErrConcurrency' END AS result;` - args = []any{storeutil.NormalizePart(converted.String()), obj.Data, config.ETag} + args = []any{databaseutil.NormalizePart(converted.String()), obj.Data, config.ETag} } result := "" @@ -389,9 +389,9 @@ END AS result;` if err != nil { return err } else if result == "ErrNotFound" { - return &store.ErrNotFound{ID: obj.ID} + return &database.ErrNotFound{ID: obj.ID} } else if result == "ErrConcurrency" { - return &store.ErrConcurrency{} + return &database.ErrConcurrency{} } return nil diff --git a/pkg/ucp/store/postgres/postgresclient_test.go b/pkg/ucp/database/postgres/postgresclient_test.go similarity index 100% rename from pkg/ucp/store/postgres/postgresclient_test.go rename to pkg/ucp/database/postgres/postgresclient_test.go diff --git a/pkg/ucp/store/resources.go b/pkg/ucp/database/resources.go similarity index 97% rename from pkg/ucp/store/resources.go rename to pkg/ucp/database/resources.go index ecefd07a68..f1dbc3be89 100644 --- a/pkg/ucp/store/resources.go +++ b/pkg/ucp/database/resources.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package store +package database const ( UCPScopePrefix = "scope" diff --git a/pkg/ucp/dataprovider/factory.go b/pkg/ucp/databaseprovider/factory.go similarity index 74% rename from pkg/ucp/dataprovider/factory.go rename to pkg/ucp/databaseprovider/factory.go index e879339d2b..4f02132430 100644 --- a/pkg/ucp/dataprovider/factory.go +++ b/pkg/ucp/databaseprovider/factory.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package dataprovider +package databaseprovider import ( context "context" @@ -24,28 +24,28 @@ import ( "github.com/jackc/pgx/v5/pgxpool" "github.com/radius-project/radius/pkg/kubeutil" - store "github.com/radius-project/radius/pkg/ucp/store" - "github.com/radius-project/radius/pkg/ucp/store/apiserverstore" - ucpv1alpha1 "github.com/radius-project/radius/pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1" - "github.com/radius-project/radius/pkg/ucp/store/etcdstore" - "github.com/radius-project/radius/pkg/ucp/store/inmemory" - "github.com/radius-project/radius/pkg/ucp/store/postgres" + store "github.com/radius-project/radius/pkg/ucp/database" + "github.com/radius-project/radius/pkg/ucp/database/apiserverstore" + ucpv1alpha1 "github.com/radius-project/radius/pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1" + "github.com/radius-project/radius/pkg/ucp/database/etcdstore" + "github.com/radius-project/radius/pkg/ucp/database/inmemory" + "github.com/radius-project/radius/pkg/ucp/database/postgres" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/rest" runtimeclient "sigs.k8s.io/controller-runtime/pkg/client" ) -type storageFactoryFunc func(ctx context.Context, options StorageProviderOptions) (store.StorageClient, error) +type databaseClientFactoryFunc func(ctx context.Context, options Options) (store.Client, error) -var storageClientFactory = map[StorageProviderType]storageFactoryFunc{ +var databaseClientFactory = map[DatabaseProviderType]databaseClientFactoryFunc{ TypeAPIServer: initAPIServerClient, TypeETCD: InitETCDClient, TypeInMemory: initInMemoryClient, TypePostgreSQL: initPostgreSQLClient, } -func initAPIServerClient(ctx context.Context, opt StorageProviderOptions) (store.StorageClient, error) { +func initAPIServerClient(ctx context.Context, opt Options) (store.Client, error) { if opt.APIServer.Namespace == "" { return nil, errors.New("failed to initialize APIServer client: namespace is required") } @@ -81,9 +81,9 @@ func initAPIServerClient(ctx context.Context, opt StorageProviderOptions) (store return client, nil } -// InitETCDClient checks if the ETCD client is in memory and if the client is not nil, then it initializes the storage +// InitETCDClient checks if the ETCD client is in memory and if the client is not nil, then it initializes the database // client and returns an ETCDClient. If either of these conditions are not met, an error is returned. -func InitETCDClient(ctx context.Context, opt StorageProviderOptions) (store.StorageClient, error) { +func InitETCDClient(ctx context.Context, opt Options) (store.Client, error) { if !opt.ETCD.InMemory { return nil, errors.New("failed to initialize etcd client: inmemory is the only supported mode for now") } @@ -91,7 +91,7 @@ func InitETCDClient(ctx context.Context, opt StorageProviderOptions) (store.Stor return nil, errors.New("failed to initialize etcd client: ETCDOptions.Client is nil, this is a bug") } - // Initialize the storage client once the storage service has started + // Initialize the database client once the etcd service has started client, err := opt.ETCD.Client.Get(ctx) if err != nil { return nil, fmt.Errorf("failed to initialize etcd client: %w", err) @@ -102,12 +102,12 @@ func InitETCDClient(ctx context.Context, opt StorageProviderOptions) (store.Stor } // initInMemoryClient creates a new in-memory store client. -func initInMemoryClient(ctx context.Context, opt StorageProviderOptions) (store.StorageClient, error) { +func initInMemoryClient(ctx context.Context, opt Options) (store.Client, error) { return inmemory.NewClient(), nil } // initPostgreSQLClient creates a new PostgreSQL store client. -func initPostgreSQLClient(ctx context.Context, opt StorageProviderOptions) (store.StorageClient, error) { +func initPostgreSQLClient(ctx context.Context, opt Options) (store.Client, error) { if opt.PostgreSQL.URL == "" { return nil, errors.New("failed to initialize PostgreSQL client: URL is required") } diff --git a/pkg/ucp/dataprovider/options.go b/pkg/ucp/databaseprovider/options.go similarity index 81% rename from pkg/ucp/dataprovider/options.go rename to pkg/ucp/databaseprovider/options.go index 95f99d323b..249e1b6447 100644 --- a/pkg/ucp/dataprovider/options.go +++ b/pkg/ucp/databaseprovider/options.go @@ -14,24 +14,21 @@ See the License for the specific language governing permissions and limitations under the License. */ -package dataprovider +package databaseprovider import ( "github.com/radius-project/radius/pkg/ucp/hosting" etcdclient "go.etcd.io/etcd/client/v3" ) -// StorageProviderOptions represents the data storage provider options. -type StorageProviderOptions struct { - // Provider configures the storage provider. - Provider StorageProviderType `yaml:"provider"` +// Options represents the database provider options. +type Options struct { + // Provider configures the database provider. + Provider DatabaseProviderType `yaml:"provider"` // APIServer configures options for the Kubernetes APIServer store. Will be ignored if another store is configured. APIServer APIServerOptions `yaml:"apiserver,omitempty"` - // CosmosDB configures options for the CosmosDB store. Will be ignored if another store is configured. - CosmosDB CosmosDBOptions `yaml:"cosmosdb,omitempty"` - // ETCD configures options for the etcd store. Will be ignored if another store is configured. ETCD ETCDOptions `yaml:"etcd,omitempty"` @@ -52,14 +49,6 @@ type APIServerOptions struct { Namespace string `yaml:"namespace"` } -// CosmosDBOptions represents cosmosdb options for data storage provider. -type CosmosDBOptions struct { - Url string `yaml:"url"` - Database string `yaml:"database"` - MasterKey string `yaml:"masterKey"` - CollectionThroughput int `yaml:"collectionThroughput,omitempty"` -} - // ETCDOptions represents options for the configuring the etcd store. type ETCDOptions struct { // InMemory configures the etcd store to run in-memory with the resource provider. This is not suitable for production use. diff --git a/pkg/ucp/dataprovider/storageprovider.go b/pkg/ucp/databaseprovider/storageprovider.go similarity index 51% rename from pkg/ucp/dataprovider/storageprovider.go rename to pkg/ucp/databaseprovider/storageprovider.go index 0fb89234b7..2891515aaa 100644 --- a/pkg/ucp/dataprovider/storageprovider.go +++ b/pkg/ucp/databaseprovider/storageprovider.go @@ -14,30 +14,30 @@ See the License for the specific language governing permissions and limitations under the License. */ -package dataprovider +package databaseprovider import ( "context" "fmt" "sync" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" ) -// DataStorageProvider acts as a factory for storage clients. +// DatabaseProvider acts as a factory for database clients. // // Do not use construct this directly: // -// - Use DataStorageProviderFromOptions instead for production use. -// - Use DataStorageProviderFromMemory or DataStorageProviderFromClient for testing. -type DataStorageProvider struct { - // options configures the settings of the storage provider. - options StorageProviderOptions +// - Use FromOptions instead for production use. +// - Use FromMemory or FromClient for testing. +type DatabaseProvider struct { + // options configures the settings of the database provider. + options Options - // factory is factory function to create a new storage client. Can be overridden for testing. - factory storageFactoryFunc + // factory is factory function to create a new database client. Can be overridden for testing. + factory databaseClientFactoryFunc - // init is used to guarantee single-initialization of the storage provider. + // init is used to guarantee single-initialization of the database provider. init sync.RWMutex // result is result of invoking the factory (cached). @@ -45,34 +45,34 @@ type DataStorageProvider struct { } type result struct { - client store.StorageClient + client database.Client err error } -// DataStorageProviderFromOptions creates a new instance of the DataStorageProvider struct with the given options. +// FromOptions creates a new instance of the DatabaseProvider struct with the given options. // -// This will used the known factory functions to instantiate the storage client. -func DataStorageProviderFromOptions(options StorageProviderOptions) *DataStorageProvider { - return &DataStorageProvider{options: options} +// This will used the known factory functions to instantiate the database client. +func FromOptions(options Options) *DatabaseProvider { + return &DatabaseProvider{options: options} } -// DataStorageProviderFromMemory creates a new instance of the DataStorageProvider struct using the in-memory client. +// FromMemory creates a new instance of the DatabaseProvider struct using the in-memory client. // -// This will use the ephemeral in-memory storage client. -func DataStorageProviderFromMemory() *DataStorageProvider { - return &DataStorageProvider{options: StorageProviderOptions{Provider: TypeInMemory}} +// This will use the ephemeral in-memory database client. +func FromMemory() *DatabaseProvider { + return &DatabaseProvider{options: Options{Provider: TypeInMemory}} } -// DataStorageProviderFromClient creates a new instance of the DataStorageProvider struct with the given client. +// FromClient creates a new instance of the DatabaseProvider struct with the given client. // // This will always return the given client and will not attempt to create a new one. This can be used for testing // with mocks. -func DataStorageProviderFromClient(client store.StorageClient) *DataStorageProvider { - return &DataStorageProvider{result: result{client: client}} +func FromClient(client database.Client) *DatabaseProvider { + return &DatabaseProvider{result: result{client: client}} } -// GetStorageClient returns a storage client for the given resource type. -func (p *DataStorageProvider) GetClient(ctx context.Context) (store.StorageClient, error) { +// GetClient returns a database client for the given resource type. +func (p *DatabaseProvider) GetClient(ctx context.Context) (database.Client, error) { // Guarantee single initialization. p.init.RLock() result := p.result @@ -94,7 +94,7 @@ func (p *DataStorageProvider) GetClient(ctx context.Context) (store.StorageClien return result.client, nil } -func (p *DataStorageProvider) initialize(ctx context.Context) result { +func (p *DatabaseProvider) initialize(ctx context.Context) result { p.init.Lock() defer p.init.Unlock() @@ -109,13 +109,13 @@ func (p *DataStorageProvider) initialize(ctx context.Context) result { return p.result } - // If we get here we have the exclusive lock and need to initialize the storage client. + // If we get here we have the exclusive lock and need to initialize the database client. factory := p.factory if factory == nil { - fn, ok := storageClientFactory[p.options.Provider] + fn, ok := databaseClientFactory[p.options.Provider] if !ok { - p.result = result{nil, fmt.Errorf("unsupported storage provider: %s", p.options.Provider)} + p.result = result{nil, fmt.Errorf("unsupported database provider: %s", p.options.Provider)} return p.result } @@ -124,10 +124,10 @@ func (p *DataStorageProvider) initialize(ctx context.Context) result { client, err := factory(ctx, p.options) if err != nil { - p.result = result{nil, fmt.Errorf("failed to initialize storage client: %w", err)} + p.result = result{nil, fmt.Errorf("failed to initialize database client: %w", err)} return p.result } else if client == nil { - p.result = result{nil, fmt.Errorf("failed to initialize storage client: provider returned nil")} + p.result = result{nil, fmt.Errorf("failed to initialize database client: provider returned nil")} return p.result } diff --git a/pkg/ucp/dataprovider/storageprovider_test.go b/pkg/ucp/databaseprovider/storageprovider_test.go similarity index 63% rename from pkg/ucp/dataprovider/storageprovider_test.go rename to pkg/ucp/databaseprovider/storageprovider_test.go index 984c73597f..f6a0eb9285 100644 --- a/pkg/ucp/dataprovider/storageprovider_test.go +++ b/pkg/ucp/databaseprovider/storageprovider_test.go @@ -14,20 +14,20 @@ See the License for the specific language governing permissions and limitations under the License. */ -package dataprovider +package databaseprovider import ( "context" "errors" "testing" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/stretchr/testify/require" ) -func Test_DataStorageProviderFromOptions(t *testing.T) { - options := StorageProviderOptions{Provider: TypeInMemory} - provider := DataStorageProviderFromOptions(options) +func Test_FromOptions(t *testing.T) { + options := Options{Provider: TypeInMemory} + provider := FromOptions(options) require.NotNil(t, provider) require.Equal(t, options, provider.options) @@ -37,8 +37,8 @@ func Test_DataStorageProviderFromOptions(t *testing.T) { require.NotNil(t, client) } -func Test_DataStorageProviderFromMemory(t *testing.T) { - provider := DataStorageProviderFromMemory() +func Test_FromMemory(t *testing.T) { + provider := FromMemory() require.NotNil(t, provider) require.Equal(t, TypeInMemory, provider.options.Provider) @@ -48,9 +48,9 @@ func Test_DataStorageProviderFromMemory(t *testing.T) { require.NotNil(t, client) } -func Test_DataStorageProviderFromClient(t *testing.T) { - mockClient := &store.MockStorageClient{} - provider := DataStorageProviderFromClient(mockClient) +func Test_FromClient(t *testing.T) { + mockClient := &database.MockClient{} + provider := FromClient(mockClient) require.NotNil(t, provider) require.Same(t, mockClient, provider.result.client) @@ -61,11 +61,11 @@ func Test_DataStorageProviderFromClient(t *testing.T) { } func Test_GetClient_CachedClient(t *testing.T) { - mockClient := &store.MockStorageClient{} - provider := DataStorageProviderFromOptions(StorageProviderOptions{Provider: "Test"}) + mockClient := &database.MockClient{} + provider := FromOptions(Options{Provider: "Test"}) callCount := 0 - provider.factory = storageFactoryFunc(func(ctx context.Context, options StorageProviderOptions) (store.StorageClient, error) { + provider.factory = databaseClientFactoryFunc(func(ctx context.Context, options Options) (database.Client, error) { callCount++ return mockClient, nil }) @@ -83,44 +83,44 @@ func Test_GetClient_CachedClient(t *testing.T) { } func Test_GetClient_CachedError(t *testing.T) { - provider := DataStorageProviderFromOptions(StorageProviderOptions{Provider: "Test"}) + provider := FromOptions(Options{Provider: "Test"}) expectedErr := errors.New("oh noes!") callCount := 0 - provider.factory = storageFactoryFunc(func(ctx context.Context, options StorageProviderOptions) (store.StorageClient, error) { + provider.factory = databaseClientFactoryFunc(func(ctx context.Context, options Options) (database.Client, error) { callCount++ return nil, expectedErr }) client, err := provider.GetClient(context.Background()) require.Error(t, err) - require.Equal(t, "failed to initialize storage client: oh noes!", err.Error()) + require.Equal(t, "failed to initialize database client: oh noes!", err.Error()) require.Nil(t, client) // Do it twice to ensure the client is cached. client, err = provider.GetClient(context.Background()) require.Error(t, err) - require.Equal(t, "failed to initialize storage client: oh noes!", err.Error()) + require.Equal(t, "failed to initialize database client: oh noes!", err.Error()) require.Nil(t, client) require.Equal(t, 1, callCount) } func TestGetClient_UnsupportedProvider(t *testing.T) { - options := StorageProviderOptions{Provider: "unsupported"} - provider := DataStorageProviderFromOptions(options) + options := Options{Provider: "unsupported"} + provider := FromOptions(options) client, err := provider.GetClient(context.Background()) require.Error(t, err) require.Nil(t, client) - require.Equal(t, "unsupported storage provider: unsupported", err.Error()) + require.Equal(t, "unsupported database provider: unsupported", err.Error()) } func TestInitialize(t *testing.T) { - options := StorageProviderOptions{Provider: TypeInMemory} - provider := DataStorageProviderFromOptions(options) + options := Options{Provider: TypeInMemory} + provider := FromOptions(options) result := provider.initialize(context.Background()) diff --git a/pkg/ucp/dataprovider/types.go b/pkg/ucp/databaseprovider/types.go similarity index 71% rename from pkg/ucp/dataprovider/types.go rename to pkg/ucp/databaseprovider/types.go index cc577b0d63..3a17486c72 100644 --- a/pkg/ucp/dataprovider/types.go +++ b/pkg/ucp/databaseprovider/types.go @@ -14,21 +14,21 @@ See the License for the specific language governing permissions and limitations under the License. */ -package dataprovider +package databaseprovider -// StorageProviderType represents types of storage provider. -type StorageProviderType string +// DatabaseProviderType represents types of database provider. +type DatabaseProviderType string const ( // TypeAPIServer represents the Kubernetes APIServer provider. - TypeAPIServer StorageProviderType = "apiserver" + TypeAPIServer DatabaseProviderType = "apiserver" // TypeETCD represents the etcd provider. - TypeETCD StorageProviderType = "etcd" + TypeETCD DatabaseProviderType = "etcd" // TypeInMemory represents the in-memory provider. - TypeInMemory StorageProviderType = "inmemory" + TypeInMemory DatabaseProviderType = "inmemory" // TypePostgreSQL represents the PostgreSQL provider. - TypePostgreSQL StorageProviderType = "postgresql" + TypePostgreSQL DatabaseProviderType = "postgresql" ) diff --git a/pkg/ucp/frontend/api/routes.go b/pkg/ucp/frontend/api/routes.go index fd84d51aa5..b8e732cb79 100644 --- a/pkg/ucp/frontend/api/routes.go +++ b/pkg/ucp/frontend/api/routes.go @@ -142,16 +142,16 @@ func Register(ctx context.Context, router chi.Router, planeModules []modules.Ini }, }...) - storageClient, err := options.DataProvider.GetClient(ctx) + databaseClient, err := options.DatabaseProvider.GetClient(ctx) if err != nil { return err } ctrlOptions := controller.Options{ - Address: options.Address, - PathBase: options.PathBase, - StorageClient: storageClient, - StatusManager: options.StatusManager, + Address: options.Address, + PathBase: options.PathBase, + DatabaseClient: databaseClient, + StatusManager: options.StatusManager, } for _, h := range handlerOptions { diff --git a/pkg/ucp/frontend/api/routes_test.go b/pkg/ucp/frontend/api/routes_test.go index 32fc581a22..9833f0733e 100644 --- a/pkg/ucp/frontend/api/routes_test.go +++ b/pkg/ucp/frontend/api/routes_test.go @@ -25,7 +25,7 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" "github.com/radius-project/radius/pkg/armrpc/rpctest" - "github.com/radius-project/radius/pkg/ucp/dataprovider" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" "github.com/radius-project/radius/pkg/ucp/frontend/modules" "github.com/radius-project/radius/test/testcontext" "github.com/stretchr/testify/require" @@ -80,10 +80,10 @@ func Test_Routes(t *testing.T) { } options := modules.Options{ - Address: "localhost", - PathBase: pathBase, - DataProvider: dataprovider.DataStorageProviderFromMemory(), - StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), + Address: "localhost", + PathBase: pathBase, + DatabaseProvider: databaseprovider.FromMemory(), + StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), } rpctest.AssertRouters(t, tests, pathBase, "", func(ctx context.Context) (chi.Router, error) { @@ -96,10 +96,10 @@ func Test_Route_ToModule(t *testing.T) { pathBase := "/some-path-base" options := modules.Options{ - Address: "localhost", - PathBase: pathBase, - DataProvider: dataprovider.DataStorageProviderFromMemory(), - StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), + Address: "localhost", + PathBase: pathBase, + DatabaseProvider: databaseprovider.FromMemory(), + StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), } r := chi.NewRouter() diff --git a/pkg/ucp/frontend/api/server.go b/pkg/ucp/frontend/api/server.go index 4f121582c7..99e31911ed 100644 --- a/pkg/ucp/frontend/api/server.go +++ b/pkg/ucp/frontend/api/server.go @@ -32,9 +32,9 @@ import ( "github.com/radius-project/radius/pkg/armrpc/servicecontext" "github.com/radius-project/radius/pkg/middleware" "github.com/radius-project/radius/pkg/sdk" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/datamodel/converter" - "github.com/radius-project/radius/pkg/ucp/dataprovider" aws_frontend "github.com/radius-project/radius/pkg/ucp/frontend/aws" azure_frontend "github.com/radius-project/radius/pkg/ucp/frontend/azure" "github.com/radius-project/radius/pkg/ucp/frontend/modules" @@ -42,10 +42,10 @@ import ( "github.com/radius-project/radius/pkg/ucp/frontend/versions" "github.com/radius-project/radius/pkg/ucp/hosting" "github.com/radius-project/radius/pkg/ucp/hostoptions" - queueprovider "github.com/radius-project/radius/pkg/ucp/queue/provider" + "github.com/radius-project/radius/pkg/ucp/queue/queueprovider" "github.com/radius-project/radius/pkg/ucp/resources" "github.com/radius-project/radius/pkg/ucp/rest" - secretprovider "github.com/radius-project/radius/pkg/ucp/secret/provider" + "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" "github.com/radius-project/radius/pkg/ucp/ucplog" "github.com/radius-project/radius/pkg/validator" "github.com/radius-project/radius/swagger" @@ -69,7 +69,7 @@ type ServiceOptions struct { Configure func(chi.Router) TLSCertDir string DefaultPlanesConfigFile string - StorageProviderOptions dataprovider.StorageProviderOptions + DatabaseProviderOptions databaseprovider.Options SecretProviderOptions secretprovider.SecretProviderOptions QueueProviderOptions queueprovider.QueueProviderOptions InitialPlanes []rest.Plane @@ -83,10 +83,10 @@ type ServiceOptions struct { // Service implements the hosting.Service interface for the UCP frontend API. type Service struct { - options ServiceOptions - storageProvider *dataprovider.DataStorageProvider - queueProvider *queueprovider.QueueProvider - secretProvider *secretprovider.SecretProvider + options ServiceOptions + databaseProvider *databaseprovider.DatabaseProvider + queueProvider *queueprovider.QueueProvider + secretProvider *secretprovider.SecretProvider } // DefaultModules returns a list of default modules that will be registered with the router. @@ -112,13 +112,13 @@ func (s *Service) Name() string { return "api" } -// Initialize sets up the router, storage provider, secret provider, status manager, AWS config, AWS clients, +// Initialize sets up the router, database provider, secret provider, status manager, AWS config, AWS clients, // registers the routes, configures the default planes, and sets up the http server with the appropriate middleware. It // returns an http server and an error if one occurs. func (s *Service) Initialize(ctx context.Context) (*http.Server, error) { r := chi.NewRouter() - s.storageProvider = dataprovider.DataStorageProviderFromOptions(s.options.StorageProviderOptions) + s.databaseProvider = databaseprovider.FromOptions(s.options.DatabaseProviderOptions) s.queueProvider = queueprovider.New(s.options.QueueProviderOptions) s.secretProvider = secretprovider.NewSecretProvider(s.options.SecretProviderOptions) @@ -127,7 +127,7 @@ func (s *Service) Initialize(ctx context.Context) (*http.Server, error) { return nil, err } - storageClient, err := s.storageProvider.GetClient(ctx) + databaseClient, err := s.databaseProvider.GetClient(ctx) if err != nil { return nil, err } @@ -137,19 +137,19 @@ func (s *Service) Initialize(ctx context.Context) (*http.Server, error) { return nil, err } - statusManager := statusmanager.New(storageClient, queueClient, s.options.Location) + statusManager := statusmanager.New(databaseClient, queueClient, s.options.Location) moduleOptions := modules.Options{ - Address: s.options.Address, - PathBase: s.options.PathBase, - Config: s.options.Config, - Location: s.options.Location, - DataProvider: s.storageProvider, - QueueProvider: s.queueProvider, - SecretProvider: s.secretProvider, - SpecLoader: specLoader, - StatusManager: statusManager, - UCPConnection: s.options.UCPConnection, + Address: s.options.Address, + PathBase: s.options.PathBase, + Config: s.options.Config, + Location: s.options.Location, + DatabaseProvider: s.databaseProvider, + QueueProvider: s.queueProvider, + SecretProvider: s.secretProvider, + SpecLoader: specLoader, + StatusManager: statusManager, + UCPConnection: s.options.UCPConnection, } modules := DefaultModules(moduleOptions) @@ -222,13 +222,13 @@ func (s *Service) createPlane(ctx context.Context, plane rest.Plane) error { return fmt.Errorf("invalid plane ID: %s", plane.ID) } - db, err := s.storageProvider.GetClient(ctx) + db, err := s.databaseProvider.GetClient(ctx) if err != nil { return err } opts := armrpc_controller.Options{ - StorageClient: db, + DatabaseClient: db, } var ctrl armrpc_controller.Controller diff --git a/pkg/ucp/frontend/aws/routes.go b/pkg/ucp/frontend/aws/routes.go index 6713157d50..7923343d9d 100644 --- a/pkg/ucp/frontend/aws/routes.go +++ b/pkg/ucp/frontend/aws/routes.go @@ -292,16 +292,16 @@ func (m *Module) Initialize(ctx context.Context) (http.Handler, error) { }, }...) - storageClient, err := m.options.DataProvider.GetClient(ctx) + databaseClient, err := m.options.DatabaseProvider.GetClient(ctx) if err != nil { return nil, err } ctrlOpts := controller.Options{ - Address: m.options.Address, - PathBase: m.options.PathBase, - StorageClient: storageClient, - StatusManager: m.options.StatusManager, + Address: m.options.Address, + PathBase: m.options.PathBase, + DatabaseClient: databaseClient, + StatusManager: m.options.StatusManager, } for _, h := range handlerOptions { diff --git a/pkg/ucp/frontend/aws/routes_test.go b/pkg/ucp/frontend/aws/routes_test.go index 5311a646d8..634b2fd23f 100644 --- a/pkg/ucp/frontend/aws/routes_test.go +++ b/pkg/ucp/frontend/aws/routes_test.go @@ -28,12 +28,12 @@ import ( "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/ucp/api/v20231001preview" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" "github.com/radius-project/radius/pkg/ucp/datamodel" - "github.com/radius-project/radius/pkg/ucp/dataprovider" "github.com/radius-project/radius/pkg/ucp/frontend/modules" "github.com/radius-project/radius/pkg/ucp/hostoptions" "github.com/radius-project/radius/pkg/ucp/secret" - secretprovider "github.com/radius-project/radius/pkg/ucp/secret/provider" + secretprovider "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" ) const pathBase = "/some-path-base" @@ -118,12 +118,12 @@ func Test_Routes(t *testing.T) { secretProvider.SetClient(secretClient) options := modules.Options{ - Address: "localhost", - PathBase: pathBase, - Config: &hostoptions.UCPConfig{}, - DataProvider: dataprovider.DataStorageProviderFromMemory(), - SecretProvider: secretProvider, - StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), + Address: "localhost", + PathBase: pathBase, + Config: &hostoptions.UCPConfig{}, + DatabaseProvider: databaseprovider.FromMemory(), + SecretProvider: secretProvider, + StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), } rpctest.AssertRouters(t, tests, pathBase, "", func(ctx context.Context) (chi.Router, error) { diff --git a/pkg/ucp/frontend/azure/routes.go b/pkg/ucp/frontend/azure/routes.go index c54cd05fb5..b77d70afe8 100644 --- a/pkg/ucp/frontend/azure/routes.go +++ b/pkg/ucp/frontend/azure/routes.go @@ -165,16 +165,16 @@ func (m *Module) Initialize(ctx context.Context) (http.Handler, error) { }, } - storageClient, err := m.options.DataProvider.GetClient(ctx) + databaseClient, err := m.options.DatabaseProvider.GetClient(ctx) if err != nil { return nil, err } ctrlOpts := controller.Options{ - Address: m.options.Address, - PathBase: m.options.PathBase, - StorageClient: storageClient, - StatusManager: m.options.StatusManager, + Address: m.options.Address, + PathBase: m.options.PathBase, + DatabaseClient: databaseClient, + StatusManager: m.options.StatusManager, } for _, h := range handlerOptions { diff --git a/pkg/ucp/frontend/azure/routes_test.go b/pkg/ucp/frontend/azure/routes_test.go index 1e0e3a5f8c..57109e5e08 100644 --- a/pkg/ucp/frontend/azure/routes_test.go +++ b/pkg/ucp/frontend/azure/routes_test.go @@ -28,12 +28,12 @@ import ( "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/ucp/api/v20231001preview" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" "github.com/radius-project/radius/pkg/ucp/datamodel" - "github.com/radius-project/radius/pkg/ucp/dataprovider" "github.com/radius-project/radius/pkg/ucp/frontend/modules" "github.com/radius-project/radius/pkg/ucp/hostoptions" "github.com/radius-project/radius/pkg/ucp/secret" - secretprovider "github.com/radius-project/radius/pkg/ucp/secret/provider" + secretprovider "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" ) const pathBase = "/some-path-base" @@ -92,12 +92,12 @@ func Test_Routes(t *testing.T) { secretProvider.SetClient(secretClient) options := modules.Options{ - Address: "localhost", - PathBase: pathBase, - Config: &hostoptions.UCPConfig{}, - DataProvider: dataprovider.DataStorageProviderFromMemory(), - SecretProvider: secretProvider, - StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), + Address: "localhost", + PathBase: pathBase, + Config: &hostoptions.UCPConfig{}, + DatabaseProvider: databaseprovider.FromMemory(), + SecretProvider: secretProvider, + StatusManager: statusmanager.NewMockStatusManager(gomock.NewController(t)), } rpctest.AssertRouters(t, tests, pathBase, "", func(ctx context.Context) (chi.Router, error) { diff --git a/pkg/ucp/frontend/controller/awsproxy/awsproxytest.go b/pkg/ucp/frontend/controller/awsproxy/awsproxytest.go index 0d7f4a13d7..c5f05ead31 100644 --- a/pkg/ucp/frontend/controller/awsproxy/awsproxytest.go +++ b/pkg/ucp/frontend/controller/awsproxy/awsproxytest.go @@ -21,7 +21,7 @@ import ( "fmt" "testing" - "github.com/radius-project/radius/pkg/ucp/store" + "github.com/radius-project/radius/pkg/ucp/database" "go.uber.org/mock/gomock" awsclient "github.com/radius-project/radius/pkg/ucp/aws" @@ -43,19 +43,19 @@ const ( type TestOptions struct { AWSCloudControlClient *awsclient.MockAWSCloudControlClient AWSCloudFormationClient *awsclient.MockAWSCloudFormationClient - StorageClient *store.MockStorageClient + DatabaseClient *database.MockClient } -// setupTest returns a TestOptions struct with mocked AWS and Storage clients +// setupTest returns a TestOptions struct with mocked AWS and database clients func setupTest(t *testing.T) TestOptions { mockCtrl := gomock.NewController(t) mockCloudControlClient := awsclient.NewMockAWSCloudControlClient(mockCtrl) mockCloudFormationClient := awsclient.NewMockAWSCloudFormationClient(mockCtrl) - mockStorageClient := store.NewMockStorageClient(mockCtrl) + mockDatabaseClient := database.NewMockClient(mockCtrl) return TestOptions{ AWSCloudControlClient: mockCloudControlClient, AWSCloudFormationClient: mockCloudFormationClient, - StorageClient: mockStorageClient, + DatabaseClient: mockDatabaseClient, } } diff --git a/pkg/ucp/frontend/controller/awsproxy/createorupdateawsresource_test.go b/pkg/ucp/frontend/controller/awsproxy/createorupdateawsresource_test.go index ba953a9c6e..a52e69c762 100644 --- a/pkg/ucp/frontend/controller/awsproxy/createorupdateawsresource_test.go +++ b/pkg/ucp/frontend/controller/awsproxy/createorupdateawsresource_test.go @@ -66,7 +66,7 @@ func Test_CreateAWSResource(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewCreateOrUpdateAWSResource(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewCreateOrUpdateAWSResource(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodPut, testResource.SingleResourcePath, bytes.NewBuffer(requestBodyBytes)) @@ -131,7 +131,7 @@ func Test_CreateAWSResourceInvalidRegion(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewCreateOrUpdateAWSResource(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewCreateOrUpdateAWSResource(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodPut, testResource.SingleResourcePath, bytes.NewBuffer(requestBodyBytes)) @@ -222,7 +222,7 @@ func Test_UpdateAWSResource(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewCreateOrUpdateAWSResource(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewCreateOrUpdateAWSResource(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodPut, testResource.SingleResourcePath, bytes.NewBuffer(requestBodyBytes)) @@ -304,7 +304,7 @@ func Test_UpdateNoChangesDoesNotCallUpdate(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewCreateOrUpdateAWSResource(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewCreateOrUpdateAWSResource(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodPut, testResource.SingleResourcePath, bytes.NewBuffer(requestBodyBytes)) diff --git a/pkg/ucp/frontend/controller/awsproxy/createorupdateawsresourcewithpost_test.go b/pkg/ucp/frontend/controller/awsproxy/createorupdateawsresourcewithpost_test.go index faf6e624f5..ea0efa8a34 100644 --- a/pkg/ucp/frontend/controller/awsproxy/createorupdateawsresourcewithpost_test.go +++ b/pkg/ucp/frontend/controller/awsproxy/createorupdateawsresourcewithpost_test.go @@ -74,7 +74,7 @@ func Test_CreateAWSResourceWithPost(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewCreateOrUpdateAWSResourceWithPost(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewCreateOrUpdateAWSResourceWithPost(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodPost, testResource.CollectionPath, bytes.NewBuffer(requestBodyBytes)) @@ -167,7 +167,7 @@ func Test_UpdateAWSResourceWithPost(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewCreateOrUpdateAWSResourceWithPost(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewCreateOrUpdateAWSResourceWithPost(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodPost, testResource.CollectionPath, bytes.NewBuffer(requestBodyBytes)) @@ -256,7 +256,7 @@ func Test_UpdateAWSResourceWithPost_NoChangesNoops(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewCreateOrUpdateAWSResourceWithPost(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewCreateOrUpdateAWSResourceWithPost(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodPost, "/planes/aws/aws/accounts/1234567/regions/us-west-2/providers/AWS.MemoryDB/Cluster", bytes.NewBuffer(requestBodyBytes)) @@ -335,7 +335,7 @@ func Test_CreateAWSResourceWithPost_NoPrimaryIdentifierAvailable(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewCreateOrUpdateAWSResourceWithPost(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewCreateOrUpdateAWSResourceWithPost(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodPost, testResource.CollectionPath+"/:put", bytes.NewBuffer(requestBodyBytes)) @@ -416,7 +416,7 @@ func Test_CreateAWSResourceWithPost_MultiIdentifier(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewCreateOrUpdateAWSResourceWithPost(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewCreateOrUpdateAWSResourceWithPost(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodPost, testResource.CollectionPath+"/:put", bytes.NewBuffer(requestBodyBytes)) @@ -508,7 +508,7 @@ func Test_UpdateAWSResourceWithPost_MultiIdentifier(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewCreateOrUpdateAWSResourceWithPost(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewCreateOrUpdateAWSResourceWithPost(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodPost, testResource.CollectionPath, bytes.NewBuffer(requestBodyBytes)) diff --git a/pkg/ucp/frontend/controller/awsproxy/deleteawsresource_test.go b/pkg/ucp/frontend/controller/awsproxy/deleteawsresource_test.go index 89af90c43d..4ebfe22046 100644 --- a/pkg/ucp/frontend/controller/awsproxy/deleteawsresource_test.go +++ b/pkg/ucp/frontend/controller/awsproxy/deleteawsresource_test.go @@ -47,7 +47,7 @@ func Test_DeleteAWSResource(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewDeleteAWSResource(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewDeleteAWSResource(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodDelete, testResource.SingleResourcePath, nil) @@ -89,7 +89,7 @@ func Test_DeleteAWSResource_ResourceDoesNotExist(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewDeleteAWSResource(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewDeleteAWSResource(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodDelete, testResource.SingleResourcePath, nil) diff --git a/pkg/ucp/frontend/controller/awsproxy/deleteawsresourcewithpost_test.go b/pkg/ucp/frontend/controller/awsproxy/deleteawsresourcewithpost_test.go index 929038c1f0..b86d29675a 100644 --- a/pkg/ucp/frontend/controller/awsproxy/deleteawsresourcewithpost_test.go +++ b/pkg/ucp/frontend/controller/awsproxy/deleteawsresourcewithpost_test.go @@ -59,7 +59,7 @@ func Test_DeleteAWSResourceWithPost(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewDeleteAWSResourceWithPost(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewDeleteAWSResourceWithPost(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) requestBody := map[string]any{ @@ -110,7 +110,7 @@ func Test_DeleteAWSResourceWithPost_ResourceDoesNotExist(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewDeleteAWSResourceWithPost(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewDeleteAWSResourceWithPost(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) requestBody := map[string]any{ @@ -183,7 +183,7 @@ func Test_DeleteAWSResourceWithPost_MultiIdentifier(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewDeleteAWSResourceWithPost(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewDeleteAWSResourceWithPost(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) actualResponse, err := awsController.Run(ctx, nil, request) diff --git a/pkg/ucp/frontend/controller/awsproxy/getawsoperationresults_test.go b/pkg/ucp/frontend/controller/awsproxy/getawsoperationresults_test.go index 78e35150b4..ef44c9f8e3 100644 --- a/pkg/ucp/frontend/controller/awsproxy/getawsoperationresults_test.go +++ b/pkg/ucp/frontend/controller/awsproxy/getawsoperationresults_test.go @@ -49,7 +49,7 @@ func Test_GetAWSOperationResults_TerminalStatus(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewGetAWSOperationResults(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewGetAWSOperationResults(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodGet, testResource.OperationResultsPath, nil) @@ -80,7 +80,7 @@ func Test_GetAWSOperationResults_NonTerminalStatus(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewGetAWSOperationResults(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewGetAWSOperationResults(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodGet, testResource.OperationResultsPath, nil) diff --git a/pkg/ucp/frontend/controller/awsproxy/getawsoperationstatuses_test.go b/pkg/ucp/frontend/controller/awsproxy/getawsoperationstatuses_test.go index d10a35175f..b07e30014c 100644 --- a/pkg/ucp/frontend/controller/awsproxy/getawsoperationstatuses_test.go +++ b/pkg/ucp/frontend/controller/awsproxy/getawsoperationstatuses_test.go @@ -52,7 +52,7 @@ func Test_GetAWSOperationStatuses(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewGetAWSOperationStatuses(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewGetAWSOperationStatuses(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodGet, testResource.OperationStatusesPath, nil) @@ -93,7 +93,7 @@ func Test_GetAWSOperationStatuses_Failed(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewGetAWSOperationStatuses(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewGetAWSOperationStatuses(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodGet, testResource.OperationStatusesPath, nil) @@ -135,7 +135,7 @@ func Test_GetAWSOperationStatuses_Delete_NotFound(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewGetAWSOperationStatuses(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewGetAWSOperationStatuses(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodGet, testResource.OperationStatusesPath, nil) diff --git a/pkg/ucp/frontend/controller/awsproxy/getawsresource_test.go b/pkg/ucp/frontend/controller/awsproxy/getawsresource_test.go index 80d53375d4..d30dbdb708 100644 --- a/pkg/ucp/frontend/controller/awsproxy/getawsresource_test.go +++ b/pkg/ucp/frontend/controller/awsproxy/getawsresource_test.go @@ -61,7 +61,7 @@ func Test_GetAWSResource(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewGetAWSResource(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewGetAWSResource(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodGet, testResource.SingleResourcePath, nil) @@ -97,7 +97,7 @@ func Test_GetAWSResource_NotFound(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewGetAWSResource(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewGetAWSResource(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodGet, testResource.SingleResourcePath, nil) @@ -124,7 +124,7 @@ func Test_GetAWSResource_UnknownError(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewGetAWSResource(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewGetAWSResource(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodGet, testResource.SingleResourcePath, nil) @@ -155,7 +155,7 @@ func Test_GetAWSResource_SmithyError(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewGetAWSResource(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewGetAWSResource(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodGet, testResource.SingleResourcePath, nil) diff --git a/pkg/ucp/frontend/controller/awsproxy/getawsresourcewithpost_test.go b/pkg/ucp/frontend/controller/awsproxy/getawsresourcewithpost_test.go index ce61b22cb9..06063cadc8 100644 --- a/pkg/ucp/frontend/controller/awsproxy/getawsresourcewithpost_test.go +++ b/pkg/ucp/frontend/controller/awsproxy/getawsresourcewithpost_test.go @@ -74,7 +74,7 @@ func Test_GetAWSResourceWithPost(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewGetAWSResourceWithPost(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewGetAWSResourceWithPost(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) requestBody := map[string]any{ @@ -126,7 +126,7 @@ func Test_GetAWSResourceWithPost_NotFound(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewGetAWSResourceWithPost(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewGetAWSResourceWithPost(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) requestBody := map[string]any{ @@ -165,7 +165,7 @@ func Test_GetAWSResourceWithPost_UnknownError(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewGetAWSResourceWithPost(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewGetAWSResourceWithPost(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) requestBody := map[string]any{ @@ -211,7 +211,7 @@ func Test_GetAWSResourceWithPost_SmithyError(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewGetAWSResourceWithPost(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewGetAWSResourceWithPost(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) requestBody := map[string]any{ @@ -287,7 +287,7 @@ func Test_GetAWSResourceWithPost_MultiIdentifier(t *testing.T) { CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewGetAWSResourceWithPost(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewGetAWSResourceWithPost(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) actualResponse, err := awsController.Run(ctx, nil, request) diff --git a/pkg/ucp/frontend/controller/awsproxy/listawsresources_test.go b/pkg/ucp/frontend/controller/awsproxy/listawsresources_test.go index 290d8136b6..74327e0e71 100644 --- a/pkg/ucp/frontend/controller/awsproxy/listawsresources_test.go +++ b/pkg/ucp/frontend/controller/awsproxy/listawsresources_test.go @@ -75,7 +75,7 @@ func Test_ListAWSResources(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewListAWSResources(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewListAWSResources(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodGet, firstTestResource.CollectionPath, nil) @@ -121,7 +121,7 @@ func Test_ListAWSResourcesEmpty(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewListAWSResources(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewListAWSResources(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodGet, testResource.CollectionPath, nil) @@ -148,7 +148,7 @@ func Test_ListAWSResource_UnknownError(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewListAWSResources(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewListAWSResources(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodGet, testResource.CollectionPath, nil) @@ -179,7 +179,7 @@ func Test_ListAWSResource_SmithyError(t *testing.T) { CloudControl: testOptions.AWSCloudControlClient, CloudFormation: testOptions.AWSCloudFormationClient, } - awsController, err := NewListAWSResources(armrpc_controller.Options{StorageClient: testOptions.StorageClient}, awsClients) + awsController, err := NewListAWSResources(armrpc_controller.Options{DatabaseClient: testOptions.DatabaseClient}, awsClients) require.NoError(t, err) request, err := http.NewRequest(http.MethodGet, testResource.CollectionPath, nil) diff --git a/pkg/ucp/frontend/controller/credentials/aws/createorupdateawscredential_test.go b/pkg/ucp/frontend/controller/credentials/aws/createorupdateawscredential_test.go index 72ddac212e..0e590c45cf 100644 --- a/pkg/ucp/frontend/controller/credentials/aws/createorupdateawscredential_test.go +++ b/pkg/ucp/frontend/controller/credentials/aws/createorupdateawscredential_test.go @@ -27,8 +27,8 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/to" "github.com/radius-project/radius/pkg/ucp/api/v20231001preview" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/secret" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/test/testutil" armrpc_controller "github.com/radius-project/radius/pkg/armrpc/frontend/controller" @@ -39,10 +39,10 @@ import ( func Test_AWS_Credential(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() - mockStorageClient := store.NewMockStorageClient(mockCtrl) + mockDatabaseClient := database.NewMockClient(mockCtrl) mockSecretClient := secret.NewMockClient(mockCtrl) - credentialCtrl, err := NewCreateOrUpdateAWSCredential(armrpc_controller.Options{StorageClient: mockStorageClient}, mockSecretClient) + credentialCtrl, err := NewCreateOrUpdateAWSCredential(armrpc_controller.Options{DatabaseClient: mockDatabaseClient}, mockSecretClient) require.NoError(t, err) tests := []struct { @@ -51,7 +51,7 @@ func Test_AWS_Credential(t *testing.T) { headerfile string url string expected armrpc_rest.Response - fn func(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) + fn func(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) err error }{ { @@ -121,7 +121,7 @@ func Test_AWS_Credential(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tt.fn(*mockStorageClient, *mockSecretClient) + tt.fn(*mockDatabaseClient, *mockSecretClient) credentialVersionedInput := &v20231001preview.AwsCredentialResource{} credentialInput := testutil.ReadFixture(tt.filename) @@ -165,44 +165,44 @@ func getAwsResponse() armrpc_rest.Response { }, map[string]string{"ETag": ""}) } -func setupCredentialSuccessMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Times(1).DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} +func setupCredentialSuccessMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Times(1).DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }) mockSecretClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) - mockStorageClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) + mockDatabaseClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) } -func setupEmptyMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { +func setupEmptyMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { } -func setupCredentialNotFoundMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, options ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} +func setupCredentialNotFoundMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). + DoAndReturn(func(ctx context.Context, id string, options ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }).Times(1) mockSecretClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) - mockStorageClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) + mockDatabaseClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) } -func setupCredentialNotFoundErrorMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, options ...store.GetOptions) (*store.Object, error) { +func setupCredentialNotFoundErrorMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). + DoAndReturn(func(ctx context.Context, id string, options ...database.GetOptions) (*database.Object, error) { return nil, errors.New("Error") }).Times(1) } -func setupCredentialGetFailMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, options ...store.GetOptions) (*store.Object, error) { +func setupCredentialGetFailMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). + DoAndReturn(func(ctx context.Context, id string, options ...database.GetOptions) (*database.Object, error) { return nil, errors.New("Failed Get") }).Times(1) } -func setupCredentialSecretSaveFailMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Times(1). - DoAndReturn(func(ctx context.Context, id string, options ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} +func setupCredentialSecretSaveFailMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Times(1). + DoAndReturn(func(ctx context.Context, id string, options ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }).Times(1) mockSecretClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("Secret Save Failure")).Times(1) } diff --git a/pkg/ucp/frontend/controller/credentials/aws/deleteawscredential.go b/pkg/ucp/frontend/controller/credentials/aws/deleteawscredential.go index 0f6b0b96aa..eaa9d9c7f7 100644 --- a/pkg/ucp/frontend/controller/credentials/aws/deleteawscredential.go +++ b/pkg/ucp/frontend/controller/credentials/aws/deleteawscredential.go @@ -24,11 +24,11 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" armrpc_controller "github.com/radius-project/radius/pkg/armrpc/frontend/controller" armrpcrest "github.com/radius-project/radius/pkg/armrpc/rest" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/datamodel/converter" "github.com/radius-project/radius/pkg/ucp/frontend/controller/credentials" "github.com/radius-project/radius/pkg/ucp/secret" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/ucplog" ) @@ -82,8 +82,8 @@ func (c *DeleteAWSCredential) Run(ctx context.Context, w http.ResponseWriter, re return r, err } - if err := c.StorageClient().Delete(ctx, serviceCtx.ResourceID.String()); err != nil { - if errors.Is(&store.ErrNotFound{ID: serviceCtx.ResourceID.String()}, err) { + if err := c.DatabaseClient().Delete(ctx, serviceCtx.ResourceID.String()); err != nil { + if errors.Is(&database.ErrNotFound{ID: serviceCtx.ResourceID.String()}, err) { return armrpcrest.NewNoContentResponse(), nil } return nil, err diff --git a/pkg/ucp/frontend/controller/credentials/aws/deleteawscredential_test.go b/pkg/ucp/frontend/controller/credentials/aws/deleteawscredential_test.go index d3b562264e..223ff65c2a 100644 --- a/pkg/ucp/frontend/controller/credentials/aws/deleteawscredential_test.go +++ b/pkg/ucp/frontend/controller/credentials/aws/deleteawscredential_test.go @@ -25,9 +25,9 @@ import ( armrpc_controller "github.com/radius-project/radius/pkg/armrpc/frontend/controller" armrpcrest "github.com/radius-project/radius/pkg/armrpc/rest" "github.com/radius-project/radius/pkg/armrpc/rpctest" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/secret" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -36,17 +36,17 @@ import ( func Test_Credential_Delete(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() - mockStorageClient := store.NewMockStorageClient(mockCtrl) + mockDatabaseClient := database.NewMockClient(mockCtrl) mockSecretClient := secret.NewMockClient(mockCtrl) - credentialCtrl, err := NewDeleteAWSCredential(armrpc_controller.Options{StorageClient: mockStorageClient}, mockSecretClient) + credentialCtrl, err := NewDeleteAWSCredential(armrpc_controller.Options{DatabaseClient: mockDatabaseClient}, mockSecretClient) require.NoError(t, err) tests := []struct { name string url string headerfile string - fn func(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) + fn func(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) expected armrpcrest.Response err error }{ @@ -110,7 +110,7 @@ func Test_Credential_Delete(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tt.fn(*mockStorageClient, *mockSecretClient) + tt.fn(*mockDatabaseClient, *mockSecretClient) request, err := rpctest.NewHTTPRequestFromJSON(context.Background(), http.MethodDelete, tt.headerfile, nil) require.NoError(t, err) ctx := rpctest.NewARMRequestContext(request) @@ -125,7 +125,7 @@ func Test_Credential_Delete(t *testing.T) { } } -func setupCredentialMocks(mockStorageClient store.MockStorageClient) { +func setupCredentialMocks(mockDatabaseClient database.MockClient) { datamodelCredential := datamodel.AWSCredential{ BaseResource: v1.BaseResource{}, Properties: &datamodel.AWSCredentialResourceProperties{ @@ -133,10 +133,10 @@ func setupCredentialMocks(mockStorageClient store.MockStorageClient) { }, } - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, options ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). + DoAndReturn(func(ctx context.Context, id string, options ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ ID: datamodelCredential.TrackedResource.ID, }, Data: &datamodelCredential, @@ -144,40 +144,40 @@ func setupCredentialMocks(mockStorageClient store.MockStorageClient) { }).Times(1) } -func setupCredentialDeleteSuccessMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - setupCredentialMocks(mockStorageClient) +func setupCredentialDeleteSuccessMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + setupCredentialMocks(mockDatabaseClient) mockSecretClient.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil).Times(1) - mockStorageClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) + mockDatabaseClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) } -func setupNonExistentCredentialDeleteMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, &store.ErrNotFound{}).Times(1) +func setupNonExistentCredentialDeleteMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, &database.ErrNotFound{}).Times(1) } -func setupCredentialExistenceCheckFailureMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("test_failure")).Times(1) +func setupCredentialExistenceCheckFailureMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("test_failure")).Times(1) } -func setupNonExistentSecretDeleteMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - setupCredentialMocks(mockStorageClient) +func setupNonExistentSecretDeleteMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + setupCredentialMocks(mockDatabaseClient) mockSecretClient.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(&secret.ErrNotFound{}).Times(1) } -func setupSecretDeleteFailureMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - setupCredentialMocks(mockStorageClient) +func setupSecretDeleteFailureMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + setupCredentialMocks(mockDatabaseClient) mockSecretClient.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(errors.New("Failed secret deletion")).Times(1) } -func setupNonExistingCredentialDeleteFromStorageMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - setupCredentialMocks(mockStorageClient) +func setupNonExistingCredentialDeleteFromStorageMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + setupCredentialMocks(mockDatabaseClient) mockSecretClient.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil).Times(1) - mockStorageClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(&store.ErrNotFound{}).Times(1) + mockDatabaseClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(&database.ErrNotFound{}).Times(1) } -func setupFailedCredentialDeleteFromStorageMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - setupCredentialMocks(mockStorageClient) +func setupFailedCredentialDeleteFromStorageMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + setupCredentialMocks(mockDatabaseClient) mockSecretClient.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil).Times(1) - mockStorageClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("Failed Storage Deletion")).Times(1) + mockDatabaseClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("Failed Storage Deletion")).Times(1) } diff --git a/pkg/ucp/frontend/controller/credentials/azure/createorupdateazurecredential_test.go b/pkg/ucp/frontend/controller/credentials/azure/createorupdateazurecredential_test.go index 03a98b5788..1889ede636 100644 --- a/pkg/ucp/frontend/controller/credentials/azure/createorupdateazurecredential_test.go +++ b/pkg/ucp/frontend/controller/credentials/azure/createorupdateazurecredential_test.go @@ -27,8 +27,8 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/to" "github.com/radius-project/radius/pkg/ucp/api/v20231001preview" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/secret" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/test/testutil" armrpc_controller "github.com/radius-project/radius/pkg/armrpc/frontend/controller" @@ -39,11 +39,11 @@ import ( func Test_Azure_Credential(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() - mockStorageClient := store.NewMockStorageClient(mockCtrl) + mockDatabaseClient := database.NewMockClient(mockCtrl) mockSecretClient := secret.NewMockClient(mockCtrl) credentialCtrl, err := NewCreateOrUpdateAzureCredential(armrpc_controller.Options{ - StorageClient: mockStorageClient, + DatabaseClient: mockDatabaseClient, }, mockSecretClient) require.NoError(t, err) @@ -53,7 +53,7 @@ func Test_Azure_Credential(t *testing.T) { headerfile string url string expected armrpc_rest.Response - fn func(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) + fn func(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) err error }{ { @@ -123,7 +123,7 @@ func Test_Azure_Credential(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tt.fn(*mockStorageClient, *mockSecretClient) + tt.fn(*mockDatabaseClient, *mockSecretClient) credentialVersionedInput := &v20231001preview.AzureCredentialResource{} credentialInput := testutil.ReadFixture(tt.filename) err = json.Unmarshal(credentialInput, credentialVersionedInput) @@ -165,44 +165,44 @@ func getAzureCredentialResponse() armrpc_rest.Response { }, map[string]string{"ETag": ""}) } -func setupCredentialSuccessMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Times(1).DoAndReturn(func(ctx context.Context, id string, _ ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} +func setupCredentialSuccessMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Times(1).DoAndReturn(func(ctx context.Context, id string, _ ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }) mockSecretClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) - mockStorageClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) + mockDatabaseClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) } -func setupCredentialNotFoundMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, options ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} +func setupCredentialNotFoundMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). + DoAndReturn(func(ctx context.Context, id string, options ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }).Times(1) mockSecretClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) - mockStorageClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) + mockDatabaseClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) } -func setupCredentialNotFoundErrorMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, options ...store.GetOptions) (*store.Object, error) { +func setupCredentialNotFoundErrorMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). + DoAndReturn(func(ctx context.Context, id string, options ...database.GetOptions) (*database.Object, error) { return nil, errors.New("Error") }).Times(1) } -func setupCredentialGetFailMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, options ...store.GetOptions) (*store.Object, error) { +func setupCredentialGetFailMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). + DoAndReturn(func(ctx context.Context, id string, options ...database.GetOptions) (*database.Object, error) { return nil, errors.New("Failed Get") }).Times(1) } -func setupCredentialSecretSaveFailMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, options ...store.GetOptions) (*store.Object, error) { - return nil, &store.ErrNotFound{ID: id} +func setupCredentialSecretSaveFailMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). + DoAndReturn(func(ctx context.Context, id string, options ...database.GetOptions) (*database.Object, error) { + return nil, &database.ErrNotFound{ID: id} }).Times(1) mockSecretClient.EXPECT().Save(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("Secret Save Failure")).Times(1) } -func setupEmptyMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { +func setupEmptyMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { } diff --git a/pkg/ucp/frontend/controller/credentials/azure/deleteazurecredential.go b/pkg/ucp/frontend/controller/credentials/azure/deleteazurecredential.go index 896d936304..09f1b3025f 100644 --- a/pkg/ucp/frontend/controller/credentials/azure/deleteazurecredential.go +++ b/pkg/ucp/frontend/controller/credentials/azure/deleteazurecredential.go @@ -24,11 +24,11 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" armrpc_controller "github.com/radius-project/radius/pkg/armrpc/frontend/controller" armrpc_rest "github.com/radius-project/radius/pkg/armrpc/rest" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/datamodel/converter" "github.com/radius-project/radius/pkg/ucp/frontend/controller/credentials" "github.com/radius-project/radius/pkg/ucp/secret" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/ucplog" ) @@ -83,8 +83,8 @@ func (c *DeleteAzureCredential) Run(ctx context.Context, w http.ResponseWriter, return r, err } - if err := c.StorageClient().Delete(ctx, serviceCtx.ResourceID.String()); err != nil { - if errors.Is(&store.ErrNotFound{ID: serviceCtx.ResourceID.String()}, err) { + if err := c.DatabaseClient().Delete(ctx, serviceCtx.ResourceID.String()); err != nil { + if errors.Is(&database.ErrNotFound{ID: serviceCtx.ResourceID.String()}, err) { return armrpc_rest.NewNoContentResponse(), nil } return nil, err diff --git a/pkg/ucp/frontend/controller/credentials/azure/deleteazurecredential_test.go b/pkg/ucp/frontend/controller/credentials/azure/deleteazurecredential_test.go index ff66ff221a..046c54d985 100644 --- a/pkg/ucp/frontend/controller/credentials/azure/deleteazurecredential_test.go +++ b/pkg/ucp/frontend/controller/credentials/azure/deleteazurecredential_test.go @@ -25,9 +25,9 @@ import ( armrpc_controller "github.com/radius-project/radius/pkg/armrpc/frontend/controller" armrpc_rest "github.com/radius-project/radius/pkg/armrpc/rest" "github.com/radius-project/radius/pkg/armrpc/rpctest" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/secret" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) @@ -35,11 +35,11 @@ import ( func Test_Credential_Delete(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() - mockStorageClient := store.NewMockStorageClient(mockCtrl) + mockDatabaseClient := database.NewMockClient(mockCtrl) mockSecretClient := secret.NewMockClient(mockCtrl) credentialCtrl, err := NewDeleteAzureCredential(armrpc_controller.Options{ - StorageClient: mockStorageClient, + DatabaseClient: mockDatabaseClient, }, mockSecretClient) require.NoError(t, err) @@ -47,7 +47,7 @@ func Test_Credential_Delete(t *testing.T) { name string url string headerfile string - fn func(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) + fn func(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) expected armrpc_rest.Response err error }{ @@ -111,7 +111,7 @@ func Test_Credential_Delete(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tt.fn(*mockStorageClient, *mockSecretClient) + tt.fn(*mockDatabaseClient, *mockSecretClient) request, err := rpctest.NewHTTPRequestFromJSON(context.Background(), http.MethodDelete, tt.headerfile, nil) require.NoError(t, err) @@ -128,7 +128,7 @@ func Test_Credential_Delete(t *testing.T) { } } -func setupCredentialMocks(mockStorageClient store.MockStorageClient) { +func setupCredentialMocks(mockDatabaseClient database.MockClient) { datamodelCredential := datamodel.AzureCredential{ BaseResource: v1.BaseResource{}, Properties: &datamodel.AzureCredentialResourceProperties{ @@ -136,10 +136,10 @@ func setupCredentialMocks(mockStorageClient store.MockStorageClient) { }, } - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, id string, options ...store.GetOptions) (*store.Object, error) { - return &store.Object{ - Metadata: store.Metadata{ + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()). + DoAndReturn(func(ctx context.Context, id string, options ...database.GetOptions) (*database.Object, error) { + return &database.Object{ + Metadata: database.Metadata{ ID: datamodelCredential.TrackedResource.ID, }, Data: &datamodelCredential, @@ -147,42 +147,42 @@ func setupCredentialMocks(mockStorageClient store.MockStorageClient) { }).Times(1) } -func setupCredentialDeleteSuccessMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - setupCredentialMocks(mockStorageClient) +func setupCredentialDeleteSuccessMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + setupCredentialMocks(mockDatabaseClient) mockSecretClient.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil).Times(1) - mockStorageClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) + mockDatabaseClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) } -func setupNonExistentCredentialDeleteMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, &store.ErrNotFound{}).Times(1) +func setupNonExistentCredentialDeleteMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, &database.ErrNotFound{}).Times(1) } -func setupCredentialExistenceCheckFailureMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - mockStorageClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("test_failure")).Times(1) +func setupCredentialExistenceCheckFailureMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + mockDatabaseClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("test_failure")).Times(1) } -func setupNonExistentSecretDeleteMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - setupCredentialMocks(mockStorageClient) +func setupNonExistentSecretDeleteMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + setupCredentialMocks(mockDatabaseClient) mockSecretClient.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(&secret.ErrNotFound{}).Times(1) } -func setupSecretDeleteFailureMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - setupCredentialMocks(mockStorageClient) +func setupSecretDeleteFailureMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + setupCredentialMocks(mockDatabaseClient) mockSecretClient.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(errors.New("Failed secret deletion")).Times(1) } -func setupNonExistingCredentialDeleteFromStorageMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - setupCredentialMocks(mockStorageClient) +func setupNonExistingCredentialDeleteFromStorageMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + setupCredentialMocks(mockDatabaseClient) mockSecretClient.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil).Times(1) - mockStorageClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(&store.ErrNotFound{}).Times(1) + mockDatabaseClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(&database.ErrNotFound{}).Times(1) } -func setupFailedCredentialDeleteFromStorageMocks(mockStorageClient store.MockStorageClient, mockSecretClient secret.MockClient) { - setupCredentialMocks(mockStorageClient) +func setupFailedCredentialDeleteFromStorageMocks(mockDatabaseClient database.MockClient, mockSecretClient secret.MockClient) { + setupCredentialMocks(mockDatabaseClient) mockSecretClient.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil).Times(1) - mockStorageClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("Failed Storage Deletion")).Times(1) + mockDatabaseClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("Failed Storage Deletion")).Times(1) } diff --git a/pkg/ucp/frontend/controller/planes/listplanes.go b/pkg/ucp/frontend/controller/planes/listplanes.go index 25592d705d..a90a1c9e5f 100644 --- a/pkg/ucp/frontend/controller/planes/listplanes.go +++ b/pkg/ucp/frontend/controller/planes/listplanes.go @@ -23,9 +23,9 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" armrpc_controller "github.com/radius-project/radius/pkg/armrpc/frontend/controller" armrpc_rest "github.com/radius-project/radius/pkg/armrpc/rest" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/datamodel/converter" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/ucplog" ) @@ -48,7 +48,7 @@ func NewListPlanes(opts armrpc_controller.Options) (armrpc_controller.Controller }, nil } -// Run() queries the storage client for planes in a given scope, creates a response with the results, and +// Run() queries the database client for planes in a given scope, creates a response with the results, and // returns an OKResponse with the response. If an error occurs, it is returned. func (e *ListPlanes) Run(ctx context.Context, w http.ResponseWriter, req *http.Request) (armrpc_rest.Response, error) { serviceCtx := v1.ARMRequestContextFromContext(ctx) @@ -61,16 +61,16 @@ func (e *ListPlanes) Run(ctx context.Context, w http.ResponseWriter, req *http.R "radius", } - objs := []store.Object{} + objs := []database.Object{} for _, planeType := range planeTypes { - query := store.Query{ + query := database.Query{ RootScope: serviceCtx.ResourceID.String(), ResourceType: planeType, IsScopeQuery: true, } logger.Info(fmt.Sprintf("Listing planes of type %s in scope %s", query.ResourceType, query.RootScope)) - result, err := e.StorageClient().Query(ctx, query) + result, err := e.DatabaseClient().Query(ctx, query) if err != nil { return nil, err } @@ -86,7 +86,7 @@ func (e *ListPlanes) Run(ctx context.Context, w http.ResponseWriter, req *http.R return ok, nil } -func (p *ListPlanes) createResponse(ctx context.Context, objs []store.Object) (*v1.PaginatedList, error) { +func (p *ListPlanes) createResponse(ctx context.Context, objs []database.Object) (*v1.PaginatedList, error) { serviceCtx := v1.ARMRequestContextFromContext(ctx) items := v1.PaginatedList{} diff --git a/pkg/ucp/frontend/controller/planes/listplanes_test.go b/pkg/ucp/frontend/controller/planes/listplanes_test.go index 505a3cd320..aac6c6d086 100644 --- a/pkg/ucp/frontend/controller/planes/listplanes_test.go +++ b/pkg/ucp/frontend/controller/planes/listplanes_test.go @@ -25,8 +25,8 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/to" "github.com/radius-project/radius/pkg/ucp/api/v20231001preview" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) @@ -34,9 +34,9 @@ import ( func Test_ListPlanes(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() - mockStorageClient := store.NewMockStorageClient(mockCtrl) + mockDatabaseClient := database.NewMockClient(mockCtrl) - planesCtrl, err := NewListPlanes(armrpc_controller.Options{StorageClient: mockStorageClient}) + planesCtrl, err := NewListPlanes(armrpc_controller.Options{DatabaseClient: mockDatabaseClient}) require.NoError(t, err) url := "/planes?api-version=2023-10-01-preview" @@ -57,30 +57,30 @@ func Test_ListPlanes(t *testing.T) { Properties: datamodel.AWSPlaneProperties{}, } - mockStorageClient.EXPECT().Query(gomock.Any(), store.Query{ + mockDatabaseClient.EXPECT().Query(gomock.Any(), database.Query{ RootScope: "/planes", ResourceType: "aws", IsScopeQuery: true, - }).Return(&store.ObjectQueryResult{ - Items: []store.Object{ + }).Return(&database.ObjectQueryResult{ + Items: []database.Object{ { - Metadata: store.Metadata{}, + Metadata: database.Metadata{}, Data: &planeData, }, }, }, nil) - mockStorageClient.EXPECT().Query(gomock.Any(), store.Query{ + mockDatabaseClient.EXPECT().Query(gomock.Any(), database.Query{ RootScope: "/planes", ResourceType: "azure", IsScopeQuery: true, - }).Return(&store.ObjectQueryResult{}, nil) + }).Return(&database.ObjectQueryResult{}, nil) - mockStorageClient.EXPECT().Query(gomock.Any(), store.Query{ + mockDatabaseClient.EXPECT().Query(gomock.Any(), database.Query{ RootScope: "/planes", ResourceType: "radius", IsScopeQuery: true, - }).Return(&store.ObjectQueryResult{}, nil) + }).Return(&database.ObjectQueryResult{}, nil) request, err := http.NewRequest(http.MethodGet, url, nil) require.NoError(t, err) diff --git a/pkg/ucp/frontend/controller/planes/listplanesbytype.go b/pkg/ucp/frontend/controller/planes/listplanesbytype.go index 69ca21f49d..c5dda15396 100644 --- a/pkg/ucp/frontend/controller/planes/listplanesbytype.go +++ b/pkg/ucp/frontend/controller/planes/listplanesbytype.go @@ -26,9 +26,9 @@ import ( armrpc_controller "github.com/radius-project/radius/pkg/armrpc/frontend/controller" armrpc_rest "github.com/radius-project/radius/pkg/armrpc/rest" "github.com/radius-project/radius/pkg/middleware" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/ucplog" ) @@ -42,20 +42,20 @@ type ListPlanesByType[P interface { armrpc_controller.Operation[P, T] } -// ListPlanesByType takes in a request object and returns a list of planes of a given type from the storage client. If +// ListPlanesByType takes in a request object and returns a list of planes of a given type from the database client. If // an error occurs, it returns an error. func (e *ListPlanesByType[P, T]) Run(ctx context.Context, w http.ResponseWriter, req *http.Request) (armrpc_rest.Response, error) { path := middleware.GetRelativePath(e.Options().PathBase, req.URL.Path) // The path is /planes/{planeType} planeType := strings.Split(path, resources.SegmentSeparator)[2] - query := store.Query{ + query := database.Query{ RootScope: resources.SegmentSeparator + resources.PlanesSegment, IsScopeQuery: true, ResourceType: planeType, } logger := ucplog.FromContextOrDiscard(ctx) logger.Info(fmt.Sprintf("Listing planes in scope %s/%s", query.RootScope, planeType)) - result, err := e.StorageClient().Query(ctx, query) + result, err := e.DatabaseClient().Query(ctx, query) if err != nil { return nil, err } @@ -67,7 +67,7 @@ func (e *ListPlanesByType[P, T]) Run(ctx context.Context, w http.ResponseWriter, return ok, nil } -func (p *ListPlanesByType[P, T]) createResponse(ctx context.Context, result *store.ObjectQueryResult) (*v1.PaginatedList, error) { +func (p *ListPlanesByType[P, T]) createResponse(ctx context.Context, result *database.ObjectQueryResult) (*v1.PaginatedList, error) { serviceCtx := v1.ARMRequestContextFromContext(ctx) items := v1.PaginatedList{} diff --git a/pkg/ucp/frontend/controller/planes/listplanesbytype_test.go b/pkg/ucp/frontend/controller/planes/listplanesbytype_test.go index 58bf997eed..e426a6255b 100644 --- a/pkg/ucp/frontend/controller/planes/listplanesbytype_test.go +++ b/pkg/ucp/frontend/controller/planes/listplanesbytype_test.go @@ -25,9 +25,9 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/to" "github.com/radius-project/radius/pkg/ucp/api/v20231001preview" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/datamodel/converter" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) @@ -35,11 +35,11 @@ import ( func Test_ListPlanesByType(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() - mockStorageClient := store.NewMockStorageClient(mockCtrl) + mockDatabaseClient := database.NewMockClient(mockCtrl) ctrl := &ListPlanesByType[*datamodel.RadiusPlane, datamodel.RadiusPlane]{ Operation: armrpc_controller.NewOperation[*datamodel.RadiusPlane, datamodel.RadiusPlane]( - armrpc_controller.Options{StorageClient: mockStorageClient}, + armrpc_controller.Options{DatabaseClient: mockDatabaseClient}, armrpc_controller.ResourceOptions[datamodel.RadiusPlane]{ ResponseConverter: converter.RadiusPlaneDataModelToVersioned, }), @@ -47,7 +47,7 @@ func Test_ListPlanesByType(t *testing.T) { url := "/planes/radius?api-version=2023-10-01-preview" - query := store.Query{ + query := database.Query{ RootScope: "/planes", IsScopeQuery: true, ResourceType: "radius", @@ -73,10 +73,10 @@ func Test_ListPlanesByType(t *testing.T) { }, } - mockStorageClient.EXPECT().Query(gomock.Any(), query).Return(&store.ObjectQueryResult{ - Items: []store.Object{ + mockDatabaseClient.EXPECT().Query(gomock.Any(), query).Return(&database.ObjectQueryResult{ + Items: []database.Object{ { - Metadata: store.Metadata{}, + Metadata: database.Metadata{}, Data: &planeData, }, }, diff --git a/pkg/ucp/frontend/controller/radius/proxy.go b/pkg/ucp/frontend/controller/radius/proxy.go index 84cc7360a2..25fff5ea23 100644 --- a/pkg/ucp/frontend/controller/radius/proxy.go +++ b/pkg/ucp/frontend/controller/radius/proxy.go @@ -31,11 +31,11 @@ import ( armrpc_controller "github.com/radius-project/radius/pkg/armrpc/frontend/controller" armrpc_rest "github.com/radius-project/radius/pkg/armrpc/rest" "github.com/radius-project/radius/pkg/middleware" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/frontend/controller/resourcegroups" "github.com/radius-project/radius/pkg/ucp/proxy" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/trackedresource" "github.com/radius-project/radius/pkg/ucp/ucplog" ) @@ -82,7 +82,7 @@ func NewProxyController(opts armrpc_controller.Options, transport http.RoundTrip return nil, fmt.Errorf("failed to parse default downstream URL: %w", err) } - updater := trackedresource.NewUpdater(opts.StorageClient, &http.Client{Transport: transport}) + updater := trackedresource.NewUpdater(opts.DatabaseClient, &http.Client{Transport: transport}) return &ProxyController{ Operation: armrpc_controller.NewOperation(opts, armrpc_controller.ResourceOptions[datamodel.RadiusPlane]{}), transport: transport, @@ -113,7 +113,7 @@ func (p *ProxyController) Run(ctx context.Context, w http.ResponseWriter, req *h return armrpc_rest.NewBadRequestARMResponse(response), nil } - downstreamURL, err := resourcegroups.ValidateDownstream(ctx, p.StorageClient(), id, v1.LocationGlobal, apiVersion) + downstreamURL, err := resourcegroups.ValidateDownstream(ctx, p.DatabaseClient(), id, v1.LocationGlobal, apiVersion) if errors.Is(err, &resourcegroups.NotFoundError{}) { return armrpc_rest.NewNotFoundResponseWithCause(id, err.Error()), nil } else if errors.Is(err, &resourcegroups.InvalidError{}) { @@ -279,8 +279,8 @@ func (p *ProxyController) EnqueueTrackedResourceUpdate(ctx context.Context, id r queueOperation := false retry: for retryCount := 1; retryCount <= EnqueueOperationRetryCount; retryCount++ { - obj, err := p.StorageClient().Get(ctx, trackingID.String()) - if errors.Is(err, &store.ErrNotFound{}) { + obj, err := p.DatabaseClient().Get(ctx, trackingID.String()) + if errors.Is(err, &database.ErrNotFound{}) { // Safe to ignore. This means that the resource has not been tracked yet. } else if err != nil { return err @@ -302,8 +302,8 @@ retry: } logger.V(ucplog.LevelDebug).Info("enqueuing tracked resource update") - err = p.StorageClient().Save(ctx, &store.Object{Metadata: store.Metadata{ID: trackingID.String()}, Data: entry}, store.WithETag(etag)) - if errors.Is(err, &store.ErrConcurrency{}) { + err = p.DatabaseClient().Save(ctx, &database.Object{Metadata: database.Metadata{ID: trackingID.String()}, Data: entry}, database.WithETag(etag)) + if errors.Is(err, &database.ErrConcurrency{}) { // This means we hit a concurrency error saving the tracked resource entry. This means that the resource // was updated in the background. We should retry. logger.V(ucplog.LevelDebug).Info("enqueue tracked resource update failed due to concurrency error", "retryCount", retryCount) diff --git a/pkg/ucp/frontend/controller/radius/proxy_test.go b/pkg/ucp/frontend/controller/radius/proxy_test.go index 8e51472637..aeb5d4d4d5 100644 --- a/pkg/ucp/frontend/controller/radius/proxy_test.go +++ b/pkg/ucp/frontend/controller/radius/proxy_test.go @@ -28,9 +28,9 @@ import ( "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" "github.com/radius-project/radius/pkg/armrpc/frontend/controller" "github.com/radius-project/radius/pkg/armrpc/rest" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/trackedresource" "github.com/radius-project/radius/test/testcontext" "github.com/stretchr/testify/require" @@ -44,15 +44,15 @@ const ( // The Run function is also tested by integration tests in the pkg/ucp/integrationtests/radius package. -func createController(t *testing.T) (*ProxyController, *store.MockStorageClient, *mockUpdater, *mockRoundTripper, *statusmanager.MockStatusManager) { +func createController(t *testing.T) (*ProxyController, *database.MockClient, *mockUpdater, *mockRoundTripper, *statusmanager.MockStatusManager) { ctrl := gomock.NewController(t) - storageClient := store.NewMockStorageClient(ctrl) + databaseClient := database.NewMockClient(ctrl) statusManager := statusmanager.NewMockStatusManager(ctrl) roundTripper := mockRoundTripper{} p, err := NewProxyController( - controller.Options{StorageClient: storageClient, StatusManager: statusManager}, + controller.Options{DatabaseClient: databaseClient, StatusManager: statusManager}, &roundTripper, "http://localhost:1234") require.NoError(t, err) @@ -62,7 +62,7 @@ func createController(t *testing.T) (*ProxyController, *store.MockStorageClient, pc := p.(*ProxyController) pc.updater = &updater - return pc, storageClient, &updater, &roundTripper, statusManager + return pc, databaseClient, &updater, &roundTripper, statusManager } func Test_Run(t *testing.T) { @@ -83,7 +83,7 @@ func Test_Run(t *testing.T) { resourceGroup := datamodel.ResourceGroup{} t.Run("success (non-tracked)", func(t *testing.T) { - p, storageClient, _, roundTripper, _ := createController(t) + p, databaseClient, _, roundTripper, _ := createController(t) svcContext := &v1.ARMRequestContext{ APIVersion: apiVersion, @@ -97,17 +97,17 @@ func Test_Run(t *testing.T) { // Not a mutating request req := httptest.NewRequest(http.MethodGet, id.String()+"?api-version="+apiVersion, nil) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), resourceTypeID.String(), gomock.Any()). - Return(nil, &store.ErrNotFound{}).Times(1) + Return(nil, &database.ErrNotFound{}).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), "/planes/"+id.PlaneNamespace(), gomock.Any()). - Return(&store.Object{Data: plane}, nil).Times(1) + Return(&database.Object{Data: plane}, nil).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), id.RootScope(), gomock.Any()). - Return(&store.Object{Data: resourceGroup}, nil).Times(1) + Return(&database.Object{Data: resourceGroup}, nil).Times(1) downstreamResponse := httptest.NewRecorder() downstreamResponse.WriteHeader(http.StatusOK) @@ -119,7 +119,7 @@ func Test_Run(t *testing.T) { }) t.Run("success (tracked terminal response)", func(t *testing.T) { - p, storageClient, updater, roundTripper, _ := createController(t) + p, databaseClient, updater, roundTripper, _ := createController(t) svcContext := &v1.ARMRequestContext{ APIVersion: apiVersion, @@ -133,17 +133,17 @@ func Test_Run(t *testing.T) { // Mutating request that will complete synchronously req := httptest.NewRequest(http.MethodDelete, id.String()+"?api-version="+apiVersion, nil) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), resourceTypeID.String(), gomock.Any()). - Return(nil, &store.ErrNotFound{}).Times(1) + Return(nil, &database.ErrNotFound{}).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), "/planes/"+id.PlaneNamespace(), gomock.Any()). - Return(&store.Object{Data: plane}, nil).Times(1) + Return(&database.Object{Data: plane}, nil).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), id.RootScope(), gomock.Any()). - Return(&store.Object{Data: resourceGroup}, nil).Times(1) + Return(&database.Object{Data: resourceGroup}, nil).Times(1) downstreamResponse := httptest.NewRecorder() downstreamResponse.WriteHeader(http.StatusOK) @@ -158,7 +158,7 @@ func Test_Run(t *testing.T) { }) t.Run("success (fallback to async)", func(t *testing.T) { - p, storageClient, updater, roundTripper, statusManager := createController(t) + p, databaseClient, updater, roundTripper, statusManager := createController(t) svcContext := &v1.ARMRequestContext{ APIVersion: apiVersion, @@ -172,23 +172,23 @@ func Test_Run(t *testing.T) { // Mutating request that will complete synchronously req := httptest.NewRequest(http.MethodDelete, id.String()+"?api-version="+apiVersion, nil) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), resourceTypeID.String(), gomock.Any()). - Return(nil, &store.ErrNotFound{}).Times(1) + Return(nil, &database.ErrNotFound{}).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), "/planes/"+id.PlaneNamespace(), gomock.Any()). - Return(&store.Object{Data: plane}, nil).Times(1) + Return(&database.Object{Data: plane}, nil).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), id.RootScope(), gomock.Any()). - Return(&store.Object{Data: resourceGroup}, nil).Times(1) + Return(&database.Object{Data: resourceGroup}, nil).Times(1) // Tracking entry created - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), gomock.Any(), gomock.Any()). - Return(nil, &store.ErrNotFound{}).Times(1) - storageClient.EXPECT(). + Return(nil, &database.ErrNotFound{}).Times(1) + databaseClient.EXPECT(). Save(gomock.Any(), gomock.Any(), gomock.Any()). Return(nil).Times(1) @@ -209,7 +209,7 @@ func Test_Run(t *testing.T) { }) t.Run("success (fallback to async without workitem)", func(t *testing.T) { - p, storageClient, updater, roundTripper, _ := createController(t) + p, databaseClient, updater, roundTripper, _ := createController(t) svcContext := &v1.ARMRequestContext{ APIVersion: apiVersion, @@ -223,20 +223,20 @@ func Test_Run(t *testing.T) { // Mutating request that will complete asynchronously req := httptest.NewRequest(http.MethodDelete, id.String()+"?api-version="+apiVersion, nil) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), resourceTypeID.String(), gomock.Any()). - Return(nil, &store.ErrNotFound{}).Times(1) + Return(nil, &database.ErrNotFound{}).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), "/planes/"+id.PlaneNamespace(), gomock.Any()). - Return(&store.Object{Data: plane}, nil).Times(1) + Return(&database.Object{Data: plane}, nil).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), id.RootScope(), gomock.Any()). - Return(&store.Object{Data: resourceGroup}, nil).Times(1) + Return(&database.Object{Data: resourceGroup}, nil).Times(1) // Tracking entry created - existingEntry := &store.Object{ + existingEntry := &database.Object{ Data: &datamodel.GenericResource{ BaseResource: v1.BaseResource{ InternalMetadata: v1.InternalMetadata{ @@ -245,10 +245,10 @@ func Test_Run(t *testing.T) { }, }, } - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), gomock.Any(), gomock.Any()). Return(existingEntry, nil).Times(1) - storageClient.EXPECT(). + databaseClient.EXPECT(). Save(gomock.Any(), gomock.Any(), gomock.Any()). Return(nil).Times(1) @@ -267,7 +267,7 @@ func Test_Run(t *testing.T) { }) t.Run("failure (validate downstream: not found)", func(t *testing.T) { - p, storageClient, _, _, _ := createController(t) + p, databaseClient, _, _, _ := createController(t) svcContext := &v1.ARMRequestContext{ APIVersion: apiVersion, @@ -279,9 +279,9 @@ func Test_Run(t *testing.T) { w := httptest.NewRecorder() req := httptest.NewRequest(http.MethodPut, id.String()+"?api-version="+apiVersion, nil) - storageClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), "/planes/"+id.PlaneNamespace(), gomock.Any()). - Return(nil, &store.ErrNotFound{}).Times(1) + Return(nil, &database.ErrNotFound{}).Times(1) expected := rest.NewNotFoundResponseWithCause(id, "plane \"/planes/test/local\" not found") diff --git a/pkg/ucp/frontend/controller/resourcegroups/listresourcegroups.go b/pkg/ucp/frontend/controller/resourcegroups/listresourcegroups.go index c4ad1e988c..58cf0dd321 100644 --- a/pkg/ucp/frontend/controller/resourcegroups/listresourcegroups.go +++ b/pkg/ucp/frontend/controller/resourcegroups/listresourcegroups.go @@ -23,10 +23,10 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" armrpc_controller "github.com/radius-project/radius/pkg/armrpc/frontend/controller" armrpc_rest "github.com/radius-project/radius/pkg/armrpc/rest" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/datamodel/converter" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/ucplog" ) @@ -49,7 +49,7 @@ func NewListResourceGroups(opts armrpc_controller.Options) (armrpc_controller.Co }, nil } -// Run() function extracts the plane type and name from the request URL, queries the storage client for resource groups in the +// Run() function extracts the plane type and name from the request URL, queries the database client for resource groups in the // scope of the plane, creates a response with the list of resource groups and returns an OK response with the list of resource groups. func (r *ListResourceGroups) Run(ctx context.Context, w http.ResponseWriter, req *http.Request) (armrpc_rest.Response, error) { logger := ucplog.FromContextOrDiscard(ctx) @@ -60,13 +60,13 @@ func (r *ListResourceGroups) Run(ctx context.Context, w http.ResponseWriter, req return nil, err } - var query store.Query + var query database.Query query.RootScope = resources.SegmentSeparator + resources.PlanesSegment + resources.SegmentSeparator + planeType + resources.SegmentSeparator + planeName query.IsScopeQuery = true query.ResourceType = "resourcegroups" logger.Info(fmt.Sprintf("Listing resource groups in scope %s", query.RootScope)) - result, err := r.StorageClient().Query(ctx, query) + result, err := r.DatabaseClient().Query(ctx, query) if err != nil { return nil, err } @@ -79,7 +79,7 @@ func (r *ListResourceGroups) Run(ctx context.Context, w http.ResponseWriter, req return ok, nil } -func (e *ListResourceGroups) createResponse(ctx context.Context, result *store.ObjectQueryResult) (*v1.PaginatedList, error) { +func (e *ListResourceGroups) createResponse(ctx context.Context, result *database.ObjectQueryResult) (*v1.PaginatedList, error) { items := v1.PaginatedList{} serviceCtx := v1.ARMRequestContextFromContext(ctx) diff --git a/pkg/ucp/frontend/controller/resourcegroups/listresourcegroups_test.go b/pkg/ucp/frontend/controller/resourcegroups/listresourcegroups_test.go index e91a917c8d..ce7b87ce8b 100644 --- a/pkg/ucp/frontend/controller/resourcegroups/listresourcegroups_test.go +++ b/pkg/ucp/frontend/controller/resourcegroups/listresourcegroups_test.go @@ -29,21 +29,21 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/to" "github.com/radius-project/radius/pkg/ucp/api/v20231001preview" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" - "github.com/radius-project/radius/pkg/ucp/store" ) func Test_ListResourceGroups(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() - mockStorageClient := store.NewMockStorageClient(mockCtrl) + mockDatabaseClient := database.NewMockClient(mockCtrl) - rgCtrl, err := NewListResourceGroups(armrpc_controller.Options{StorageClient: mockStorageClient}) + rgCtrl, err := NewListResourceGroups(armrpc_controller.Options{DatabaseClient: mockDatabaseClient}) require.NoError(t, err) url := "/planes/radius/local/resourceGroups?api-version=2023-10-01-preview" - query := store.Query{ + query := database.Query{ RootScope: "/planes/radius/local", IsScopeQuery: true, ResourceType: "resourcegroups", @@ -63,11 +63,11 @@ func Test_ListResourceGroups(t *testing.T) { }, } - mockStorageClient.EXPECT().Query(gomock.Any(), query).DoAndReturn(func(ctx context.Context, query store.Query, options ...store.QueryOptions) (*store.ObjectQueryResult, error) { - return &store.ObjectQueryResult{ - Items: []store.Object{ + mockDatabaseClient.EXPECT().Query(gomock.Any(), query).DoAndReturn(func(ctx context.Context, query database.Query, options ...database.QueryOptions) (*database.ObjectQueryResult, error) { + return &database.ObjectQueryResult{ + Items: []database.Object{ { - Metadata: store.Metadata{}, + Metadata: database.Metadata{}, Data: &rg, }, }, diff --git a/pkg/ucp/frontend/controller/resourcegroups/listresources.go b/pkg/ucp/frontend/controller/resourcegroups/listresources.go index 4cfc82a53c..66a3cb6b66 100644 --- a/pkg/ucp/frontend/controller/resourcegroups/listresources.go +++ b/pkg/ucp/frontend/controller/resourcegroups/listresources.go @@ -25,10 +25,10 @@ import ( armrpc_rest "github.com/radius-project/radius/pkg/armrpc/rest" "github.com/radius-project/radius/pkg/middleware" "github.com/radius-project/radius/pkg/ucp/api/v20231001preview" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/datamodel/converter" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" ) var _ armrpc_controller.Controller = (*ListResources)(nil) @@ -62,19 +62,19 @@ func (r *ListResources) Run(ctx context.Context, w http.ResponseWriter, req *htt resourceGroupID := id.Truncate() // First check if the resource group exists. - _, err = r.StorageClient().Get(ctx, resourceGroupID.String()) - if errors.Is(err, &store.ErrNotFound{}) { + _, err = r.DatabaseClient().Get(ctx, resourceGroupID.String()) + if errors.Is(err, &database.ErrNotFound{}) { return armrpc_rest.NewNotFoundResponse(id), nil } else if err != nil { return nil, err } - query := store.Query{ + query := database.Query{ RootScope: resourceGroupID.String(), ResourceType: v20231001preview.ResourceType, } - result, err := r.StorageClient().Query(ctx, query) + result, err := r.DatabaseClient().Query(ctx, query) if err != nil { return nil, err } @@ -87,7 +87,7 @@ func (r *ListResources) Run(ctx context.Context, w http.ResponseWriter, req *htt return armrpc_rest.NewOKResponse(response), nil } -func (r *ListResources) createResponse(ctx context.Context, result *store.ObjectQueryResult) (*v1.PaginatedList, error) { +func (r *ListResources) createResponse(ctx context.Context, result *database.ObjectQueryResult) (*v1.PaginatedList, error) { items := v1.PaginatedList{} serviceCtx := v1.ARMRequestContextFromContext(ctx) diff --git a/pkg/ucp/frontend/controller/resourcegroups/listresources_test.go b/pkg/ucp/frontend/controller/resourcegroups/listresources_test.go index c7f77c9934..35e58eb8d8 100644 --- a/pkg/ucp/frontend/controller/resourcegroups/listresources_test.go +++ b/pkg/ucp/frontend/controller/resourcegroups/listresources_test.go @@ -29,9 +29,9 @@ import ( "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/to" "github.com/radius-project/radius/pkg/ucp/api/v20231001preview" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" ) func Test_ListResources(t *testing.T) { @@ -62,17 +62,17 @@ func Test_ListResources(t *testing.T) { id := resourceGroupID + "/resources" t.Run("success", func(t *testing.T) { - storage, ctrl := setupListResources(t) + databaseClient, ctrl := setupListResources(t) - storage.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), resourceGroupID). - Return(&store.Object{Data: resourceGroupDatamodel}, nil). + Return(&database.Object{Data: resourceGroupDatamodel}, nil). Times(1) - expectedQuery := store.Query{RootScope: resourceGroupID, ResourceType: v20231001preview.ResourceType} - storage.EXPECT(). + expectedQuery := database.Query{RootScope: resourceGroupID, ResourceType: v20231001preview.ResourceType} + databaseClient.EXPECT(). Query(gomock.Any(), expectedQuery). - Return(&store.ObjectQueryResult{Items: []store.Object{{Data: entryDatamodel}}}, nil). + Return(&database.ObjectQueryResult{Items: []database.Object{{Data: entryDatamodel}}}, nil). Times(1) expected := armrpc_rest.NewOKResponse(&v1.PaginatedList{ @@ -88,17 +88,17 @@ func Test_ListResources(t *testing.T) { }) t.Run("success - empty", func(t *testing.T) { - storage, ctrl := setupListResources(t) + databaseClient, ctrl := setupListResources(t) - storage.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), resourceGroupID). - Return(&store.Object{Data: resourceGroupDatamodel}, nil). + Return(&database.Object{Data: resourceGroupDatamodel}, nil). Times(1) - expectedQuery := store.Query{RootScope: resourceGroupID, ResourceType: v20231001preview.ResourceType} - storage.EXPECT(). + expectedQuery := database.Query{RootScope: resourceGroupID, ResourceType: v20231001preview.ResourceType} + databaseClient.EXPECT(). Query(gomock.Any(), expectedQuery). - Return(&store.ObjectQueryResult{Items: []store.Object{}}, nil). + Return(&database.ObjectQueryResult{Items: []database.Object{}}, nil). Times(1) expected := armrpc_rest.NewOKResponse(&v1.PaginatedList{}) @@ -112,11 +112,11 @@ func Test_ListResources(t *testing.T) { }) t.Run("resource group not found", func(t *testing.T) { - storage, ctrl := setupListResources(t) + databaseClient, ctrl := setupListResources(t) - storage.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), resourceGroupID). - Return(nil, &store.ErrNotFound{ID: resourceGroupID}). + Return(nil, &database.ErrNotFound{ID: resourceGroupID}). Times(1) parsed, err := resources.Parse(id) @@ -133,12 +133,12 @@ func Test_ListResources(t *testing.T) { }) } -func setupListResources(t *testing.T) (*store.MockStorageClient, *ListResources) { +func setupListResources(t *testing.T) (*database.MockClient, *ListResources) { ctrl := gomock.NewController(t) - storage := store.NewMockStorageClient(ctrl) + databaseClient := database.NewMockClient(ctrl) - c, err := NewListResources(armrpc_controller.Options{StorageClient: storage, PathBase: "/" + uuid.New().String()}) + c, err := NewListResources(armrpc_controller.Options{DatabaseClient: databaseClient, PathBase: "/" + uuid.New().String()}) require.NoError(t, err) - return storage, c.(*ListResources) + return databaseClient, c.(*ListResources) } diff --git a/pkg/ucp/frontend/controller/resourcegroups/util.go b/pkg/ucp/frontend/controller/resourcegroups/util.go index a1d5f8c507..4edbef9f96 100644 --- a/pkg/ucp/frontend/controller/resourcegroups/util.go +++ b/pkg/ucp/frontend/controller/resourcegroups/util.go @@ -23,10 +23,10 @@ import ( "net/url" "strings" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/resources" resources_radius "github.com/radius-project/radius/pkg/ucp/resources/radius" - "github.com/radius-project/radius/pkg/ucp/store" ) // NotFoundError is returned when a resource group or plane is not found. @@ -62,15 +62,15 @@ func (e *InvalidError) Is(err error) bool { } // ValidateRadiusPlane validates that the plane specified in the id exists. Returns NotFoundError if the plane does not exist. -func ValidateRadiusPlane(ctx context.Context, client store.StorageClient, id resources.ID) (*datamodel.RadiusPlane, error) { +func ValidateRadiusPlane(ctx context.Context, client database.Client, id resources.ID) (*datamodel.RadiusPlane, error) { planeID, err := resources.ParseScope(id.PlaneScope()) if err != nil { // Not expected to happen. return nil, err } - plane, err := store.GetResource[datamodel.RadiusPlane](ctx, client, planeID.String()) - if errors.Is(err, &store.ErrNotFound{}) { + plane, err := database.GetResource[datamodel.RadiusPlane](ctx, client, planeID.String()) + if errors.Is(err, &database.ErrNotFound{}) { return nil, &NotFoundError{Message: fmt.Sprintf("plane %q not found", planeID.String())} } else if err != nil { return nil, fmt.Errorf("failed to fetch plane %q: %w", planeID.String(), err) @@ -81,7 +81,7 @@ func ValidateRadiusPlane(ctx context.Context, client store.StorageClient, id res // ValidateResourceGroup validates that the resource group specified in the id exists (if applicable). // Returns NotFoundError if the resource group does not exist. -func ValidateResourceGroup(ctx context.Context, client store.StorageClient, id resources.ID) error { +func ValidateResourceGroup(ctx context.Context, client database.Client, id resources.ID) error { // If the ID contains a resource group, validate it now. if id.FindScope(resources_radius.ScopeResourceGroups) == "" { return nil @@ -93,8 +93,8 @@ func ValidateResourceGroup(ctx context.Context, client store.StorageClient, id r return err } - _, err = store.GetResource[datamodel.ResourceGroup](ctx, client, resourceGroupID.String()) - if errors.Is(err, &store.ErrNotFound{}) { + _, err = database.GetResource[datamodel.ResourceGroup](ctx, client, resourceGroupID.String()) + if errors.Is(err, &database.ErrNotFound{}) { return &NotFoundError{Message: fmt.Sprintf("resource group %q not found", resourceGroupID.String())} } else if err != nil { return fmt.Errorf("failed to fetch resource group %q: %w", resourceGroupID.String(), err) @@ -108,7 +108,7 @@ func ValidateResourceGroup(ctx context.Context, client store.StorageClient, id r // // Returns NotFoundError if the resource type does not exist. // Returns InvalidError if the request cannot be routed due to an invalid configuration. -func ValidateResourceType(ctx context.Context, client store.StorageClient, id resources.ID, locationName string, apiVersion string) (*url.URL, error) { +func ValidateResourceType(ctx context.Context, client database.Client, id resources.ID, locationName string, apiVersion string) (*url.URL, error) { // The strategy is to: // - Look up the resource type and validate that it exists .. then // - Look up the location resource, and validate that it supports the requested resource type and API version. @@ -121,8 +121,8 @@ func ValidateResourceType(ctx context.Context, client store.StorageClient, id re return nil, err } - _, err = store.GetResource[datamodel.ResourceType](ctx, client, resourceTypeID.String()) - if errors.Is(err, &store.ErrNotFound{}) { + _, err = database.GetResource[datamodel.ResourceType](ctx, client, resourceTypeID.String()) + if errors.Is(err, &database.ErrNotFound{}) { // Return the error as-is to fallback to the legacy routing behavior. return nil, err @@ -139,8 +139,8 @@ func ValidateResourceType(ctx context.Context, client store.StorageClient, id re return nil, err } - location, err := store.GetResource[datamodel.Location](ctx, client, locationID.String()) - if errors.Is(err, &store.ErrNotFound{}) { + location, err := database.GetResource[datamodel.Location](ctx, client, locationID.String()) + if errors.Is(err, &database.ErrNotFound{}) { // Return the error as-is to fallback to the legacy routing behavior. return nil, err @@ -228,7 +228,7 @@ func isOperationResourceType(id resources.ID) bool { // ValidateLegacyResourceProvider validates that the resource provider specified in the id exists. Returns InvalidError if the plane // contains invalid data. -func ValidateLegacyResourceProvider(ctx context.Context, client store.StorageClient, id resources.ID, plane *datamodel.RadiusPlane) (*url.URL, error) { +func ValidateLegacyResourceProvider(ctx context.Context, client database.Client, id resources.ID, plane *datamodel.RadiusPlane) (*url.URL, error) { downstream := plane.LookupResourceProvider(id.ProviderNamespace()) if downstream == "" { return nil, &InvalidError{Message: fmt.Sprintf("resource provider %s not configured", id.ProviderNamespace())} @@ -245,7 +245,7 @@ func ValidateLegacyResourceProvider(ctx context.Context, client store.StorageCli // ValidateDownstream can be used to find and validate the downstream URL for a resource. // Returns NotFoundError for the case where the plane or resource group does not exist. // Returns InvalidError for cases where the data is invalid, like when the resource provider is not configured. -func ValidateDownstream(ctx context.Context, client store.StorageClient, id resources.ID, location string, apiVersion string) (*url.URL, error) { +func ValidateDownstream(ctx context.Context, client database.Client, id resources.ID, location string, apiVersion string) (*url.URL, error) { // There are a few steps to validation: // // - The plane exists @@ -269,7 +269,7 @@ func ValidateDownstream(ctx context.Context, client store.StorageClient, id reso // If this returns success, it means the resource type is configured using new/UDT routing. downstreamURL, err := ValidateResourceType(ctx, client, id, location, apiVersion) - if errors.Is(err, &store.ErrNotFound{}) { + if errors.Is(err, &database.ErrNotFound{}) { // If the resource provider is not found, treat it like a legacy provider. return ValidateLegacyResourceProvider(ctx, client, id, plane) } else if err != nil { diff --git a/pkg/ucp/frontend/controller/resourcegroups/util_test.go b/pkg/ucp/frontend/controller/resourcegroups/util_test.go index f266458196..7def6c8b60 100644 --- a/pkg/ucp/frontend/controller/resourcegroups/util_test.go +++ b/pkg/ucp/frontend/controller/resourcegroups/util_test.go @@ -23,9 +23,9 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" "github.com/radius-project/radius/pkg/to" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/test/testcontext" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -93,9 +93,9 @@ func Test_ValidateDownstream(t *testing.T) { }, } - setup := func(t *testing.T) *store.MockStorageClient { + setup := func(t *testing.T) *database.MockClient { ctrl := gomock.NewController(t) - return store.NewMockStorageClient(ctrl) + return database.NewMockClient(ctrl) } t.Run("success (resource group)", func(t *testing.T) { @@ -108,10 +108,10 @@ func Test_ValidateDownstream(t *testing.T) { } mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&store.Object{Data: resourceGroup}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), resourceTypeResource.ID).Return(&store.Object{Data: resourceTypeResource}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&store.Object{Data: locationResource}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&database.Object{Data: resourceGroup}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), resourceTypeResource.ID).Return(&database.Object{Data: resourceTypeResource}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&database.Object{Data: locationResource}, nil).Times(1) expectedURL, err := url.Parse(downstream) require.NoError(t, err) @@ -123,9 +123,9 @@ func Test_ValidateDownstream(t *testing.T) { t.Run("success (non resource group)", func(t *testing.T) { mock := setup(t) - mock.EXPECT().Get(gomock.Any(), idWithoutResourceGroup.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), resourceTypeResource.ID).Return(&store.Object{Data: resourceTypeResource}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&store.Object{Data: locationResource}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), idWithoutResourceGroup.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), resourceTypeResource.ID).Return(&database.Object{Data: resourceTypeResource}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&database.Object{Data: locationResource}, nil).Times(1) expectedURL, err := url.Parse(downstream) require.NoError(t, err) @@ -138,8 +138,8 @@ func Test_ValidateDownstream(t *testing.T) { // The deployment engine models its operation status resources as child resources of the deployment resource. t.Run("success (operationstatuses as child resource)", func(t *testing.T) { mock := setup(t) - mock.EXPECT().Get(gomock.Any(), idWithoutResourceGroup.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&store.Object{Data: locationResource}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), idWithoutResourceGroup.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&database.Object{Data: locationResource}, nil).Times(1) operationStatusID := resources.MustParse("/planes/radius/local/providers/System.TestRP/deployments/xzy/operationStatuses/abcd") @@ -154,8 +154,8 @@ func Test_ValidateDownstream(t *testing.T) { // All of the Radius RPs include a location in the operation status child resource. t.Run("success (operationstatuses with location)", func(t *testing.T) { mock := setup(t) - mock.EXPECT().Get(gomock.Any(), idWithoutResourceGroup.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&store.Object{Data: locationResource}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), idWithoutResourceGroup.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&database.Object{Data: locationResource}, nil).Times(1) operationStatusID := resources.MustParse("/planes/radius/local/providers/System.TestRP/locations/east/operationStatuses/abcd") @@ -170,8 +170,8 @@ func Test_ValidateDownstream(t *testing.T) { // The deployment engine models its operation result resources as child resources of the deployment resource. t.Run("success (operationresults as child resource)", func(t *testing.T) { mock := setup(t) - mock.EXPECT().Get(gomock.Any(), idWithoutResourceGroup.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&store.Object{Data: locationResource}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), idWithoutResourceGroup.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&database.Object{Data: locationResource}, nil).Times(1) operationResultID := resources.MustParse("/planes/radius/local/providers/System.TestRP/deployments/xzy/operationResults/abcd") @@ -186,8 +186,8 @@ func Test_ValidateDownstream(t *testing.T) { // All of the Radius RPs include a location in the operation result child resource. t.Run("success (operationresults with location)", func(t *testing.T) { mock := setup(t) - mock.EXPECT().Get(gomock.Any(), idWithoutResourceGroup.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&store.Object{Data: locationResource}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), idWithoutResourceGroup.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&database.Object{Data: locationResource}, nil).Times(1) operationResultID := resources.MustParse("/planes/radius/local/providers/System.TestRP/locations/east/operationResults/abcd") @@ -201,7 +201,7 @@ func Test_ValidateDownstream(t *testing.T) { t.Run("plane not found", func(t *testing.T) { mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(nil, &store.ErrNotFound{}).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(nil, &database.ErrNotFound{}).Times(1) downstreamURL, err := ValidateDownstream(testcontext.New(t), mock, id, location, apiVersion) require.Error(t, err) @@ -223,8 +223,8 @@ func Test_ValidateDownstream(t *testing.T) { t.Run("resource group not found", func(t *testing.T) { mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(nil, &store.ErrNotFound{}).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(nil, &database.ErrNotFound{}).Times(1) downstreamURL, err := ValidateDownstream(testcontext.New(t), mock, id, location, apiVersion) require.Error(t, err) @@ -235,7 +235,7 @@ func Test_ValidateDownstream(t *testing.T) { t.Run("resource group err", func(t *testing.T) { mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(nil, errors.New("test error")).Times(1) downstreamURL, err := ValidateDownstream(testcontext.New(t), mock, id, location, apiVersion) @@ -256,8 +256,8 @@ func Test_ValidateDownstream(t *testing.T) { expected := fmt.Errorf("failed to fetch resource type %q: %w", "System.TestRP/testResources", errors.New("test error")) mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&store.Object{Data: resourceGroup}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&database.Object{Data: resourceGroup}, nil).Times(1) mock.EXPECT().Get(gomock.Any(), resourceTypeResource.ID).Return(nil, errors.New("test error")).Times(1) downstreamURL, err := ValidateDownstream(testcontext.New(t), mock, id, location, apiVersion) @@ -278,9 +278,9 @@ func Test_ValidateDownstream(t *testing.T) { expected := fmt.Errorf("failed to fetch location %q: %w", locationResource.ID, errors.New("test error")) mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&store.Object{Data: resourceGroup}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), resourceTypeResource.ID).Return(&store.Object{Data: resourceTypeID}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&database.Object{Data: resourceGroup}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), resourceTypeResource.ID).Return(&database.Object{Data: resourceTypeID}, nil).Times(1) mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(nil, errors.New("test error")).Times(1) downstreamURL, err := ValidateDownstream(testcontext.New(t), mock, id, location, apiVersion) @@ -318,10 +318,10 @@ func Test_ValidateDownstream(t *testing.T) { } mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&store.Object{Data: resourceGroup}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), resourceTypeResource.ID).Return(&store.Object{Data: resourceTypeID}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&store.Object{Data: locationResource}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&database.Object{Data: resourceGroup}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), resourceTypeResource.ID).Return(&database.Object{Data: resourceTypeID}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&database.Object{Data: locationResource}, nil).Times(1) downstreamURL, err := ValidateDownstream(testcontext.New(t), mock, id, location, apiVersion) require.Error(t, err) @@ -358,10 +358,10 @@ func Test_ValidateDownstream(t *testing.T) { } mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&store.Object{Data: resourceGroup}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), resourceTypeResource.ID).Return(&store.Object{Data: resourceTypeID}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&store.Object{Data: locationResource}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&database.Object{Data: resourceGroup}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), resourceTypeResource.ID).Return(&database.Object{Data: resourceTypeID}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&database.Object{Data: locationResource}, nil).Times(1) downstreamURL, err := ValidateDownstream(testcontext.New(t), mock, id, location, apiVersion) require.Error(t, err) @@ -398,10 +398,10 @@ func Test_ValidateDownstream(t *testing.T) { } mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&store.Object{Data: resourceGroup}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), resourceTypeResource.ID).Return(&store.Object{Data: resourceTypeID}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&store.Object{Data: locationResource}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&database.Object{Data: resourceGroup}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), resourceTypeResource.ID).Return(&database.Object{Data: resourceTypeID}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), locationResource.ID).Return(&database.Object{Data: locationResource}, nil).Times(1) downstreamURL, err := ValidateDownstream(testcontext.New(t), mock, id, location, apiVersion) require.Error(t, err) @@ -437,9 +437,9 @@ func Test_ValidateDownstream_Legacy(t *testing.T) { }, } - setup := func(t *testing.T) *store.MockStorageClient { + setup := func(t *testing.T) *database.MockClient { ctrl := gomock.NewController(t) - return store.NewMockStorageClient(ctrl) + return database.NewMockClient(ctrl) } t.Run("success (resource group)", func(t *testing.T) { @@ -452,9 +452,9 @@ func Test_ValidateDownstream_Legacy(t *testing.T) { } mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&store.Object{Data: resourceGroup}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), resourceTypeID.String()).Return(nil, &store.ErrNotFound{}).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&database.Object{Data: resourceGroup}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), resourceTypeID.String()).Return(nil, &database.ErrNotFound{}).Times(1) expectedURL, err := url.Parse(downstream) require.NoError(t, err) @@ -466,8 +466,8 @@ func Test_ValidateDownstream_Legacy(t *testing.T) { t.Run("success (non resource group)", func(t *testing.T) { mock := setup(t) - mock.EXPECT().Get(gomock.Any(), idWithoutResourceGroup.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), resourceTypeID.String()).Return(nil, &store.ErrNotFound{}).Times(1) + mock.EXPECT().Get(gomock.Any(), idWithoutResourceGroup.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), resourceTypeID.String()).Return(nil, &database.ErrNotFound{}).Times(1) expectedURL, err := url.Parse(downstream) require.NoError(t, err) @@ -479,7 +479,7 @@ func Test_ValidateDownstream_Legacy(t *testing.T) { t.Run("plane not found", func(t *testing.T) { mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(nil, &store.ErrNotFound{}).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(nil, &database.ErrNotFound{}).Times(1) downstreamURL, err := ValidateDownstream(testcontext.New(t), mock, id, location, apiVersion) require.Error(t, err) @@ -501,8 +501,8 @@ func Test_ValidateDownstream_Legacy(t *testing.T) { t.Run("resource group not found", func(t *testing.T) { mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(nil, &store.ErrNotFound{}).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(nil, &database.ErrNotFound{}).Times(1) downstreamURL, err := ValidateDownstream(testcontext.New(t), mock, id, location, apiVersion) require.Error(t, err) @@ -513,7 +513,7 @@ func Test_ValidateDownstream_Legacy(t *testing.T) { t.Run("resource group err", func(t *testing.T) { mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(nil, errors.New("test error")).Times(1) downstreamURL, err := ValidateDownstream(testcontext.New(t), mock, id, location, apiVersion) @@ -543,9 +543,9 @@ func Test_ValidateDownstream_Legacy(t *testing.T) { } mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&store.Object{Data: resourceGroup}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), resourceTypeID.String()).Return(nil, &store.ErrNotFound{}).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&database.Object{Data: resourceGroup}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), resourceTypeID.String()).Return(nil, &database.ErrNotFound{}).Times(1) downstreamURL, err := ValidateDownstream(testcontext.New(t), mock, id, location, apiVersion) require.Error(t, err) @@ -574,9 +574,9 @@ func Test_ValidateDownstream_Legacy(t *testing.T) { } mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&store.Object{Data: resourceGroup}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), resourceTypeID.String()).Return(nil, &store.ErrNotFound{}).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&database.Object{Data: resourceGroup}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), resourceTypeID.String()).Return(nil, &database.ErrNotFound{}).Times(1) downstreamURL, err := ValidateDownstream(testcontext.New(t), mock, id, location, apiVersion) require.Error(t, err) @@ -607,9 +607,9 @@ func Test_ValidateDownstream_Legacy(t *testing.T) { } mock := setup(t) - mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&store.Object{Data: plane}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&store.Object{Data: resourceGroup}, nil).Times(1) - mock.EXPECT().Get(gomock.Any(), resourceTypeID.String()).Return(nil, &store.ErrNotFound{}).Times(1) + mock.EXPECT().Get(gomock.Any(), id.PlaneScope()).Return(&database.Object{Data: plane}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), id.RootScope()).Return(&database.Object{Data: resourceGroup}, nil).Times(1) + mock.EXPECT().Get(gomock.Any(), resourceTypeID.String()).Return(nil, &database.ErrNotFound{}).Times(1) downstreamURL, err := ValidateDownstream(testcontext.New(t), mock, id, location, apiVersion) require.Error(t, err) diff --git a/pkg/ucp/frontend/controller/resourceproviders/getresourceprovidersummary.go b/pkg/ucp/frontend/controller/resourceproviders/getresourceprovidersummary.go index ac0b92acd4..a1b5b638a4 100644 --- a/pkg/ucp/frontend/controller/resourceproviders/getresourceprovidersummary.go +++ b/pkg/ucp/frontend/controller/resourceproviders/getresourceprovidersummary.go @@ -26,10 +26,10 @@ import ( armrpc_controller "github.com/radius-project/radius/pkg/armrpc/frontend/controller" armrpc_rest "github.com/radius-project/radius/pkg/armrpc/rest" "github.com/radius-project/radius/pkg/middleware" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/datamodel/converter" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" ) var _ armrpc_controller.Controller = (*GetResourceProviderSummary)(nil) @@ -61,8 +61,8 @@ func (r *GetResourceProviderSummary) Run(ctx context.Context, w http.ResponseWri } // First check if the plane exists. - _, err = r.StorageClient().Get(ctx, scope.String()) - if errors.Is(err, &store.ErrNotFound{}) { + _, err = r.DatabaseClient().Get(ctx, scope.String()) + if errors.Is(err, &database.ErrNotFound{}) { return armrpc_rest.NewNotFoundResponse(scope), nil } else if err != nil { return nil, err @@ -74,8 +74,8 @@ func (r *GetResourceProviderSummary) Run(ctx context.Context, w http.ResponseWri return nil, err } - result, err := r.StorageClient().Get(ctx, id.String()) - if errors.Is(err, &store.ErrNotFound{}) { + result, err := r.DatabaseClient().Get(ctx, id.String()) + if errors.Is(err, &database.ErrNotFound{}) { // If we fail to find the summary, then use the relative path as the target. message := fmt.Sprintf("the resource provider with name '%s' was not found", name) return armrpc_rest.NewNotFoundMessageResponse(message), nil @@ -117,7 +117,7 @@ func (r *GetResourceProviderSummary) extractScopeAndName(relativePath string) (r return scope, name, nil } -func (r *GetResourceProviderSummary) createResponse(ctx context.Context, result *store.Object) (any, error) { +func (r *GetResourceProviderSummary) createResponse(ctx context.Context, result *database.Object) (any, error) { serviceCtx := v1.ARMRequestContextFromContext(ctx) summary := datamodel.ResourceProviderSummary{} diff --git a/pkg/ucp/frontend/controller/resourceproviders/listresourceprovidersummaries.go b/pkg/ucp/frontend/controller/resourceproviders/listresourceprovidersummaries.go index edd72c4575..f50570b755 100644 --- a/pkg/ucp/frontend/controller/resourceproviders/listresourceprovidersummaries.go +++ b/pkg/ucp/frontend/controller/resourceproviders/listresourceprovidersummaries.go @@ -25,10 +25,10 @@ import ( armrpc_controller "github.com/radius-project/radius/pkg/armrpc/frontend/controller" armrpc_rest "github.com/radius-project/radius/pkg/armrpc/rest" "github.com/radius-project/radius/pkg/middleware" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/datamodel/converter" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" ) var _ armrpc_controller.Controller = (*ListResourceProviderSummaries)(nil) @@ -68,20 +68,20 @@ func (r *ListResourceProviderSummaries) Run(ctx context.Context, w http.Response } // First check if the plane exists. - _, err = r.StorageClient().Get(ctx, scope.String()) - if errors.Is(err, &store.ErrNotFound{}) { + _, err = r.DatabaseClient().Get(ctx, scope.String()) + if errors.Is(err, &database.ErrNotFound{}) { return armrpc_rest.NewNotFoundResponse(scope), nil } else if err != nil { return nil, err } // Now query for resource provider summaries - query := store.Query{ + query := database.Query{ RootScope: scope.String(), ResourceType: datamodel.ResourceProviderSummaryResourceType, } - result, err := r.StorageClient().Query(ctx, query) + result, err := r.DatabaseClient().Query(ctx, query) if err != nil { return nil, err } @@ -94,7 +94,7 @@ func (r *ListResourceProviderSummaries) Run(ctx context.Context, w http.Response return armrpc_rest.NewOKResponse(response), nil } -func (r *ListResourceProviderSummaries) createResponse(ctx context.Context, result *store.ObjectQueryResult) (*v1.PaginatedList, error) { +func (r *ListResourceProviderSummaries) createResponse(ctx context.Context, result *database.ObjectQueryResult) (*v1.PaginatedList, error) { items := v1.PaginatedList{ Value: []any{}, // Initialize to empty list for testability } diff --git a/pkg/ucp/frontend/modules/types.go b/pkg/ucp/frontend/modules/types.go index 87abadc2c4..2c959df585 100644 --- a/pkg/ucp/frontend/modules/types.go +++ b/pkg/ucp/frontend/modules/types.go @@ -22,10 +22,10 @@ import ( "github.com/radius-project/radius/pkg/armrpc/asyncoperation/statusmanager" "github.com/radius-project/radius/pkg/sdk" - "github.com/radius-project/radius/pkg/ucp/dataprovider" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" "github.com/radius-project/radius/pkg/ucp/hostoptions" - queueprovider "github.com/radius-project/radius/pkg/ucp/queue/provider" - secretprovider "github.com/radius-project/radius/pkg/ucp/secret/provider" + "github.com/radius-project/radius/pkg/ucp/queue/queueprovider" + "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" "github.com/radius-project/radius/pkg/validator" ) @@ -60,8 +60,8 @@ type Options struct { // Location is the location of the server hosting UCP. Location string - // DataProvider is the data storage provider. - DataProvider *dataprovider.DataStorageProvider + // DatabaseProvider is the database provider. + DatabaseProvider *databaseprovider.DatabaseProvider // QeueueProvider provides access to the queue for async operations. QueueProvider *queueprovider.QueueProvider diff --git a/pkg/ucp/frontend/radius/routes.go b/pkg/ucp/frontend/radius/routes.go index cee401c79b..951a49af3a 100644 --- a/pkg/ucp/frontend/radius/routes.go +++ b/pkg/ucp/frontend/radius/routes.go @@ -64,16 +64,16 @@ func (m *Module) Initialize(ctx context.Context) (http.Handler, error) { return handler } - storageClient, err := m.options.DataProvider.GetClient(ctx) + databaseClient, err := m.options.DatabaseProvider.GetClient(ctx) if err != nil { return nil, err } ctrlOptions := controller.Options{ - Address: m.options.Address, - PathBase: m.options.PathBase, - StorageClient: storageClient, - StatusManager: m.options.StatusManager, + Address: m.options.Address, + PathBase: m.options.PathBase, + DatabaseClient: databaseClient, + StatusManager: m.options.StatusManager, } // NOTE: we're careful where we use the `apiValidator` middleware. It's not used for the proxy routes. @@ -380,6 +380,6 @@ func operationStatusGetHandler(ctx context.Context, ctrlOptions controller.Optio } func operationResultGetHandler(ctx context.Context, ctrlOptions controller.Options) (http.HandlerFunc, error) { - // NOTE: The resource type below is CORRECT. operation status and operation result use the same resource for storage. + // NOTE: The resource type below is CORRECT. operation status and operation result use the same resource type in the database. return server.CreateHandler(ctx, "System.Resources/operationstatuses", v1.OperationGet, ctrlOptions, defaultoperation.NewGetOperationResult) } diff --git a/pkg/ucp/frontend/radius/routes_test.go b/pkg/ucp/frontend/radius/routes_test.go index 6e26e16adf..ac6f6e8be5 100644 --- a/pkg/ucp/frontend/radius/routes_test.go +++ b/pkg/ucp/frontend/radius/routes_test.go @@ -25,12 +25,12 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" "github.com/radius-project/radius/pkg/armrpc/rpctest" "github.com/radius-project/radius/pkg/ucp/api/v20231001preview" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" "github.com/radius-project/radius/pkg/ucp/datamodel" - "github.com/radius-project/radius/pkg/ucp/dataprovider" "github.com/radius-project/radius/pkg/ucp/frontend/modules" "github.com/radius-project/radius/pkg/ucp/hostoptions" "github.com/radius-project/radius/pkg/ucp/secret" - secretprovider "github.com/radius-project/radius/pkg/ucp/secret/provider" + secretprovider "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" "go.uber.org/mock/gomock" ) @@ -185,18 +185,18 @@ func Test_Routes(t *testing.T) { } ctrl := gomock.NewController(t) - dataProvider := dataprovider.DataStorageProviderFromMemory() + databaseProvider := databaseprovider.FromMemory() secretClient := secret.NewMockClient(ctrl) secretProvider := secretprovider.NewSecretProvider(secretprovider.SecretProviderOptions{}) secretProvider.SetClient(secretClient) options := modules.Options{ - Address: "localhost", - PathBase: pathBase, - Config: &hostoptions.UCPConfig{}, - DataProvider: dataProvider, - SecretProvider: secretProvider, + Address: "localhost", + PathBase: pathBase, + Config: &hostoptions.UCPConfig{}, + DatabaseProvider: databaseProvider, + SecretProvider: secretProvider, } rpctest.AssertRouters(t, tests, pathBase, "", func(ctx context.Context) (chi.Router, error) { diff --git a/pkg/ucp/hostoptions/providerconfig.go b/pkg/ucp/hostoptions/providerconfig.go index 4b37e6a8cf..3f615a0c98 100644 --- a/pkg/ucp/hostoptions/providerconfig.go +++ b/pkg/ucp/hostoptions/providerconfig.go @@ -21,21 +21,21 @@ import ( profilerprovider "github.com/radius-project/radius/pkg/profiler/provider" "github.com/radius-project/radius/pkg/trace" "github.com/radius-project/radius/pkg/ucp/config" - "github.com/radius-project/radius/pkg/ucp/dataprovider" - qprovider "github.com/radius-project/radius/pkg/ucp/queue/provider" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" + "github.com/radius-project/radius/pkg/ucp/queue/queueprovider" "github.com/radius-project/radius/pkg/ucp/rest" - "github.com/radius-project/radius/pkg/ucp/secret/provider" + "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" "github.com/radius-project/radius/pkg/ucp/ucplog" ) // UCPConfig includes the resource provider configuration. type UCPConfig struct { - StorageProvider dataprovider.StorageProviderOptions `yaml:"storageProvider"` + DatabaseProvider databaseprovider.Options `yaml:"storageProvider"` Planes []rest.Plane `yaml:"planes"` - SecretProvider provider.SecretProviderOptions `yaml:"secretProvider"` + SecretProvider secretprovider.SecretProviderOptions `yaml:"secretProvider"` MetricsProvider metricsprovider.MetricsProviderOptions `yaml:"metricsProvider"` ProfilerProvider profilerprovider.ProfilerProviderOptions `yaml:"profilerProvider"` - QueueProvider qprovider.QueueProviderOptions `yaml:"queueProvider"` + QueueProvider queueprovider.QueueProviderOptions `yaml:"queueProvider"` TracerProvider trace.Options `yaml:"tracerProvider"` Logging ucplog.LoggingOptions `yaml:"logging"` Identity Identity `yaml:"identity,omitempty"` diff --git a/pkg/ucp/integrationtests/aws/awstest.go b/pkg/ucp/integrationtests/aws/awstest.go index 52aa311d44..6be034b1c5 100644 --- a/pkg/ucp/integrationtests/aws/awstest.go +++ b/pkg/ucp/integrationtests/aws/awstest.go @@ -22,11 +22,11 @@ import ( "testing" ucp_aws "github.com/radius-project/radius/pkg/ucp/aws" + "github.com/radius-project/radius/pkg/ucp/database" ucp_aws_frontend "github.com/radius-project/radius/pkg/ucp/frontend/aws" "github.com/radius-project/radius/pkg/ucp/frontend/modules" "github.com/radius-project/radius/pkg/ucp/integrationtests/testserver" "github.com/radius-project/radius/pkg/ucp/secret" - "github.com/radius-project/radius/pkg/ucp/store" "go.uber.org/mock/gomock" ) @@ -38,7 +38,7 @@ const ( testAWSRequestToken = "79B9F0DA-4882-4DC8-A367-6FD3BC122DED" // Random UUID ) -func initializeAWSTest(t *testing.T) (*testserver.TestServer, *store.MockStorageClient, *secret.MockClient, *ucp_aws.MockAWSCloudControlClient, *ucp_aws.MockAWSCloudFormationClient) { +func initializeAWSTest(t *testing.T) (*testserver.TestServer, *database.MockClient, *secret.MockClient, *ucp_aws.MockAWSCloudControlClient, *ucp_aws.MockAWSCloudFormationClient) { ctrl := gomock.NewController(t) cloudControlClient := ucp_aws.NewMockAWSCloudControlClient(ctrl) cloudFormationClient := ucp_aws.NewMockAWSCloudFormationClient(ctrl) @@ -50,5 +50,5 @@ func initializeAWSTest(t *testing.T) (*testserver.TestServer, *store.MockStorage return []modules.Initializer{module} }) - return ucp, ucp.Mocks.Storage, ucp.Mocks.Secrets, cloudControlClient, cloudFormationClient + return ucp, ucp.Mocks.Database, ucp.Mocks.Secrets, cloudControlClient, cloudFormationClient } diff --git a/pkg/ucp/integrationtests/radius/proxy_test.go b/pkg/ucp/integrationtests/radius/proxy_test.go index 0cd69ea5fc..4b96eb7229 100644 --- a/pkg/ucp/integrationtests/radius/proxy_test.go +++ b/pkg/ucp/integrationtests/radius/proxy_test.go @@ -176,7 +176,7 @@ func Test_RadiusPlane_ResourceAsync(t *testing.T) { return result, nil } - client, err := ucp.Clients.StorageProvider.GetClient(ctx) + client, err := ucp.Clients.DatabaseProvider.GetClient(ctx) require.NoError(t, err) err = client.Delete(ctx, testResourceID) require.NoError(t, err) diff --git a/pkg/ucp/integrationtests/testrp/async.go b/pkg/ucp/integrationtests/testrp/async.go index 61043b1092..1af3838fb5 100644 --- a/pkg/ucp/integrationtests/testrp/async.go +++ b/pkg/ucp/integrationtests/testrp/async.go @@ -33,7 +33,7 @@ import ( "github.com/radius-project/radius/pkg/armrpc/servicecontext" "github.com/radius-project/radius/pkg/middleware" "github.com/radius-project/radius/pkg/ucp/integrationtests/testserver" - queueprovider "github.com/radius-project/radius/pkg/ucp/queue/provider" + "github.com/radius-project/radius/pkg/ucp/queue/queueprovider" "github.com/radius-project/radius/test/testcontext" "github.com/stretchr/testify/require" ) @@ -59,8 +59,8 @@ func AsyncResource(t *testing.T, ts *testserver.TestServer, rootScope string, pu resourceType := "System.Test/testResources" - // We can share the storage provider with the test server. - storageClient, err := ts.Clients.StorageProvider.GetClient(ctx) + // We can share the database provider with the test server. + databaseClient, err := ts.Clients.DatabaseProvider.GetClient(ctx) require.NoError(t, err) // Do not share the queue. @@ -73,10 +73,10 @@ func AsyncResource(t *testing.T, ts *testserver.TestServer, rootScope string, pu queueClient, err := queueProvider.GetClient(ctx) require.NoError(t, err) - statusManager := statusmanager.New(storageClient, queueClient, v1.LocationGlobal) + statusManager := statusmanager.New(databaseClient, queueClient, v1.LocationGlobal) backendOpts := backend_ctrl.Options{ - StorageClient: storageClient, + DatabaseClient: databaseClient, } registry := worker.NewControllerRegistry() @@ -100,9 +100,9 @@ func AsyncResource(t *testing.T, ts *testserver.TestServer, rootScope string, pu }() frontendOpts := frontend_ctrl.Options{ - Address: "localhost:8080", - StorageClient: storageClient, - StatusManager: statusManager, + Address: "localhost:8080", + DatabaseClient: databaseClient, + StatusManager: statusManager, } err = server.ConfigureDefaultHandlers(ctx, r, rootScope, false, "System.Test", nil, frontendOpts) diff --git a/pkg/ucp/integrationtests/testrp/sync.go b/pkg/ucp/integrationtests/testrp/sync.go index f720a319ed..94b4d9af7b 100644 --- a/pkg/ucp/integrationtests/testrp/sync.go +++ b/pkg/ucp/integrationtests/testrp/sync.go @@ -30,7 +30,7 @@ import ( "github.com/radius-project/radius/pkg/armrpc/servicecontext" "github.com/radius-project/radius/pkg/middleware" "github.com/radius-project/radius/pkg/ucp/integrationtests/testserver" - queueprovider "github.com/radius-project/radius/pkg/ucp/queue/provider" + "github.com/radius-project/radius/pkg/ucp/queue/queueprovider" "github.com/radius-project/radius/test/testcontext" "github.com/stretchr/testify/require" ) @@ -43,8 +43,8 @@ func SyncResource(t *testing.T, ts *testserver.TestServer, rootScope string) fun r := chi.NewRouter() r.Use(servicecontext.ARMRequestCtx("", v1.LocationGlobal), middleware.LowercaseURLPath) - // We can share the storage provider with the test server. - storageClient, err := ts.Clients.StorageProvider.GetClient(ctx) + // We can share the database provider with the test server. + databaseClient, err := ts.Clients.DatabaseProvider.GetClient(ctx) require.NoError(t, err) // Do not share the queue. @@ -57,12 +57,12 @@ func SyncResource(t *testing.T, ts *testserver.TestServer, rootScope string) fun queueClient, err := queueProvider.GetClient(ctx) require.NoError(t, err) - statusManager := statusmanager.New(storageClient, queueClient, v1.LocationGlobal) + statusManager := statusmanager.New(databaseClient, queueClient, v1.LocationGlobal) ctrlOpts := frontend_ctrl.Options{ - Address: "localhost:8080", - StatusManager: statusManager, - StorageClient: storageClient, + Address: "localhost:8080", + StatusManager: statusManager, + DatabaseClient: databaseClient, } err = server.ConfigureDefaultHandlers(ctx, r, rootScope, false, "System.Test", nil, ctrlOpts) diff --git a/pkg/ucp/integrationtests/testserver/testserver.go b/pkg/ucp/integrationtests/testserver/testserver.go index 218181b40c..8643c3f839 100644 --- a/pkg/ucp/integrationtests/testserver/testserver.go +++ b/pkg/ucp/integrationtests/testserver/testserver.go @@ -48,17 +48,17 @@ import ( "github.com/radius-project/radius/pkg/sdk" "github.com/radius-project/radius/pkg/ucp/backend" "github.com/radius-project/radius/pkg/ucp/data" - "github.com/radius-project/radius/pkg/ucp/dataprovider" + "github.com/radius-project/radius/pkg/ucp/database" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" "github.com/radius-project/radius/pkg/ucp/frontend/api" "github.com/radius-project/radius/pkg/ucp/frontend/modules" "github.com/radius-project/radius/pkg/ucp/hosting" "github.com/radius-project/radius/pkg/ucp/hostoptions" queue "github.com/radius-project/radius/pkg/ucp/queue/client" - queueprovider "github.com/radius-project/radius/pkg/ucp/queue/provider" + "github.com/radius-project/radius/pkg/ucp/queue/queueprovider" "github.com/radius-project/radius/pkg/ucp/secret" - secretprovider "github.com/radius-project/radius/pkg/ucp/secret/provider" + "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" "github.com/radius-project/radius/pkg/ucp/server" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/validator" "github.com/radius-project/radius/swagger" "github.com/radius-project/radius/test/testcontext" @@ -104,8 +104,8 @@ type TestServerClients struct { // SecretProvider is the secret client provider. SecretProvider *secretprovider.SecretProvider - // StorageProvider is the storage client provider. - StorageProvider *dataprovider.DataStorageProvider + // DatabaseProvider is the database client provider. + DatabaseProvider *databaseprovider.DatabaseProvider } // TestServerMocks provides access to mock instances created by the TestServer. @@ -113,8 +113,8 @@ type TestServerMocks struct { // Secrets is the mock secret client. Secrets *secret.MockClient - // Storage is the mock storage client. - Storage *store.MockStorageClient + // Database is the mock database client. + Database *database.MockClient } // Client provides access to an http.Client that can be used to send requests. Most tests should use the functionality @@ -149,8 +149,8 @@ func StartWithMocks(t *testing.T, configureModules func(options modules.Options) pathBase := "/" + uuid.New().String() ctrl := gomock.NewController(t) - dataClient := store.NewMockStorageClient(ctrl) - dataProvider := dataprovider.DataStorageProviderFromClient(dataClient) + databaseClient := database.NewMockClient(ctrl) + databaseProvider := databaseprovider.FromClient(databaseClient) queueClient := queue.NewMockClient(ctrl) queueProvider := queueprovider.New(queueprovider.QueueProviderOptions{Name: "System.Resources"}) @@ -176,13 +176,13 @@ func StartWithMocks(t *testing.T, configureModules func(options modules.Options) require.NoError(t, err, "failed to load OpenAPI spec") options := modules.Options{ - Address: "localhost:9999", // Will be dynamically populated when server is started - PathBase: pathBase, - Config: &hostoptions.UCPConfig{}, - DataProvider: dataProvider, - SecretProvider: secretProvider, - SpecLoader: specLoader, - StatusManager: statusManager, + Address: "localhost:9999", // Will be dynamically populated when server is started + PathBase: pathBase, + Config: &hostoptions.UCPConfig{}, + DatabaseProvider: databaseProvider, + SecretProvider: secretProvider, + SpecLoader: specLoader, + StatusManager: statusManager, } if configureModules == nil { @@ -202,13 +202,13 @@ func StartWithMocks(t *testing.T, configureModules func(options modules.Options) ucp := &TestServer{ BaseURL: server.URL + pathBase, Clients: &TestServerClients{ - QueueProvider: queueProvider, - SecretProvider: secretProvider, - StorageProvider: dataProvider, + QueueProvider: queueProvider, + SecretProvider: secretProvider, + DatabaseProvider: databaseProvider, }, Mocks: &TestServerMocks{ - Secrets: secretClient, - Storage: dataClient, + Secrets: secretClient, + Database: databaseClient, }, Server: server, cancel: cancel, @@ -252,16 +252,16 @@ func StartWithETCD(t *testing.T, configureModules func(options modules.Options) } }() - storageOptions := dataprovider.StorageProviderOptions{ - Provider: dataprovider.TypeETCD, - ETCD: dataprovider.ETCDOptions{ + databaseOptions := databaseprovider.Options{ + Provider: databaseprovider.TypeETCD, + ETCD: databaseprovider.ETCDOptions{ InMemory: true, Client: config, }, } secretOptions := secretprovider.SecretProviderOptions{ Provider: secretprovider.TypeETCDSecret, - ETCD: storageOptions.ETCD, + ETCD: databaseOptions.ETCD, } queueOptions := queueprovider.QueueProviderOptions{ Name: server.UCPProviderName, @@ -271,7 +271,7 @@ func StartWithETCD(t *testing.T, configureModules func(options modules.Options) // Generate a random base path to ensure we're handling it correctly. pathBase := "/" + uuid.New().String() - dataProvider := dataprovider.DataStorageProviderFromOptions(storageOptions) + databaseProvider := databaseprovider.FromOptions(databaseOptions) secretProvider := secretprovider.NewSecretProvider(secretOptions) queueProvider := queueprovider.New(queueOptions) @@ -292,23 +292,23 @@ func StartWithETCD(t *testing.T, configureModules func(options modules.Options) connection, err := sdk.NewDirectConnection(address + pathBase) require.NoError(t, err) - storageClient, err := dataProvider.GetClient(ctx) + databaseClient, err := databaseProvider.GetClient(ctx) require.NoError(t, err) - statusManager := statusmanager.New(storageClient, queueClient, v1.LocationGlobal) + statusManager := statusmanager.New(databaseClient, queueClient, v1.LocationGlobal) specLoader, err := validator.LoadSpec(ctx, "ucp", swagger.SpecFilesUCP, []string{pathBase}, "") require.NoError(t, err, "failed to load OpenAPI spec") options := modules.Options{ - Address: address, - PathBase: pathBase, - Config: &hostoptions.UCPConfig{}, - DataProvider: dataProvider, - SecretProvider: secretProvider, - SpecLoader: specLoader, - QueueProvider: queueProvider, - StatusManager: statusManager, + Address: address, + PathBase: pathBase, + Config: &hostoptions.UCPConfig{}, + DatabaseProvider: databaseProvider, + SecretProvider: secretProvider, + SpecLoader: specLoader, + QueueProvider: queueProvider, + StatusManager: statusManager, } if configureModules == nil { @@ -327,7 +327,7 @@ func StartWithETCD(t *testing.T, configureModules func(options modules.Options) require.NoError(t, err) registry := worker.NewControllerRegistry() - err = backend.RegisterControllers(registry, connection, http.DefaultTransport, backend_ctrl.Options{StorageClient: storageClient}, defaultDownstream) + err = backend.RegisterControllers(registry, connection, http.DefaultTransport, backend_ctrl.Options{DatabaseClient: databaseClient}, defaultDownstream) require.NoError(t, err) w := worker.New(worker.Options{}, statusManager, queueClient, registry) @@ -356,9 +356,9 @@ func StartWithETCD(t *testing.T, configureModules func(options modules.Options) ucp := &TestServer{ BaseURL: server.URL + pathBase, Clients: &TestServerClients{ - QueueProvider: queueProvider, - SecretProvider: secretProvider, - StorageProvider: dataProvider, + QueueProvider: queueProvider, + SecretProvider: secretProvider, + DatabaseProvider: databaseProvider, }, Server: server, cancel: cancel, diff --git a/pkg/ucp/queue/apiserver/client.go b/pkg/ucp/queue/apiserver/client.go index 225e9eef93..c133d874e4 100644 --- a/pkg/ucp/queue/apiserver/client.go +++ b/pkg/ucp/queue/apiserver/client.go @@ -62,7 +62,7 @@ import ( "github.com/radius-project/radius/pkg/ucp/queue/client" - v1alpha1 "github.com/radius-project/radius/pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1" + v1alpha1 "github.com/radius-project/radius/pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/ucp/queue/apiserver/client_test.go b/pkg/ucp/queue/apiserver/client_test.go index 6b786ebb51..77c608199f 100644 --- a/pkg/ucp/queue/apiserver/client_test.go +++ b/pkg/ucp/queue/apiserver/client_test.go @@ -22,8 +22,8 @@ import ( "testing" "time" + v1alpha1 "github.com/radius-project/radius/pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1" "github.com/radius-project/radius/pkg/ucp/queue/client" - v1alpha1 "github.com/radius-project/radius/pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1" "github.com/radius-project/radius/test/testcontext" "github.com/radius-project/radius/test/ucp/kubeenv" sharedtest "github.com/radius-project/radius/test/ucp/queuetest" diff --git a/pkg/ucp/queue/provider/factory.go b/pkg/ucp/queue/queueprovider/factory.go similarity index 95% rename from pkg/ucp/queue/provider/factory.go rename to pkg/ucp/queue/queueprovider/factory.go index 3cc87958c4..c206cb7942 100644 --- a/pkg/ucp/queue/provider/factory.go +++ b/pkg/ucp/queue/queueprovider/factory.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package provider +package queueprovider import ( context "context" @@ -22,10 +22,10 @@ import ( "fmt" "github.com/radius-project/radius/pkg/kubeutil" + ucpv1alpha1 "github.com/radius-project/radius/pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1" "github.com/radius-project/radius/pkg/ucp/queue/apiserver" queue "github.com/radius-project/radius/pkg/ucp/queue/client" qinmem "github.com/radius-project/radius/pkg/ucp/queue/inmemory" - ucpv1alpha1 "github.com/radius-project/radius/pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/rest" runtimeclient "sigs.k8s.io/controller-runtime/pkg/client" diff --git a/pkg/ucp/queue/provider/options.go b/pkg/ucp/queue/queueprovider/options.go similarity index 92% rename from pkg/ucp/queue/provider/options.go rename to pkg/ucp/queue/queueprovider/options.go index 116313d03a..2b15e56090 100644 --- a/pkg/ucp/queue/provider/options.go +++ b/pkg/ucp/queue/queueprovider/options.go @@ -14,11 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -package provider +package queueprovider -// QueueProviderOptions represents the data storage provider options. +// QueueProviderOptions represents the queueprovider options. type QueueProviderOptions struct { - // Provider configures the storage provider. + // Provider configures the queue provider. Provider QueueProviderType `yaml:"provider"` // Name represents the unique name of queue. diff --git a/pkg/ucp/queue/provider/provider.go b/pkg/ucp/queue/queueprovider/provider.go similarity index 92% rename from pkg/ucp/queue/provider/provider.go rename to pkg/ucp/queue/queueprovider/provider.go index b22418800c..6b25ea1e4f 100644 --- a/pkg/ucp/queue/provider/provider.go +++ b/pkg/ucp/queue/queueprovider/provider.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package provider +package queueprovider import ( "context" @@ -25,7 +25,7 @@ import ( ) var ( - ErrUnsupportedStorageProvider = errors.New("unsupported queue provider") + ErrUnsupportedQueueProvider = errors.New("unsupported queue provider") ) // QueueProvider is the provider to create and manage queue client. @@ -50,7 +50,7 @@ func (p *QueueProvider) GetClient(ctx context.Context) (queue.Client, error) { return p.queueClient, nil } - err := ErrUnsupportedStorageProvider + err := ErrUnsupportedQueueProvider p.once.Do(func() { if fn, ok := clientFactory[p.options.Provider]; ok { p.queueClient, err = fn(ctx, p.options) diff --git a/pkg/ucp/queue/provider/provider_test.go b/pkg/ucp/queue/queueprovider/provider_test.go similarity index 94% rename from pkg/ucp/queue/provider/provider_test.go rename to pkg/ucp/queue/queueprovider/provider_test.go index 1a1bb49320..6b4c4a174e 100644 --- a/pkg/ucp/queue/provider/provider_test.go +++ b/pkg/ucp/queue/queueprovider/provider_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package provider +package queueprovider import ( "context" @@ -45,5 +45,5 @@ func TestGetClient_InvalidQueue(t *testing.T) { }) _, err := p.GetClient(context.TODO()) - require.ErrorIs(t, ErrUnsupportedStorageProvider, err) + require.ErrorIs(t, ErrUnsupportedQueueProvider, err) } diff --git a/pkg/ucp/queue/provider/types.go b/pkg/ucp/queue/queueprovider/types.go similarity index 97% rename from pkg/ucp/queue/provider/types.go rename to pkg/ucp/queue/queueprovider/types.go index ff69fb9b37..e3d18553ff 100644 --- a/pkg/ucp/queue/provider/types.go +++ b/pkg/ucp/queue/queueprovider/types.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package provider +package queueprovider // QueueProviderType represents types of queue provider. type QueueProviderType string diff --git a/pkg/ucp/secret/provider/factory.go b/pkg/ucp/secret/secretprovider/factory.go similarity index 91% rename from pkg/ucp/secret/provider/factory.go rename to pkg/ucp/secret/secretprovider/factory.go index 839fb7b9fa..219b355827 100644 --- a/pkg/ucp/secret/provider/factory.go +++ b/pkg/ucp/secret/secretprovider/factory.go @@ -14,19 +14,19 @@ See the License for the specific language governing permissions and limitations under the License. */ -package provider +package secretprovider import ( "context" "errors" "github.com/radius-project/radius/pkg/kubeutil" - "github.com/radius-project/radius/pkg/ucp/dataprovider" + "github.com/radius-project/radius/pkg/ucp/database/etcdstore" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" "github.com/radius-project/radius/pkg/ucp/secret" "github.com/radius-project/radius/pkg/ucp/secret/etcd" "github.com/radius-project/radius/pkg/ucp/secret/inmemory" kubernetes_client "github.com/radius-project/radius/pkg/ucp/secret/kubernetes" - "github.com/radius-project/radius/pkg/ucp/store/etcdstore" "k8s.io/kubectl/pkg/scheme" controller_runtime "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -42,7 +42,7 @@ var secretClientFactory = map[SecretProviderType]secretFactoryFunc{ func initETCDSecretClient(ctx context.Context, opts SecretProviderOptions) (secret.Client, error) { // etcd is a separate process run for development storage. // data provider already creates an etcd process which can be re-used instead of a new process for secret. - client, err := dataprovider.InitETCDClient(ctx, dataprovider.StorageProviderOptions{ + client, err := databaseprovider.InitETCDClient(ctx, databaseprovider.Options{ ETCD: opts.ETCD, }) if err != nil { diff --git a/pkg/ucp/secret/provider/options.go b/pkg/ucp/secret/secretprovider/options.go similarity index 86% rename from pkg/ucp/secret/provider/options.go rename to pkg/ucp/secret/secretprovider/options.go index 4d414aea25..b10fe006b8 100644 --- a/pkg/ucp/secret/provider/options.go +++ b/pkg/ucp/secret/secretprovider/options.go @@ -14,9 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -package provider +package secretprovider -import "github.com/radius-project/radius/pkg/ucp/dataprovider" +import "github.com/radius-project/radius/pkg/ucp/databaseprovider" // SecretProviderOptions contains provider information of the secret. type SecretProviderOptions struct { @@ -24,7 +24,7 @@ type SecretProviderOptions struct { Provider SecretProviderType `yaml:"provider"` // ETCD configures options for the etcd secret store. - ETCD dataprovider.ETCDOptions `yaml:"etcd,omitempty"` + ETCD databaseprovider.ETCDOptions `yaml:"etcd,omitempty"` // InMemory configures options for the in-memory secret store. InMemory struct{} `yaml:"inmemory,omitempty"` diff --git a/pkg/ucp/secret/provider/provider.go b/pkg/ucp/secret/secretprovider/provider.go similarity index 98% rename from pkg/ucp/secret/provider/provider.go rename to pkg/ucp/secret/secretprovider/provider.go index 8365851aef..feef4f47a3 100644 --- a/pkg/ucp/secret/provider/provider.go +++ b/pkg/ucp/secret/secretprovider/provider.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package provider +package secretprovider import ( "context" diff --git a/pkg/ucp/secret/provider/provider_test.go b/pkg/ucp/secret/secretprovider/provider_test.go similarity index 97% rename from pkg/ucp/secret/provider/provider_test.go rename to pkg/ucp/secret/secretprovider/provider_test.go index 05e3c52d33..2eb8c67597 100644 --- a/pkg/ucp/secret/provider/provider_test.go +++ b/pkg/ucp/secret/secretprovider/provider_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package provider +package secretprovider import ( "context" diff --git a/pkg/ucp/secret/provider/types.go b/pkg/ucp/secret/secretprovider/types.go similarity index 97% rename from pkg/ucp/secret/provider/types.go rename to pkg/ucp/secret/secretprovider/types.go index 72abadf5da..66a0c77ff6 100644 --- a/pkg/ucp/secret/provider/types.go +++ b/pkg/ucp/secret/secretprovider/types.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package provider +package secretprovider // SecretProviderType represents types of secret provider. type SecretProviderType string diff --git a/pkg/ucp/server/server.go b/pkg/ucp/server/server.go index 83a1e9cd8b..5759bc2959 100644 --- a/pkg/ucp/server/server.go +++ b/pkg/ucp/server/server.go @@ -34,13 +34,13 @@ import ( "github.com/radius-project/radius/pkg/ucp/backend" "github.com/radius-project/radius/pkg/ucp/config" "github.com/radius-project/radius/pkg/ucp/data" - "github.com/radius-project/radius/pkg/ucp/dataprovider" + "github.com/radius-project/radius/pkg/ucp/databaseprovider" "github.com/radius-project/radius/pkg/ucp/frontend/api" "github.com/radius-project/radius/pkg/ucp/hosting" "github.com/radius-project/radius/pkg/ucp/hostoptions" - qprovider "github.com/radius-project/radius/pkg/ucp/queue/provider" + "github.com/radius-project/radius/pkg/ucp/queue/queueprovider" "github.com/radius-project/radius/pkg/ucp/rest" - "github.com/radius-project/radius/pkg/ucp/secret/provider" + "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" "github.com/radius-project/radius/pkg/ucp/ucplog" kube_rest "k8s.io/client-go/rest" @@ -54,10 +54,10 @@ const ( type Options struct { Config *hostoptions.UCPConfig Port string - StorageProviderOptions dataprovider.StorageProviderOptions + DatabaseProviderOptions databaseprovider.Options LoggingOptions ucplog.LoggingOptions - SecretProviderOptions provider.SecretProviderOptions - QueueProviderOptions qprovider.QueueProviderOptions + SecretProviderOptions secretprovider.SecretProviderOptions + QueueProviderOptions queueprovider.QueueProviderOptions MetricsProviderOptions metricsprovider.MetricsProviderOptions ProfilerProviderOptions profilerprovider.ProfilerProviderOptions TracerProviderOptions trace.Options @@ -89,7 +89,7 @@ func NewServerOptionsFromEnvironment(configFilePath string) (Options, error) { return Options{}, err } - storeOpts := opts.Config.StorageProvider + storeOpts := opts.Config.DatabaseProvider planes := opts.Config.Planes secretOpts := opts.Config.SecretProvider qproviderOpts := opts.Config.QueueProvider @@ -131,7 +131,7 @@ func NewServerOptionsFromEnvironment(configFilePath string) (Options, error) { Port: port, TLSCertDir: tlsCertDir, PathBase: basePath, - StorageProviderOptions: storeOpts, + DatabaseProviderOptions: storeOpts, SecretProviderOptions: secretOpts, QueueProviderOptions: qproviderOpts, MetricsProviderOptions: metricsOpts, @@ -150,24 +150,24 @@ func NewServerOptionsFromEnvironment(configFilePath string) (Options, error) { func NewServer(options *Options) (*hosting.Host, error) { hostingServices := []hosting.Service{ api.NewService(api.ServiceOptions{ - ProviderName: UCPProviderName, - Address: ":" + options.Port, - PathBase: options.PathBase, - Config: options.Config, - Location: options.Location, - TLSCertDir: options.TLSCertDir, - StorageProviderOptions: options.StorageProviderOptions, - SecretProviderOptions: options.SecretProviderOptions, - QueueProviderOptions: options.QueueProviderOptions, - InitialPlanes: options.InitialPlanes, - Identity: options.Identity, - UCPConnection: options.UCPConnection, + ProviderName: UCPProviderName, + Address: ":" + options.Port, + PathBase: options.PathBase, + Config: options.Config, + Location: options.Location, + TLSCertDir: options.TLSCertDir, + DatabaseProviderOptions: options.DatabaseProviderOptions, + SecretProviderOptions: options.SecretProviderOptions, + QueueProviderOptions: options.QueueProviderOptions, + InitialPlanes: options.InitialPlanes, + Identity: options.Identity, + UCPConnection: options.UCPConnection, }), } - if options.StorageProviderOptions.Provider == dataprovider.TypeETCD && - options.StorageProviderOptions.ETCD.InMemory { - hostingServices = append(hostingServices, data.NewEmbeddedETCDService(data.EmbeddedETCDServiceOptions{ClientConfigSink: options.StorageProviderOptions.ETCD.Client})) + if options.DatabaseProviderOptions.Provider == databaseprovider.TypeETCD && + options.DatabaseProviderOptions.ETCD.InMemory { + hostingServices = append(hostingServices, data.NewEmbeddedETCDService(data.EmbeddedETCDServiceOptions{ClientConfigSink: options.DatabaseProviderOptions.ETCD.Client})) } options.MetricsProviderOptions.ServiceName = ServiceName @@ -191,7 +191,7 @@ func NewServer(options *Options) (*hosting.Host, error) { Env: hostopts.EnvironmentOptions{ RoleLocation: options.Config.Location, }, - StorageProvider: options.StorageProviderOptions, + DatabaseProvider: options.DatabaseProviderOptions, SecretProvider: options.SecretProviderOptions, QueueProvider: options.QueueProviderOptions, MetricsProvider: options.MetricsProviderOptions, diff --git a/pkg/ucp/store/mock_storageClient.go b/pkg/ucp/store/mock_storageClient.go deleted file mode 100644 index 8784a9848c..0000000000 --- a/pkg/ucp/store/mock_storageClient.go +++ /dev/null @@ -1,214 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/radius-project/radius/pkg/ucp/store (interfaces: StorageClient) -// -// Generated by this command: -// -// mockgen -typed -destination=./mock_storageClient.go -package=store -self_package github.com/radius-project/radius/pkg/ucp/store github.com/radius-project/radius/pkg/ucp/store StorageClient -// - -// Package store is a generated GoMock package. -package store - -import ( - context "context" - reflect "reflect" - - gomock "go.uber.org/mock/gomock" -) - -// MockStorageClient is a mock of StorageClient interface. -type MockStorageClient struct { - ctrl *gomock.Controller - recorder *MockStorageClientMockRecorder -} - -// MockStorageClientMockRecorder is the mock recorder for MockStorageClient. -type MockStorageClientMockRecorder struct { - mock *MockStorageClient -} - -// NewMockStorageClient creates a new mock instance. -func NewMockStorageClient(ctrl *gomock.Controller) *MockStorageClient { - mock := &MockStorageClient{ctrl: ctrl} - mock.recorder = &MockStorageClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockStorageClient) EXPECT() *MockStorageClientMockRecorder { - return m.recorder -} - -// Delete mocks base method. -func (m *MockStorageClient) Delete(arg0 context.Context, arg1 string, arg2 ...DeleteOptions) error { - m.ctrl.T.Helper() - varargs := []any{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Delete", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// Delete indicates an expected call of Delete. -func (mr *MockStorageClientMockRecorder) Delete(arg0, arg1 any, arg2 ...any) *MockStorageClientDeleteCall { - mr.mock.ctrl.T.Helper() - varargs := append([]any{arg0, arg1}, arg2...) - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockStorageClient)(nil).Delete), varargs...) - return &MockStorageClientDeleteCall{Call: call} -} - -// MockStorageClientDeleteCall wrap *gomock.Call -type MockStorageClientDeleteCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *MockStorageClientDeleteCall) Return(arg0 error) *MockStorageClientDeleteCall { - c.Call = c.Call.Return(arg0) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *MockStorageClientDeleteCall) Do(f func(context.Context, string, ...DeleteOptions) error) *MockStorageClientDeleteCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockStorageClientDeleteCall) DoAndReturn(f func(context.Context, string, ...DeleteOptions) error) *MockStorageClientDeleteCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// Get mocks base method. -func (m *MockStorageClient) Get(arg0 context.Context, arg1 string, arg2 ...GetOptions) (*Object, error) { - m.ctrl.T.Helper() - varargs := []any{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Get", varargs...) - ret0, _ := ret[0].(*Object) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Get indicates an expected call of Get. -func (mr *MockStorageClientMockRecorder) Get(arg0, arg1 any, arg2 ...any) *MockStorageClientGetCall { - mr.mock.ctrl.T.Helper() - varargs := append([]any{arg0, arg1}, arg2...) - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockStorageClient)(nil).Get), varargs...) - return &MockStorageClientGetCall{Call: call} -} - -// MockStorageClientGetCall wrap *gomock.Call -type MockStorageClientGetCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *MockStorageClientGetCall) Return(arg0 *Object, arg1 error) *MockStorageClientGetCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *MockStorageClientGetCall) Do(f func(context.Context, string, ...GetOptions) (*Object, error)) *MockStorageClientGetCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockStorageClientGetCall) DoAndReturn(f func(context.Context, string, ...GetOptions) (*Object, error)) *MockStorageClientGetCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// Query mocks base method. -func (m *MockStorageClient) Query(arg0 context.Context, arg1 Query, arg2 ...QueryOptions) (*ObjectQueryResult, error) { - m.ctrl.T.Helper() - varargs := []any{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Query", varargs...) - ret0, _ := ret[0].(*ObjectQueryResult) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Query indicates an expected call of Query. -func (mr *MockStorageClientMockRecorder) Query(arg0, arg1 any, arg2 ...any) *MockStorageClientQueryCall { - mr.mock.ctrl.T.Helper() - varargs := append([]any{arg0, arg1}, arg2...) - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockStorageClient)(nil).Query), varargs...) - return &MockStorageClientQueryCall{Call: call} -} - -// MockStorageClientQueryCall wrap *gomock.Call -type MockStorageClientQueryCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *MockStorageClientQueryCall) Return(arg0 *ObjectQueryResult, arg1 error) *MockStorageClientQueryCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *MockStorageClientQueryCall) Do(f func(context.Context, Query, ...QueryOptions) (*ObjectQueryResult, error)) *MockStorageClientQueryCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockStorageClientQueryCall) DoAndReturn(f func(context.Context, Query, ...QueryOptions) (*ObjectQueryResult, error)) *MockStorageClientQueryCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// Save mocks base method. -func (m *MockStorageClient) Save(arg0 context.Context, arg1 *Object, arg2 ...SaveOptions) error { - m.ctrl.T.Helper() - varargs := []any{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Save", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// Save indicates an expected call of Save. -func (mr *MockStorageClientMockRecorder) Save(arg0, arg1 any, arg2 ...any) *MockStorageClientSaveCall { - mr.mock.ctrl.T.Helper() - varargs := append([]any{arg0, arg1}, arg2...) - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Save", reflect.TypeOf((*MockStorageClient)(nil).Save), varargs...) - return &MockStorageClientSaveCall{Call: call} -} - -// MockStorageClientSaveCall wrap *gomock.Call -type MockStorageClientSaveCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *MockStorageClientSaveCall) Return(arg0 error) *MockStorageClientSaveCall { - c.Call = c.Call.Return(arg0) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *MockStorageClientSaveCall) Do(f func(context.Context, *Object, ...SaveOptions) error) *MockStorageClientSaveCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockStorageClientSaveCall) DoAndReturn(f func(context.Context, *Object, ...SaveOptions) error) *MockStorageClientSaveCall { - c.Call = c.Call.DoAndReturn(f) - return c -} diff --git a/pkg/ucp/trackedresource/update.go b/pkg/ucp/trackedresource/update.go index 49f9de3c8c..813d4273ed 100644 --- a/pkg/ucp/trackedresource/update.go +++ b/pkg/ucp/trackedresource/update.go @@ -29,9 +29,9 @@ import ( "github.com/go-logr/logr" v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/ucplog" ) @@ -42,9 +42,9 @@ const ( ) // NewUpdater creates a new Updater. -func NewUpdater(storeClient store.StorageClient, httpClient *http.Client) *Updater { +func NewUpdater(databaseClient database.Client, httpClient *http.Client) *Updater { return &Updater{ - Store: storeClient, + DatabaseClient: databaseClient, Client: httpClient, AttemptCount: retryCount, RetryDelay: retryDelay, @@ -54,8 +54,8 @@ func NewUpdater(storeClient store.StorageClient, httpClient *http.Client) *Updat // Updater is a utility struct that can perform updates on tracked resources. type Updater struct { - // Store is the storage client used to access the database. - Store store.StorageClient + // DatabaseClient is the database client used to access the database. + DatabaseClient database.Client // Client is the HTTP client used to make requests to the downstream API. Client *http.Client @@ -153,8 +153,8 @@ func (u *Updater) Update(ctx context.Context, downstream string, id resources.ID func (u *Updater) run(ctx context.Context, id resources.ID, trackingID resources.ID, destination *url.URL, apiVersion string) error { logger := ucplog.FromContextOrDiscard(ctx) - obj, err := u.Store.Get(ctx, trackingID.String()) - if errors.Is(err, &store.ErrNotFound{}) { + obj, err := u.DatabaseClient.Get(ctx, trackingID.String()) + if errors.Is(err, &database.ErrNotFound{}) { // This is fine. It might be a new resource. } else if err != nil { return err @@ -179,8 +179,8 @@ func (u *Updater) run(ctx context.Context, id resources.ID, trackingID resources if data == nil { // Resource was not found. We can delete the tracked resource entry. logger.V(ucplog.LevelDebug).Info("deleting tracked resource entry") - err = u.Store.Delete(ctx, trackingID.String(), store.WithETag(etag)) - if errors.Is(err, &store.ErrNotFound{}) { + err = u.DatabaseClient.Delete(ctx, trackingID.String(), database.WithETag(etag)) + if errors.Is(err, &database.ErrNotFound{}) { return nil } else if err != nil { return err @@ -201,15 +201,15 @@ func (u *Updater) run(ctx context.Context, id resources.ID, trackingID resources entry.AsyncProvisioningState = *data.Properties.ProvisioningState } - obj = &store.Object{ - Metadata: store.Metadata{ + obj = &database.Object{ + Metadata: database.Metadata{ ID: trackingID.String(), }, Data: entry, } logger.V(ucplog.LevelDebug).Info("updating tracked resource entry") - err = u.Store.Save(ctx, obj, store.WithETag(etag)) - if errors.Is(err, &store.ErrConcurrency{}) { + err = u.DatabaseClient.Save(ctx, obj, database.WithETag(etag)) + if errors.Is(err, &database.ErrConcurrency{}) { logger.V(ucplog.LevelDebug).Info("tracked resource was updated concurrently") return &InProgressErr{} } else if err != nil { diff --git a/pkg/ucp/trackedresource/update_test.go b/pkg/ucp/trackedresource/update_test.go index 98d3ba173b..2a2c475cc9 100644 --- a/pkg/ucp/trackedresource/update_test.go +++ b/pkg/ucp/trackedresource/update_test.go @@ -28,8 +28,8 @@ import ( v1 "github.com/radius-project/radius/pkg/armrpc/api/v1" "github.com/radius-project/radius/pkg/to" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/datamodel" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/test/testcontext" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -45,12 +45,12 @@ var ( }() ) -func setupUpdater(t *testing.T) (*Updater, *store.MockStorageClient, *mockRoundTripper) { +func setupUpdater(t *testing.T) (*Updater, *database.MockClient, *mockRoundTripper) { ctrl := gomock.NewController(t) - storeClient := store.NewMockStorageClient(ctrl) + databaseClient := database.NewMockClient(ctrl) roundTripper := &mockRoundTripper{} - updater := NewUpdater(storeClient, &http.Client{Transport: roundTripper}) + updater := NewUpdater(databaseClient, &http.Client{Transport: roundTripper}) // Optimize these values for testability. We don't want to wait for retries or timeouts unless // the test is specifically testing that behavior. @@ -58,12 +58,12 @@ func setupUpdater(t *testing.T) (*Updater, *store.MockStorageClient, *mockRoundT updater.AttemptCount = 1 updater.RequestTimeout = time.Microsecond * 100 - return updater, storeClient, roundTripper + return updater, databaseClient, roundTripper } func Test_Update(t *testing.T) { t.Run("successful update", func(t *testing.T) { - updater, storeClient, roundTripper := setupUpdater(t) + updater, databaseClient, roundTripper := setupUpdater(t) apiVersion := "1234" resource := map[string]any{ @@ -73,17 +73,17 @@ func Test_Update(t *testing.T) { "properties": map[string]any{}, } - storeClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), IDFor(testID).String()). - Return(nil, &store.ErrNotFound{}). + Return(nil, &database.ErrNotFound{}). Times(1) // Mock a successful (terminal) response from the downstream API. roundTripper.RespondWithJSON(t, http.StatusOK, resource) - storeClient.EXPECT(). + databaseClient.EXPECT(). Save(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, obj *store.Object, options ...store.SaveOptions) error { + DoAndReturn(func(ctx context.Context, obj *database.Object, options ...database.SaveOptions) error { require.Equal(t, IDFor(testID).String(), obj.ID) dm := obj.Data.(*datamodel.GenericResource) @@ -99,7 +99,7 @@ func Test_Update(t *testing.T) { }) t.Run("retry then success", func(t *testing.T) { - updater, storeClient, roundTripper := setupUpdater(t) + updater, databaseClient, roundTripper := setupUpdater(t) updater.AttemptCount = 2 apiVersion := "1234" @@ -111,21 +111,21 @@ func Test_Update(t *testing.T) { } // Fail once, then succeed. - storeClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), IDFor(testID).String()). Return(nil, errors.New("this will be retried")). Times(1) - storeClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), IDFor(testID).String()). - Return(nil, &store.ErrNotFound{}). + Return(nil, &database.ErrNotFound{}). Times(1) // Mock a successful (terminal) response from the downstream API. roundTripper.RespondWithJSON(t, http.StatusOK, resource) - storeClient.EXPECT(). + databaseClient.EXPECT(). Save(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, obj *store.Object, options ...store.SaveOptions) error { + DoAndReturn(func(ctx context.Context, obj *database.Object, options ...database.SaveOptions) error { require.Equal(t, IDFor(testID).String(), obj.ID) dm := obj.Data.(*datamodel.GenericResource) @@ -141,7 +141,7 @@ func Test_Update(t *testing.T) { }) t.Run("resource still provisioning", func(t *testing.T) { - updater, storeClient, roundTripper := setupUpdater(t) + updater, databaseClient, roundTripper := setupUpdater(t) apiVersion := "1234" resource := map[string]any{ @@ -153,9 +153,9 @@ func Test_Update(t *testing.T) { }, } - storeClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), IDFor(testID).String()). - Return(nil, &store.ErrNotFound{}). + Return(nil, &database.ErrNotFound{}). Times(1) // Mock a successful (non-terminal) response from the downstream API. @@ -167,7 +167,7 @@ func Test_Update(t *testing.T) { }) t.Run("tracked resource updated concurrently", func(t *testing.T) { - updater, storeClient, roundTripper := setupUpdater(t) + updater, databaseClient, roundTripper := setupUpdater(t) apiVersion := "1234" resource := map[string]any{ @@ -176,15 +176,15 @@ func Test_Update(t *testing.T) { "type": testID.Type(), } - storeClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), IDFor(testID).String()). - Return(nil, &store.ErrNotFound{}). + Return(nil, &database.ErrNotFound{}). Times(1) // Fail the "Save" operation due to a concurrent update. - storeClient.EXPECT(). + databaseClient.EXPECT(). Save(gomock.Any(), gomock.Any(), gomock.Any()). - Return(&store.ErrConcurrency{}). + Return(&database.ErrConcurrency{}). Times(1) // Mock a successful (non-terminal) response from the downstream API. @@ -196,13 +196,13 @@ func Test_Update(t *testing.T) { }) t.Run("retries exhausted", func(t *testing.T) { - updater, storeClient, _ := setupUpdater(t) + updater, databaseClient, _ := setupUpdater(t) updater.AttemptCount = 3 apiVersion := "1234" // Fail enough times to exhaust our retries. - storeClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), IDFor(testID).String()). Return(nil, errors.New("this will be retried")). Times(3) @@ -217,7 +217,7 @@ func Test_run(t *testing.T) { apiVersion := "1234" t.Run("successful update (new resource)", func(t *testing.T) { - updater, storeClient, roundTripper := setupUpdater(t) + updater, databaseClient, roundTripper := setupUpdater(t) resource := map[string]any{ "id": testID.String(), @@ -226,17 +226,17 @@ func Test_run(t *testing.T) { "properties": map[string]any{}, } - storeClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), IDFor(testID).String()). - Return(nil, &store.ErrNotFound{}). + Return(nil, &database.ErrNotFound{}). Times(1) // Mock a successful (terminal) response from the downstream API. roundTripper.RespondWithJSON(t, http.StatusOK, resource) - storeClient.EXPECT(). + databaseClient.EXPECT(). Save(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, obj *store.Object, options ...store.SaveOptions) error { + DoAndReturn(func(ctx context.Context, obj *database.Object, options ...database.SaveOptions) error { require.Equal(t, IDFor(testID).String(), obj.ID) dm := obj.Data.(*datamodel.GenericResource) @@ -252,7 +252,7 @@ func Test_run(t *testing.T) { }) t.Run("successful update (existing resource)", func(t *testing.T) { - updater, storeClient, roundTripper := setupUpdater(t) + updater, databaseClient, roundTripper := setupUpdater(t) resource := map[string]any{ "id": testID.String(), @@ -265,17 +265,17 @@ func Test_run(t *testing.T) { dm := datamodel.GenericResourceFromID(testID, IDFor(testID)) dm.Properties.APIVersion = apiVersion - storeClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), IDFor(testID).String()). - Return(&store.Object{Metadata: store.Metadata{ETag: etag}, Data: dm}, nil). + Return(&database.Object{Metadata: database.Metadata{ETag: etag}, Data: dm}, nil). Times(1) // Mock a successful (terminal) response from the downstream API. roundTripper.RespondWithJSON(t, http.StatusOK, resource) - storeClient.EXPECT(). + databaseClient.EXPECT(). Save(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, obj *store.Object, options ...store.SaveOptions) error { + DoAndReturn(func(ctx context.Context, obj *database.Object, options ...database.SaveOptions) error { require.Equal(t, IDFor(testID).String(), obj.ID) dm := obj.Data.(*datamodel.GenericResource) @@ -291,21 +291,21 @@ func Test_run(t *testing.T) { }) t.Run("successful delete", func(t *testing.T) { - updater, storeClient, roundTripper := setupUpdater(t) + updater, databaseClient, roundTripper := setupUpdater(t) etag := "some-etag" dm := datamodel.GenericResourceFromID(testID, IDFor(testID)) dm.Properties.APIVersion = apiVersion - storeClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), IDFor(testID).String()). - Return(&store.Object{Metadata: store.Metadata{ETag: etag}, Data: dm}, nil). + Return(&database.Object{Metadata: database.Metadata{ETag: etag}, Data: dm}, nil). Times(1) // Mock a successful (terminal) response from the downstream API. roundTripper.RespondWithJSON(t, http.StatusNotFound, &v1.ErrorResponse{Error: v1.ErrorDetails{Code: v1.CodeNotFound}}) - storeClient.EXPECT(). + databaseClient.EXPECT(). Delete(gomock.Any(), IDFor(testID).String(), gomock.Any()). Return(nil). Times(1) @@ -315,7 +315,7 @@ func Test_run(t *testing.T) { }) t.Run("resource still provisioning", func(t *testing.T) { - updater, storeClient, roundTripper := setupUpdater(t) + updater, databaseClient, roundTripper := setupUpdater(t) resource := map[string]any{ "id": testID.String(), @@ -326,9 +326,9 @@ func Test_run(t *testing.T) { }, } - storeClient.EXPECT(). + databaseClient.EXPECT(). Get(gomock.Any(), IDFor(testID).String()). - Return(nil, &store.ErrNotFound{}). + Return(nil, &database.ErrNotFound{}). Times(1) // Mock a successful (terminal) response from the downstream API. diff --git a/test/ucp/kubeenv/testenv.go b/test/ucp/kubeenv/testenv.go index a800c309c9..2c78248704 100644 --- a/test/ucp/kubeenv/testenv.go +++ b/test/ucp/kubeenv/testenv.go @@ -23,7 +23,7 @@ import ( "os" "os/exec" - ucpv1alpha1 "github.com/radius-project/radius/pkg/ucp/store/apiserverstore/api/ucp.dev/v1alpha1" + ucpv1alpha1 "github.com/radius-project/radius/pkg/ucp/database/apiserverstore/api/ucp.dev/v1alpha1" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/test/ucp/storetest/shared.go b/test/ucp/storetest/shared.go index 6dcd7da34c..0ab6e761bb 100644 --- a/test/ucp/storetest/shared.go +++ b/test/ucp/storetest/shared.go @@ -21,8 +21,8 @@ import ( "encoding/json" "testing" + "github.com/radius-project/radius/pkg/ucp/database" "github.com/radius-project/radius/pkg/ucp/resources" - "github.com/radius-project/radius/pkg/ucp/store" "github.com/radius-project/radius/pkg/ucp/util/etag" "github.com/radius-project/radius/test/testcontext" "github.com/stretchr/testify/require" @@ -143,16 +143,16 @@ func parseOrPanic(id string) resources.ID { return parsed } -func createObject(id resources.ID, data any) store.Object { - return store.Object{ - Metadata: store.Metadata{ +func createObject(id resources.ID, data any) database.Object { + return database.Object{ + Metadata: database.Metadata{ ID: id.String(), }, Data: data, } } -func compareObjects(t *testing.T, expected *store.Object, actual *store.Object) { +func compareObjects(t *testing.T, expected *database.Object, actual *database.Object) { t.Helper() // Compare everything except ETags @@ -166,13 +166,13 @@ func compareObjects(t *testing.T, expected *store.Object, actual *store.Object) } // CompareObjectLists compares two slices of store.Objects, ignoring their ETags. -func CompareObjectLists(t *testing.T, expected []store.Object, actual []store.Object) { +func CompareObjectLists(t *testing.T, expected []database.Object, actual []database.Object) { t.Helper() - expectedCopy := []store.Object{} + expectedCopy := []database.Object{} expectedCopy = append(expectedCopy, expected...) - actualCopy := []store.Object{} + actualCopy := []database.Object{} actualCopy = append(actualCopy, actual...) // Compare everything except ETags @@ -187,10 +187,10 @@ func CompareObjectLists(t *testing.T, expected []store.Object, actual []store.Ob require.ElementsMatch(t, expectedCopy, actualCopy) } -// This function tests the StorageClient's Get, Save and Delete methods by creating, updating and deleting objects with +// This function tests the database Client's Get, Save and Delete methods by creating, updating and deleting objects with // different IDs and scopes, and checks the results of various query scenarios with different filters and scopes. It also // checks that the expected objects are returned. -func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) { +func RunTest(t *testing.T, client database.Client, clear func(t *testing.T)) { ctx, cancel := testcontext.NewWithCancel(t) t.Cleanup(cancel) @@ -198,7 +198,7 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) clear(t) obj, err := client.Get(ctx, Resource1ID.String()) - require.ErrorIs(t, err, &store.ErrNotFound{ID: Resource1ID.String()}) + require.ErrorIs(t, err, &database.ErrNotFound{ID: Resource1ID.String()}) require.Nil(t, obj) }) @@ -206,7 +206,7 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) clear(t) err := client.Delete(ctx, Resource1ID.String()) - require.ErrorIs(t, err, &store.ErrNotFound{ID: Resource1ID.String()}) + require.ErrorIs(t, err, &database.ErrNotFound{ID: Resource1ID.String()}) }) t.Run("save_and_get_arm", func(t *testing.T) { @@ -275,7 +275,7 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) require.NotEmpty(t, obj1.ETag) obj1.Data = Data2 - err = client.Save(ctx, &obj1, store.WithETag(obj1.ETag)) + err = client.Save(ctx, &obj1, database.WithETag(obj1.ETag)) require.NoError(t, err) obj1Get, err := client.Get(ctx, Resource1ID.String()) @@ -291,8 +291,8 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) require.NoError(t, err) obj1.Data = Data2 - err = client.Save(ctx, &obj1, store.WithETag(etag.New(MarshalOrPanic(Data2)))) - require.ErrorIs(t, err, &store.ErrConcurrency{}) + err = client.Save(ctx, &obj1, database.WithETag(etag.New(MarshalOrPanic(Data2)))) + require.ErrorIs(t, err, &database.ErrConcurrency{}) obj1.Data = Data1 obj1Get, err := client.Get(ctx, Resource1ID.String()) @@ -305,11 +305,11 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) obj1 := createObject(Resource1ID, Data1) - err := client.Save(ctx, &obj1, store.WithETag(etag.New(MarshalOrPanic(Data1)))) - require.ErrorIs(t, err, &store.ErrConcurrency{}) + err := client.Save(ctx, &obj1, database.WithETag(etag.New(MarshalOrPanic(Data1)))) + require.ErrorIs(t, err, &database.ErrConcurrency{}) obj1Get, err := client.Get(ctx, Resource1ID.String()) - require.ErrorIs(t, err, &store.ErrNotFound{ID: Resource1ID.String()}) + require.ErrorIs(t, err, &database.ErrNotFound{ID: Resource1ID.String()}) require.Nil(t, obj1Get) }) @@ -336,7 +336,7 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) require.NoError(t, err) obj1Get, err := client.Get(ctx, Resource1ID.String()) - require.ErrorIs(t, err, &store.ErrNotFound{ID: Resource1ID.String()}) + require.ErrorIs(t, err, &database.ErrNotFound{ID: Resource1ID.String()}) require.Nil(t, obj1Get) }) @@ -347,11 +347,11 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) err := client.Save(ctx, &obj1) require.NoError(t, err) - err = client.Delete(ctx, Resource1ID.String(), store.WithETag(obj1.ETag)) + err = client.Delete(ctx, Resource1ID.String(), database.WithETag(obj1.ETag)) require.NoError(t, err) obj1Get, err := client.Get(ctx, Resource1ID.String()) - require.ErrorIs(t, err, &store.ErrNotFound{ID: Resource1ID.String()}) + require.ErrorIs(t, err, &database.ErrNotFound{ID: Resource1ID.String()}) require.Nil(t, obj1Get) }) @@ -362,8 +362,8 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) err := client.Save(ctx, &obj1) require.NoError(t, err) - err = client.Delete(ctx, Resource1ID.String(), store.WithETag(etag.New(MarshalOrPanic(Data2)))) - require.ErrorIs(t, err, &store.ErrConcurrency{}) + err = client.Delete(ctx, Resource1ID.String(), database.WithETag(etag.New(MarshalOrPanic(Data2)))) + require.ErrorIs(t, err, &database.ErrConcurrency{}) obj1Get, err := client.Get(ctx, Resource1ID.String()) require.NoError(t, err) @@ -373,14 +373,14 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) t.Run("delete_cannot_delete_missing_resource_with_not_matching_etag", func(t *testing.T) { clear(t) - err := client.Delete(ctx, Resource1ID.String(), store.WithETag(etag.New(MarshalOrPanic(Data1)))) - require.ErrorIs(t, err, &store.ErrConcurrency{}) + err := client.Delete(ctx, Resource1ID.String(), database.WithETag(etag.New(MarshalOrPanic(Data1)))) + require.ErrorIs(t, err, &database.ErrConcurrency{}) }) t.Run("list_can_be_empty", func(t *testing.T) { clear(t) - objs, err := client.Query(ctx, store.Query{RootScope: RadiusScope, ResourceType: "asdf"}) + objs, err := client.Query(ctx, database.Query{RootScope: RadiusScope, ResourceType: "asdf"}) require.NoError(t, err) require.Empty(t, objs) }) @@ -425,9 +425,9 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) require.NoError(t, err) t.Run("query_resources_at_resource_group_scope", func(t *testing.T) { - objs, err := client.Query(ctx, store.Query{RootScope: ResourceGroup1Scope, ResourceType: NestedResourceType1}) + objs, err := client.Query(ctx, database.Query{RootScope: ResourceGroup1Scope, ResourceType: NestedResourceType1}) require.NoError(t, err) - expected := []store.Object{ + expected := []database.Object{ nested1, nested2, nested3, @@ -437,19 +437,19 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) }) t.Run("query_resources_at_resource_group_scope_with_field_filter", func(t *testing.T) { - filters := []store.QueryFilter{{Field: "value", Value: "n1"}} - objs, err := client.Query(ctx, store.Query{RootScope: ResourceGroup1Scope, ResourceType: NestedResourceType1, Filters: filters}) + filters := []database.QueryFilter{{Field: "value", Value: "n1"}} + objs, err := client.Query(ctx, database.Query{RootScope: ResourceGroup1Scope, ResourceType: NestedResourceType1, Filters: filters}) require.NoError(t, err) - expected := []store.Object{ + expected := []database.Object{ nested1, } CompareObjectLists(t, expected, objs.Items) }) t.Run("query_resources_at_resource_group_scope_with_prefix", func(t *testing.T) { - objs, err := client.Query(ctx, store.Query{RootScope: ResourceGroup1Scope, ResourceType: NestedResourceType1, RoutingScopePrefix: ResourcePath1}) + objs, err := client.Query(ctx, database.Query{RootScope: ResourceGroup1Scope, ResourceType: NestedResourceType1, RoutingScopePrefix: ResourcePath1}) require.NoError(t, err) - expected := []store.Object{ + expected := []database.Object{ nested1, nested2, } @@ -457,22 +457,22 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) }) t.Run("query_scopes_at_resource_group_scope", func(t *testing.T) { - objs, err := client.Query(ctx, store.Query{RootScope: ResourceGroup1Scope, IsScopeQuery: true, ResourceType: "resourceGroups"}) + objs, err := client.Query(ctx, database.Query{RootScope: ResourceGroup1Scope, IsScopeQuery: true, ResourceType: "resourceGroups"}) require.NoError(t, err) - expected := []store.Object{} + expected := []database.Object{} CompareObjectLists(t, expected, objs.Items) }) t.Run("query_resources_at_plane_scope", func(t *testing.T) { - objs, err := client.Query(ctx, store.Query{RootScope: RadiusScope, ResourceType: ResourceType1}) + objs, err := client.Query(ctx, database.Query{RootScope: RadiusScope, ResourceType: ResourceType1}) require.NoError(t, err) require.Empty(t, objs) }) t.Run("query_resources_at_plane_scope_recursive", func(t *testing.T) { - objs, err := client.Query(ctx, store.Query{RootScope: RadiusScope, ScopeRecursive: true, ResourceType: NestedResourceType1}) + objs, err := client.Query(ctx, database.Query{RootScope: RadiusScope, ScopeRecursive: true, ResourceType: NestedResourceType1}) require.NoError(t, err) - expected := []store.Object{ + expected := []database.Object{ nested1, nested2, nested3, @@ -482,19 +482,19 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) }) t.Run("query_resources_at_plane_scope_recursive_with_field_filter", func(t *testing.T) { - filters := []store.QueryFilter{{Field: "value", Value: "1"}} - objs, err := client.Query(ctx, store.Query{RootScope: RadiusScope, ScopeRecursive: true, ResourceType: ResourceType1, Filters: filters}) + filters := []database.QueryFilter{{Field: "value", Value: "1"}} + objs, err := client.Query(ctx, database.Query{RootScope: RadiusScope, ScopeRecursive: true, ResourceType: ResourceType1, Filters: filters}) require.NoError(t, err) - expected := []store.Object{ + expected := []database.Object{ obj1, } CompareObjectLists(t, expected, objs.Items) }) t.Run("query_resources_at_plane_scope_recursive_with_prefix", func(t *testing.T) { - objs, err := client.Query(ctx, store.Query{RootScope: RadiusScope, ScopeRecursive: true, ResourceType: NestedResourceType1, RoutingScopePrefix: ResourcePath1}) + objs, err := client.Query(ctx, database.Query{RootScope: RadiusScope, ScopeRecursive: true, ResourceType: NestedResourceType1, RoutingScopePrefix: ResourcePath1}) require.NoError(t, err) - expected := []store.Object{ + expected := []database.Object{ nested1, nested2, } @@ -502,18 +502,18 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) }) t.Run("query_scopes_at_plane_scope", func(t *testing.T) { - objs, err := client.Query(ctx, store.Query{RootScope: PlaneScope, IsScopeQuery: true, ResourceType: "radius"}) + objs, err := client.Query(ctx, database.Query{RootScope: PlaneScope, IsScopeQuery: true, ResourceType: "radius"}) require.NoError(t, err) - expected := []store.Object{ + expected := []database.Object{ plane1, } CompareObjectLists(t, expected, objs.Items) }) t.Run("query_scopes_at_plane_scope_recursive", func(t *testing.T) { - objs, err := client.Query(ctx, store.Query{RootScope: RadiusScope, ScopeRecursive: true, IsScopeQuery: true, ResourceType: "resourcegroups"}) + objs, err := client.Query(ctx, database.Query{RootScope: RadiusScope, ScopeRecursive: true, IsScopeQuery: true, ResourceType: "resourcegroups"}) require.NoError(t, err) - expected := []store.Object{ + expected := []database.Object{ group1, group2, } @@ -521,18 +521,18 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) }) t.Run("query_scopes_with_filter_non_matching", func(t *testing.T) { - objs, err := client.Query(ctx, store.Query{RootScope: RadiusScope, IsScopeQuery: true, ResourceType: "resourcegroups", Filters: []store.QueryFilter{ + objs, err := client.Query(ctx, database.Query{RootScope: RadiusScope, IsScopeQuery: true, ResourceType: "resourcegroups", Filters: []database.QueryFilter{ {Field: "value", Value: "asdf"}, }}) require.NoError(t, err) - expected := []store.Object{} + expected := []database.Object{} CompareObjectLists(t, expected, objs.Items) }) t.Run("query_scopes_at_plane_scope_recursive", func(t *testing.T) { - objs, err := client.Query(ctx, store.Query{RootScope: RadiusScope, ScopeRecursive: true, IsScopeQuery: true, ResourceType: "resourcegroups"}) + objs, err := client.Query(ctx, database.Query{RootScope: RadiusScope, ScopeRecursive: true, IsScopeQuery: true, ResourceType: "resourcegroups"}) require.NoError(t, err) - expected := []store.Object{ + expected := []database.Object{ group1, group2, } @@ -540,10 +540,10 @@ func RunTest(t *testing.T, client store.StorageClient, clear func(t *testing.T)) }) t.Run("query_scopes_at_plane_scope_recursive_with_field_filter", func(t *testing.T) { - filters := []store.QueryFilter{{Field: "value", Value: "1"}} - objs, err := client.Query(ctx, store.Query{RootScope: RadiusScope, ScopeRecursive: true, IsScopeQuery: true, Filters: filters, ResourceType: "resourcegroups"}) + filters := []database.QueryFilter{{Field: "value", Value: "1"}} + objs, err := client.Query(ctx, database.Query{RootScope: RadiusScope, ScopeRecursive: true, IsScopeQuery: true, Filters: filters, ResourceType: "resourcegroups"}) require.NoError(t, err) - expected := []store.Object{ + expected := []database.Object{ group1, } CompareObjectLists(t, expected, objs.Items)