diff --git a/domain/application/errors/errors.go b/domain/application/errors/errors.go index 927585aed680..280cd97fd3ff 100644 --- a/domain/application/errors/errors.go +++ b/domain/application/errors/errors.go @@ -132,22 +132,6 @@ const ( // is found, an error is returned. MultipleCharmHashes = errors.ConstError("multiple charm hashes found") - // ResourceNotFound describes an error that occurs when a resource is - // not found. - ResourceNotFound = errors.ConstError("resource not found") - - // UnknownResourceType describes an error where the resource type is - // not oci-image or file. - UnknownResourceType = errors.ConstError("unknown resource type") - - // UnknownRetrievedByType describes an error where the retrieved by type is - // neither user, unit nor application. - UnknownRetrievedByType = errors.ConstError("unknown retrieved by type") - - // ResourceNameNotValid describes an error where the resource name is not - // valid, usually because it's empty. - ResourceNameNotValid = errors.ConstError("resource name not valid") - // AlreadyDownloadingCharm describes an error that occurs when a charm is // already being downloaded. AlreadyDownloadingCharm = errors.ConstError("already downloading charm") diff --git a/domain/application/service/application_test.go b/domain/application/service/application_test.go index d00fcaa526a1..1ab533c93474 100644 --- a/domain/application/service/application_test.go +++ b/domain/application/service/application_test.go @@ -35,7 +35,6 @@ import ( storageerrors "github.com/juju/juju/domain/storage/errors" domaintesting "github.com/juju/juju/domain/testing" "github.com/juju/juju/internal/charm" - charmresource "github.com/juju/juju/internal/charm/resource" "github.com/juju/juju/internal/errors" loggertesting "github.com/juju/juju/internal/logger/testing" "github.com/juju/juju/internal/storage" @@ -1226,9 +1225,6 @@ func (s *applicationWatcherServiceSuite) setupMocks(c *gc.C) *gomock.Controller } }) - resourceStoreGetter := NewMockResourceStoreGetter(ctrl) - resourceStoreGetter.EXPECT().AddStore(charmresource.TypeContainerImage, gomock.Any()) - modelUUID := modeltesting.GenModelUUID(c) s.clock = testclock.NewClock(time.Time{}) @@ -1236,7 +1232,6 @@ func (s *applicationWatcherServiceSuite) setupMocks(c *gc.C) *gomock.Controller s.state, s.secret, registry, - resourceStoreGetter, modelUUID, s.watcherFactory, nil, diff --git a/domain/application/service/package_mock_test.go b/domain/application/service/package_mock_test.go index e3519b99b167..7ceb05f8bf18 100644 --- a/domain/application/service/package_mock_test.go +++ b/domain/application/service/package_mock_test.go @@ -1,9 +1,9 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/juju/juju/domain/application/service (interfaces: State,DeleteSecretState,ResourceStoreGetter,WatcherFactory,AgentVersionGetter,Provider,CharmStore) +// Source: github.com/juju/juju/domain/application/service (interfaces: State,DeleteSecretState,WatcherFactory,AgentVersionGetter,Provider,CharmStore) // // Generated by this command: // -// mockgen -typed -package service -destination package_mock_test.go github.com/juju/juju/domain/application/service State,DeleteSecretState,ResourceStoreGetter,WatcherFactory,AgentVersionGetter,Provider,CharmStore +// mockgen -typed -package service -destination package_mock_test.go github.com/juju/juju/domain/application/service State,DeleteSecretState,WatcherFactory,AgentVersionGetter,Provider,CharmStore // // Package service is a generated GoMock package. @@ -20,8 +20,6 @@ import ( charm "github.com/juju/juju/core/charm" model "github.com/juju/juju/core/model" network "github.com/juju/juju/core/network" - resource "github.com/juju/juju/core/resource" - store "github.com/juju/juju/core/resource/store" secrets "github.com/juju/juju/core/secrets" unit "github.com/juju/juju/core/unit" watcher "github.com/juju/juju/core/watcher" @@ -29,10 +27,8 @@ import ( domain "github.com/juju/juju/domain" application0 "github.com/juju/juju/domain/application" charm0 "github.com/juju/juju/domain/application/charm" - resource0 "github.com/juju/juju/domain/application/resource" life "github.com/juju/juju/domain/life" storage "github.com/juju/juju/domain/storage" - resource1 "github.com/juju/juju/internal/charm/resource" version "github.com/juju/version/v2" gomock "go.uber.org/mock/gomock" ) @@ -375,45 +371,6 @@ func (c *MockStateGetApplicationLifeCall) DoAndReturn(f func(domain.AtomicContex return c } -// GetApplicationResourceID mocks base method. -func (m *MockState) GetApplicationResourceID(arg0 context.Context, arg1 resource0.GetApplicationResourceIDArgs) (resource.UUID, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetApplicationResourceID", arg0, arg1) - ret0, _ := ret[0].(resource.UUID) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetApplicationResourceID indicates an expected call of GetApplicationResourceID. -func (mr *MockStateMockRecorder) GetApplicationResourceID(arg0, arg1 any) *MockStateGetApplicationResourceIDCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetApplicationResourceID", reflect.TypeOf((*MockState)(nil).GetApplicationResourceID), arg0, arg1) - return &MockStateGetApplicationResourceIDCall{Call: call} -} - -// MockStateGetApplicationResourceIDCall wrap *gomock.Call -type MockStateGetApplicationResourceIDCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *MockStateGetApplicationResourceIDCall) Return(arg0 resource.UUID, arg1 error) *MockStateGetApplicationResourceIDCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *MockStateGetApplicationResourceIDCall) Do(f func(context.Context, resource0.GetApplicationResourceIDArgs) (resource.UUID, error)) *MockStateGetApplicationResourceIDCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockStateGetApplicationResourceIDCall) DoAndReturn(f func(context.Context, resource0.GetApplicationResourceIDArgs) (resource.UUID, error)) *MockStateGetApplicationResourceIDCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - // GetApplicationScaleState mocks base method. func (m *MockState) GetApplicationScaleState(arg0 domain.AtomicContext, arg1 application.ID) (application0.ScaleState, error) { m.ctrl.T.Helper() @@ -1126,45 +1083,6 @@ func (c *MockStateGetModelTypeCall) DoAndReturn(f func(context.Context) (model.M return c } -// GetResource mocks base method. -func (m *MockState) GetResource(arg0 context.Context, arg1 resource.UUID) (resource0.Resource, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetResource", arg0, arg1) - ret0, _ := ret[0].(resource0.Resource) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetResource indicates an expected call of GetResource. -func (mr *MockStateMockRecorder) GetResource(arg0, arg1 any) *MockStateGetResourceCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetResource", reflect.TypeOf((*MockState)(nil).GetResource), arg0, arg1) - return &MockStateGetResourceCall{Call: call} -} - -// MockStateGetResourceCall wrap *gomock.Call -type MockStateGetResourceCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *MockStateGetResourceCall) Return(arg0 resource0.Resource, arg1 error) *MockStateGetResourceCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *MockStateGetResourceCall) Do(f func(context.Context, resource.UUID) (resource0.Resource, error)) *MockStateGetResourceCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockStateGetResourceCall) DoAndReturn(f func(context.Context, resource.UUID) (resource0.Resource, error)) *MockStateGetResourceCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - // GetSecretsForApplication mocks base method. func (m *MockState) GetSecretsForApplication(arg0 domain.AtomicContext, arg1 string) ([]*secrets.URI, error) { m.ctrl.T.Helper() @@ -1749,123 +1667,6 @@ func (c *MockStateListCharmsWithOriginByNamesCall) DoAndReturn(f func(context.Co return c } -// ListResources mocks base method. -func (m *MockState) ListResources(arg0 context.Context, arg1 application.ID) (resource0.ApplicationResources, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ListResources", arg0, arg1) - ret0, _ := ret[0].(resource0.ApplicationResources) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ListResources indicates an expected call of ListResources. -func (mr *MockStateMockRecorder) ListResources(arg0, arg1 any) *MockStateListResourcesCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResources", reflect.TypeOf((*MockState)(nil).ListResources), arg0, arg1) - return &MockStateListResourcesCall{Call: call} -} - -// MockStateListResourcesCall wrap *gomock.Call -type MockStateListResourcesCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *MockStateListResourcesCall) Return(arg0 resource0.ApplicationResources, arg1 error) *MockStateListResourcesCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *MockStateListResourcesCall) Do(f func(context.Context, application.ID) (resource0.ApplicationResources, error)) *MockStateListResourcesCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockStateListResourcesCall) DoAndReturn(f func(context.Context, application.ID) (resource0.ApplicationResources, error)) *MockStateListResourcesCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// OpenApplicationResource mocks base method. -func (m *MockState) OpenApplicationResource(arg0 context.Context, arg1 resource.UUID) (resource0.Resource, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "OpenApplicationResource", arg0, arg1) - ret0, _ := ret[0].(resource0.Resource) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// OpenApplicationResource indicates an expected call of OpenApplicationResource. -func (mr *MockStateMockRecorder) OpenApplicationResource(arg0, arg1 any) *MockStateOpenApplicationResourceCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenApplicationResource", reflect.TypeOf((*MockState)(nil).OpenApplicationResource), arg0, arg1) - return &MockStateOpenApplicationResourceCall{Call: call} -} - -// MockStateOpenApplicationResourceCall wrap *gomock.Call -type MockStateOpenApplicationResourceCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *MockStateOpenApplicationResourceCall) Return(arg0 resource0.Resource, arg1 error) *MockStateOpenApplicationResourceCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *MockStateOpenApplicationResourceCall) Do(f func(context.Context, resource.UUID) (resource0.Resource, error)) *MockStateOpenApplicationResourceCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockStateOpenApplicationResourceCall) DoAndReturn(f func(context.Context, resource.UUID) (resource0.Resource, error)) *MockStateOpenApplicationResourceCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// OpenUnitResource mocks base method. -func (m *MockState) OpenUnitResource(arg0 context.Context, arg1 resource.UUID, arg2 unit.UUID) (resource0.Resource, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "OpenUnitResource", arg0, arg1, arg2) - ret0, _ := ret[0].(resource0.Resource) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// OpenUnitResource indicates an expected call of OpenUnitResource. -func (mr *MockStateMockRecorder) OpenUnitResource(arg0, arg1, arg2 any) *MockStateOpenUnitResourceCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUnitResource", reflect.TypeOf((*MockState)(nil).OpenUnitResource), arg0, arg1, arg2) - return &MockStateOpenUnitResourceCall{Call: call} -} - -// MockStateOpenUnitResourceCall wrap *gomock.Call -type MockStateOpenUnitResourceCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *MockStateOpenUnitResourceCall) Return(arg0 resource0.Resource, arg1 error) *MockStateOpenUnitResourceCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *MockStateOpenUnitResourceCall) Do(f func(context.Context, resource.UUID, unit.UUID) (resource0.Resource, error)) *MockStateOpenUnitResourceCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockStateOpenUnitResourceCall) DoAndReturn(f func(context.Context, resource.UUID, unit.UUID) (resource0.Resource, error)) *MockStateOpenUnitResourceCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - // ReserveCharmRevision mocks base method. func (m *MockState) ReserveCharmRevision(arg0 context.Context, arg1 charm.ID, arg2 int) (charm.ID, error) { m.ctrl.T.Helper() @@ -2172,83 +1973,6 @@ func (c *MockStateSetDesiredApplicationScaleCall) DoAndReturn(f func(domain.Atom return c } -// SetRepositoryResources mocks base method. -func (m *MockState) SetRepositoryResources(arg0 context.Context, arg1 resource0.SetRepositoryResourcesArgs) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetRepositoryResources", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetRepositoryResources indicates an expected call of SetRepositoryResources. -func (mr *MockStateMockRecorder) SetRepositoryResources(arg0, arg1 any) *MockStateSetRepositoryResourcesCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetRepositoryResources", reflect.TypeOf((*MockState)(nil).SetRepositoryResources), arg0, arg1) - return &MockStateSetRepositoryResourcesCall{Call: call} -} - -// MockStateSetRepositoryResourcesCall wrap *gomock.Call -type MockStateSetRepositoryResourcesCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *MockStateSetRepositoryResourcesCall) Return(arg0 error) *MockStateSetRepositoryResourcesCall { - c.Call = c.Call.Return(arg0) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *MockStateSetRepositoryResourcesCall) Do(f func(context.Context, resource0.SetRepositoryResourcesArgs) error) *MockStateSetRepositoryResourcesCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockStateSetRepositoryResourcesCall) DoAndReturn(f func(context.Context, resource0.SetRepositoryResourcesArgs) error) *MockStateSetRepositoryResourcesCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// SetResource mocks base method. -func (m *MockState) SetResource(arg0 context.Context, arg1 resource0.SetResourceArgs) (resource0.Resource, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetResource", arg0, arg1) - ret0, _ := ret[0].(resource0.Resource) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// SetResource indicates an expected call of SetResource. -func (mr *MockStateMockRecorder) SetResource(arg0, arg1 any) *MockStateSetResourceCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetResource", reflect.TypeOf((*MockState)(nil).SetResource), arg0, arg1) - return &MockStateSetResourceCall{Call: call} -} - -// MockStateSetResourceCall wrap *gomock.Call -type MockStateSetResourceCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *MockStateSetResourceCall) Return(arg0 resource0.Resource, arg1 error) *MockStateSetResourceCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *MockStateSetResourceCall) Do(f func(context.Context, resource0.SetResourceArgs) (resource0.Resource, error)) *MockStateSetResourceCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockStateSetResourceCall) DoAndReturn(f func(context.Context, resource0.SetResourceArgs) (resource0.Resource, error)) *MockStateSetResourceCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - // SetUnitAgentStatus mocks base method. func (m *MockState) SetUnitAgentStatus(arg0 domain.AtomicContext, arg1 unit.UUID, arg2 application0.UnitAgentStatusInfo) error { m.ctrl.T.Helper() @@ -2363,45 +2087,6 @@ func (c *MockStateSetUnitPasswordCall) DoAndReturn(f func(domain.AtomicContext, return c } -// SetUnitResource mocks base method. -func (m *MockState) SetUnitResource(arg0 context.Context, arg1 resource0.SetUnitResourceArgs) (resource0.SetUnitResourceResult, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetUnitResource", arg0, arg1) - ret0, _ := ret[0].(resource0.SetUnitResourceResult) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// SetUnitResource indicates an expected call of SetUnitResource. -func (mr *MockStateMockRecorder) SetUnitResource(arg0, arg1 any) *MockStateSetUnitResourceCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetUnitResource", reflect.TypeOf((*MockState)(nil).SetUnitResource), arg0, arg1) - return &MockStateSetUnitResourceCall{Call: call} -} - -// MockStateSetUnitResourceCall wrap *gomock.Call -type MockStateSetUnitResourceCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *MockStateSetUnitResourceCall) Return(arg0 resource0.SetUnitResourceResult, arg1 error) *MockStateSetUnitResourceCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *MockStateSetUnitResourceCall) Do(f func(context.Context, resource0.SetUnitResourceArgs) (resource0.SetUnitResourceResult, error)) *MockStateSetUnitResourceCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockStateSetUnitResourceCall) DoAndReturn(f func(context.Context, resource0.SetUnitResourceArgs) (resource0.SetUnitResourceResult, error)) *MockStateSetUnitResourceCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - // SetUnitWorkloadStatus mocks base method. func (m *MockState) SetUnitWorkloadStatus(arg0 domain.AtomicContext, arg1 unit.UUID, arg2 application0.UnitWorkloadStatusInfo) error { m.ctrl.T.Helper() @@ -2655,104 +2340,6 @@ func (c *MockDeleteSecretStateDeleteSecretCall) DoAndReturn(f func(domain.Atomic return c } -// MockResourceStoreGetter is a mock of ResourceStoreGetter interface. -type MockResourceStoreGetter struct { - ctrl *gomock.Controller - recorder *MockResourceStoreGetterMockRecorder -} - -// MockResourceStoreGetterMockRecorder is the mock recorder for MockResourceStoreGetter. -type MockResourceStoreGetterMockRecorder struct { - mock *MockResourceStoreGetter -} - -// NewMockResourceStoreGetter creates a new mock instance. -func NewMockResourceStoreGetter(ctrl *gomock.Controller) *MockResourceStoreGetter { - mock := &MockResourceStoreGetter{ctrl: ctrl} - mock.recorder = &MockResourceStoreGetterMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockResourceStoreGetter) EXPECT() *MockResourceStoreGetterMockRecorder { - return m.recorder -} - -// AddStore mocks base method. -func (m *MockResourceStoreGetter) AddStore(arg0 resource1.Type, arg1 store.ResourceStore) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddStore", arg0, arg1) -} - -// AddStore indicates an expected call of AddStore. -func (mr *MockResourceStoreGetterMockRecorder) AddStore(arg0, arg1 any) *MockResourceStoreGetterAddStoreCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddStore", reflect.TypeOf((*MockResourceStoreGetter)(nil).AddStore), arg0, arg1) - return &MockResourceStoreGetterAddStoreCall{Call: call} -} - -// MockResourceStoreGetterAddStoreCall wrap *gomock.Call -type MockResourceStoreGetterAddStoreCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *MockResourceStoreGetterAddStoreCall) Return() *MockResourceStoreGetterAddStoreCall { - c.Call = c.Call.Return() - return c -} - -// Do rewrite *gomock.Call.Do -func (c *MockResourceStoreGetterAddStoreCall) Do(f func(resource1.Type, store.ResourceStore)) *MockResourceStoreGetterAddStoreCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockResourceStoreGetterAddStoreCall) DoAndReturn(f func(resource1.Type, store.ResourceStore)) *MockResourceStoreGetterAddStoreCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// GetResourceStore mocks base method. -func (m *MockResourceStoreGetter) GetResourceStore(arg0 context.Context, arg1 resource1.Type) (store.ResourceStore, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetResourceStore", arg0, arg1) - ret0, _ := ret[0].(store.ResourceStore) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetResourceStore indicates an expected call of GetResourceStore. -func (mr *MockResourceStoreGetterMockRecorder) GetResourceStore(arg0, arg1 any) *MockResourceStoreGetterGetResourceStoreCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetResourceStore", reflect.TypeOf((*MockResourceStoreGetter)(nil).GetResourceStore), arg0, arg1) - return &MockResourceStoreGetterGetResourceStoreCall{Call: call} -} - -// MockResourceStoreGetterGetResourceStoreCall wrap *gomock.Call -type MockResourceStoreGetterGetResourceStoreCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *MockResourceStoreGetterGetResourceStoreCall) Return(arg0 store.ResourceStore, arg1 error) *MockResourceStoreGetterGetResourceStoreCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *MockResourceStoreGetterGetResourceStoreCall) Do(f func(context.Context, resource1.Type) (store.ResourceStore, error)) *MockResourceStoreGetterGetResourceStoreCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockResourceStoreGetterGetResourceStoreCall) DoAndReturn(f func(context.Context, resource1.Type) (store.ResourceStore, error)) *MockResourceStoreGetterGetResourceStoreCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - // MockWatcherFactory is a mock of WatcherFactory interface. type MockWatcherFactory struct { ctrl *gomock.Controller diff --git a/domain/application/service/package_test.go b/domain/application/service/package_test.go index 526914aa72c4..639b2b73f2ab 100644 --- a/domain/application/service/package_test.go +++ b/domain/application/service/package_test.go @@ -20,14 +20,13 @@ import ( corestorage "github.com/juju/juju/core/storage" "github.com/juju/juju/domain" domaintesting "github.com/juju/juju/domain/testing" - "github.com/juju/juju/internal/charm/resource" loggertesting "github.com/juju/juju/internal/logger/testing" "github.com/juju/juju/internal/storage" "github.com/juju/juju/internal/storage/provider" dummystorage "github.com/juju/juju/internal/storage/provider/dummy" ) -//go:generate go run go.uber.org/mock/mockgen -typed -package service -destination package_mock_test.go github.com/juju/juju/domain/application/service State,DeleteSecretState,ResourceStoreGetter,WatcherFactory,AgentVersionGetter,Provider,CharmStore +//go:generate go run go.uber.org/mock/mockgen -typed -package service -destination package_mock_test.go github.com/juju/juju/domain/application/service State,DeleteSecretState,WatcherFactory,AgentVersionGetter,Provider,CharmStore //go:generate go run go.uber.org/mock/mockgen -typed -package service -destination charm_mock_test.go github.com/juju/juju/internal/charm Charm func TestPackage(t *testing.T) { @@ -39,13 +38,12 @@ type baseSuite struct { modelID model.UUID - state *MockState - charm *MockCharm - secret *MockDeleteSecretState - charmStore *MockCharmStore - agentVersionGetter *MockAgentVersionGetter - provider *MockProvider - resourceStoreGetter *MockResourceStoreGetter + state *MockState + charm *MockCharm + secret *MockDeleteSecretState + charmStore *MockCharmStore + agentVersionGetter *MockAgentVersionGetter + provider *MockProvider storageRegistryGetter corestorage.ModelStorageRegistryGetter clock *testclock.Clock @@ -71,7 +69,6 @@ func (s *baseSuite) setupMocksWithProvider(c *gc.C, fn func(ctx context.Context) s.charm = NewMockCharm(ctrl) s.secret = NewMockDeleteSecretState(ctrl) s.charmStore = NewMockCharmStore(ctrl) - s.resourceStoreGetter = NewMockResourceStoreGetter(ctrl) s.storageRegistryGetter = corestorage.ConstModelStorageRegistry(func() storage.ProviderRegistry { return storage.ChainedProviderRegistry{ @@ -80,14 +77,11 @@ func (s *baseSuite) setupMocksWithProvider(c *gc.C, fn func(ctx context.Context) } }) - s.resourceStoreGetter.EXPECT().AddStore(resource.TypeContainerImage, gomock.Any()) - s.clock = testclock.NewClock(time.Time{}) s.service = NewProviderService( s.state, s.secret, s.storageRegistryGetter, - s.resourceStoreGetter, s.modelID, s.agentVersionGetter, fn, @@ -113,7 +107,6 @@ func (s *baseSuite) setupMocksWithAtomic(c *gc.C, fn func(domain.AtomicContext) s.charm = NewMockCharm(ctrl) s.secret = NewMockDeleteSecretState(ctrl) s.charmStore = NewMockCharmStore(ctrl) - s.resourceStoreGetter = NewMockResourceStoreGetter(ctrl) s.storageRegistryGetter = corestorage.ConstModelStorageRegistry(func() storage.ProviderRegistry { return storage.ChainedProviderRegistry{ @@ -122,14 +115,11 @@ func (s *baseSuite) setupMocksWithAtomic(c *gc.C, fn func(domain.AtomicContext) } }) - s.resourceStoreGetter.EXPECT().AddStore(resource.TypeContainerImage, gomock.Any()) - s.clock = testclock.NewClock(time.Time{}) s.service = NewProviderService( s.state, s.secret, s.storageRegistryGetter, - s.resourceStoreGetter, s.modelID, s.agentVersionGetter, func(ctx context.Context) (Provider, error) { diff --git a/domain/application/service/service.go b/domain/application/service/service.go index 88ff1271278f..71331e5598a4 100644 --- a/domain/application/service/service.go +++ b/domain/application/service/service.go @@ -34,7 +34,6 @@ import ( domainstorage "github.com/juju/juju/domain/storage" "github.com/juju/juju/environs" internalcharm "github.com/juju/juju/internal/charm" - charmresource "github.com/juju/juju/internal/charm/resource" "github.com/juju/juju/internal/storage" ) @@ -42,7 +41,6 @@ import ( type State interface { ApplicationState CharmState - ResourceState } const ( @@ -62,7 +60,6 @@ type Service struct { clock clock.Clock storageRegistryGetter corestorage.ModelStorageRegistryGetter - resourceStoreGetter ResourceStoreGetter secretDeleter DeleteSecretState charmStore CharmStore } @@ -73,25 +70,14 @@ func NewService( deleteSecretState DeleteSecretState, storageRegistryGetter corestorage.ModelStorageRegistryGetter, charmStore CharmStore, - resourceStoreGetter ResourceStoreGetter, clock clock.Clock, logger logger.Logger, ) *Service { - // Note: - // The store for container image resources is really a DQLite table today. - // Using AddStore is a compromise to avoid injecting one service into - // another, as would happen if NewResourceStoreFactory had a second - // argument to provide a containerImageResourceStore. - resourceStoreGetter.AddStore( - charmresource.TypeContainerImage, - nil, - ) return &Service{ st: st, logger: logger, clock: clock, storageRegistryGetter: storageRegistryGetter, - resourceStoreGetter: resourceStoreGetter, secretDeleter: deleteSecretState, charmStore: charmStore, } @@ -126,7 +112,6 @@ func NewProviderService( st State, deleteSecretState DeleteSecretState, storageRegistryGetter corestorage.ModelStorageRegistryGetter, - resourceStoreGetter ResourceStoreGetter, modelID coremodel.UUID, agentVersionGetter AgentVersionGetter, provider providertracker.ProviderGetter[Provider], @@ -140,7 +125,6 @@ func NewProviderService( deleteSecretState, storageRegistryGetter, charmStore, - resourceStoreGetter, clock, logger, ), @@ -196,7 +180,6 @@ func NewWatchableService( st State, deleteSecretState DeleteSecretState, storageRegistryGetter corestorage.ModelStorageRegistryGetter, - resourceStoreGetter ResourceStoreGetter, modelID coremodel.UUID, watcherFactory WatcherFactory, agentVersionGetter AgentVersionGetter, @@ -210,7 +193,6 @@ func NewWatchableService( st, deleteSecretState, storageRegistryGetter, - resourceStoreGetter, modelID, agentVersionGetter, provider, diff --git a/domain/application/state/types.go b/domain/application/state/types.go index 17cc665eff8d..adddd003e39f 100644 --- a/domain/application/state/types.go +++ b/domain/application/state/types.go @@ -7,13 +7,10 @@ import ( "time" coreapplication "github.com/juju/juju/core/application" - coreresource "github.com/juju/juju/core/resource" coresecrets "github.com/juju/juju/core/secrets" coreunit "github.com/juju/juju/core/unit" "github.com/juju/juju/domain/application" - "github.com/juju/juju/domain/application/resource" "github.com/juju/juju/domain/life" - charmresource "github.com/juju/juju/internal/charm/resource" "github.com/juju/juju/internal/errors" ) @@ -610,62 +607,3 @@ type charmNameWithOrigin struct { Revision int `db:"revision"` ArchitectureID int `db:"architecture_id"` } - -// resourceIdentity represents the unique identity of a resource within an application. -type resourceIdentity struct { - UUID string `db:"uuid"` - ApplicationUUID string `db:"application_uuid"` - Name string `db:"name"` -} - -// resourceView represents the view model for a resource entity. It contains -// all fields from v_resource table view -type resourceView struct { - UUID string `db:"uuid"` - ApplicationUUID string `db:"application_uuid"` - Name string `db:"name"` - CreatedAt time.Time `db:"created_at"` - Revision int `db:"revision"` - OriginTypeId int `db:"origin_type_id"` - RetrievedBy string `db:"retrieved_by"` - RetrievedByType string `db:"retrieved_by_type"` - Path string `db:"path"` - Description string `db:"description"` - KindId int `db:"kind_id"` -} - -// toCharmResource converts the resourceView struct to a charmresource.Resource, populating its fields accordingly. -func (rv resourceView) toCharmResource() charmresource.Resource { - return charmresource.Resource{ - Meta: charmresource.Meta{ - Name: rv.Name, - Type: charmresource.Type(rv.KindId), - Path: rv.Path, - Description: rv.Description, - }, - Origin: charmresource.Origin(rv.OriginTypeId), - Revision: rv.Revision, - // todo(gfouillet): deal with fingerprint & size - Fingerprint: charmresource.Fingerprint{}, - Size: 0, - } -} - -// toResource converts a resourceView object to a resource.Resource object including metadata and timestamps. -func (rv resourceView) toResource() resource.Resource { - return resource.Resource{ - Resource: rv.toCharmResource(), - UUID: coreresource.UUID(rv.UUID), - ApplicationID: coreapplication.ID(rv.ApplicationUUID), - RetrievedBy: rv.RetrievedBy, - RetrievedByType: resource.RetrievedByType(rv.RetrievedByType), - Timestamp: rv.CreatedAt, - } -} - -// unitResource represents the mapping of a resource to a unit. -type unitResource struct { - ResourceUUID string `db:"resource_uuid"` - UnitUUID string `db:"unit_uuid"` - AddedAt time.Time `db:"added_at"` -} diff --git a/domain/application/resource/doc.go b/domain/resource/doc.go similarity index 100% rename from domain/application/resource/doc.go rename to domain/resource/doc.go diff --git a/domain/resource/errors/errors.go b/domain/resource/errors/errors.go new file mode 100644 index 000000000000..c6bc0434d1c9 --- /dev/null +++ b/domain/resource/errors/errors.go @@ -0,0 +1,32 @@ +// Copyright 2024 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package errors + +import "github.com/juju/juju/internal/errors" + +const ( + // ApplicationNotFound describes an error that occurs when the application + // being operated on does not exist. + ApplicationNotFound = errors.ConstError("application not found") + + // ArgumentNotValid describes an error that occurs when an argument to + // the service is invalid. + ArgumentNotValid = errors.ConstError("argument not valid") + + // ResourceNotFound describes an error that occurs when a resource is + // not found. + ResourceNotFound = errors.ConstError("resource not found") + + // UnknownRetrievedByType describes an error where the retrieved by type is + // neither user, unit nor application. + UnknownRetrievedByType = errors.ConstError("unknown retrieved by type") + + // ResourceNameNotValid describes an error where the resource name is not + // valid, usually because it's empty. + ResourceNameNotValid = errors.ConstError("resource name not valid") + + // UnitNotFound describes an error that occurs when the unit being operated on + // does not exist. + UnitNotFound = errors.ConstError("unit not found") +) diff --git a/domain/resource/service/package_mock_test.go b/domain/resource/service/package_mock_test.go new file mode 100644 index 000000000000..a6ae96ca182d --- /dev/null +++ b/domain/resource/service/package_mock_test.go @@ -0,0 +1,455 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/juju/juju/domain/resource/service (interfaces: State,ResourceStoreGetter) +// +// Generated by this command: +// +// mockgen -typed -package service -destination package_mock_test.go github.com/juju/juju/domain/resource/service State,ResourceStoreGetter +// + +// Package service is a generated GoMock package. +package service + +import ( + context "context" + reflect "reflect" + + application "github.com/juju/juju/core/application" + resource "github.com/juju/juju/core/resource" + store "github.com/juju/juju/core/resource/store" + unit "github.com/juju/juju/core/unit" + resource0 "github.com/juju/juju/domain/resource" + resource1 "github.com/juju/juju/internal/charm/resource" + gomock "go.uber.org/mock/gomock" +) + +// MockState is a mock of State interface. +type MockState struct { + ctrl *gomock.Controller + recorder *MockStateMockRecorder +} + +// MockStateMockRecorder is the mock recorder for MockState. +type MockStateMockRecorder struct { + mock *MockState +} + +// NewMockState creates a new mock instance. +func NewMockState(ctrl *gomock.Controller) *MockState { + mock := &MockState{ctrl: ctrl} + mock.recorder = &MockStateMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockState) EXPECT() *MockStateMockRecorder { + return m.recorder +} + +// GetApplicationResourceID mocks base method. +func (m *MockState) GetApplicationResourceID(arg0 context.Context, arg1 resource0.GetApplicationResourceIDArgs) (resource.UUID, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetApplicationResourceID", arg0, arg1) + ret0, _ := ret[0].(resource.UUID) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetApplicationResourceID indicates an expected call of GetApplicationResourceID. +func (mr *MockStateMockRecorder) GetApplicationResourceID(arg0, arg1 any) *MockStateGetApplicationResourceIDCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetApplicationResourceID", reflect.TypeOf((*MockState)(nil).GetApplicationResourceID), arg0, arg1) + return &MockStateGetApplicationResourceIDCall{Call: call} +} + +// MockStateGetApplicationResourceIDCall wrap *gomock.Call +type MockStateGetApplicationResourceIDCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockStateGetApplicationResourceIDCall) Return(arg0 resource.UUID, arg1 error) *MockStateGetApplicationResourceIDCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockStateGetApplicationResourceIDCall) Do(f func(context.Context, resource0.GetApplicationResourceIDArgs) (resource.UUID, error)) *MockStateGetApplicationResourceIDCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockStateGetApplicationResourceIDCall) DoAndReturn(f func(context.Context, resource0.GetApplicationResourceIDArgs) (resource.UUID, error)) *MockStateGetApplicationResourceIDCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// GetResource mocks base method. +func (m *MockState) GetResource(arg0 context.Context, arg1 resource.UUID) (resource0.Resource, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetResource", arg0, arg1) + ret0, _ := ret[0].(resource0.Resource) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetResource indicates an expected call of GetResource. +func (mr *MockStateMockRecorder) GetResource(arg0, arg1 any) *MockStateGetResourceCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetResource", reflect.TypeOf((*MockState)(nil).GetResource), arg0, arg1) + return &MockStateGetResourceCall{Call: call} +} + +// MockStateGetResourceCall wrap *gomock.Call +type MockStateGetResourceCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockStateGetResourceCall) Return(arg0 resource0.Resource, arg1 error) *MockStateGetResourceCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockStateGetResourceCall) Do(f func(context.Context, resource.UUID) (resource0.Resource, error)) *MockStateGetResourceCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockStateGetResourceCall) DoAndReturn(f func(context.Context, resource.UUID) (resource0.Resource, error)) *MockStateGetResourceCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// ListResources mocks base method. +func (m *MockState) ListResources(arg0 context.Context, arg1 application.ID) (resource0.ApplicationResources, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListResources", arg0, arg1) + ret0, _ := ret[0].(resource0.ApplicationResources) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListResources indicates an expected call of ListResources. +func (mr *MockStateMockRecorder) ListResources(arg0, arg1 any) *MockStateListResourcesCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResources", reflect.TypeOf((*MockState)(nil).ListResources), arg0, arg1) + return &MockStateListResourcesCall{Call: call} +} + +// MockStateListResourcesCall wrap *gomock.Call +type MockStateListResourcesCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockStateListResourcesCall) Return(arg0 resource0.ApplicationResources, arg1 error) *MockStateListResourcesCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockStateListResourcesCall) Do(f func(context.Context, application.ID) (resource0.ApplicationResources, error)) *MockStateListResourcesCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockStateListResourcesCall) DoAndReturn(f func(context.Context, application.ID) (resource0.ApplicationResources, error)) *MockStateListResourcesCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// OpenApplicationResource mocks base method. +func (m *MockState) OpenApplicationResource(arg0 context.Context, arg1 resource.UUID) (resource0.Resource, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "OpenApplicationResource", arg0, arg1) + ret0, _ := ret[0].(resource0.Resource) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// OpenApplicationResource indicates an expected call of OpenApplicationResource. +func (mr *MockStateMockRecorder) OpenApplicationResource(arg0, arg1 any) *MockStateOpenApplicationResourceCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenApplicationResource", reflect.TypeOf((*MockState)(nil).OpenApplicationResource), arg0, arg1) + return &MockStateOpenApplicationResourceCall{Call: call} +} + +// MockStateOpenApplicationResourceCall wrap *gomock.Call +type MockStateOpenApplicationResourceCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockStateOpenApplicationResourceCall) Return(arg0 resource0.Resource, arg1 error) *MockStateOpenApplicationResourceCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockStateOpenApplicationResourceCall) Do(f func(context.Context, resource.UUID) (resource0.Resource, error)) *MockStateOpenApplicationResourceCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockStateOpenApplicationResourceCall) DoAndReturn(f func(context.Context, resource.UUID) (resource0.Resource, error)) *MockStateOpenApplicationResourceCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// OpenUnitResource mocks base method. +func (m *MockState) OpenUnitResource(arg0 context.Context, arg1 resource.UUID, arg2 unit.UUID) (resource0.Resource, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "OpenUnitResource", arg0, arg1, arg2) + ret0, _ := ret[0].(resource0.Resource) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// OpenUnitResource indicates an expected call of OpenUnitResource. +func (mr *MockStateMockRecorder) OpenUnitResource(arg0, arg1, arg2 any) *MockStateOpenUnitResourceCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUnitResource", reflect.TypeOf((*MockState)(nil).OpenUnitResource), arg0, arg1, arg2) + return &MockStateOpenUnitResourceCall{Call: call} +} + +// MockStateOpenUnitResourceCall wrap *gomock.Call +type MockStateOpenUnitResourceCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockStateOpenUnitResourceCall) Return(arg0 resource0.Resource, arg1 error) *MockStateOpenUnitResourceCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockStateOpenUnitResourceCall) Do(f func(context.Context, resource.UUID, unit.UUID) (resource0.Resource, error)) *MockStateOpenUnitResourceCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockStateOpenUnitResourceCall) DoAndReturn(f func(context.Context, resource.UUID, unit.UUID) (resource0.Resource, error)) *MockStateOpenUnitResourceCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetRepositoryResources mocks base method. +func (m *MockState) SetRepositoryResources(arg0 context.Context, arg1 resource0.SetRepositoryResourcesArgs) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetRepositoryResources", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetRepositoryResources indicates an expected call of SetRepositoryResources. +func (mr *MockStateMockRecorder) SetRepositoryResources(arg0, arg1 any) *MockStateSetRepositoryResourcesCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetRepositoryResources", reflect.TypeOf((*MockState)(nil).SetRepositoryResources), arg0, arg1) + return &MockStateSetRepositoryResourcesCall{Call: call} +} + +// MockStateSetRepositoryResourcesCall wrap *gomock.Call +type MockStateSetRepositoryResourcesCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockStateSetRepositoryResourcesCall) Return(arg0 error) *MockStateSetRepositoryResourcesCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockStateSetRepositoryResourcesCall) Do(f func(context.Context, resource0.SetRepositoryResourcesArgs) error) *MockStateSetRepositoryResourcesCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockStateSetRepositoryResourcesCall) DoAndReturn(f func(context.Context, resource0.SetRepositoryResourcesArgs) error) *MockStateSetRepositoryResourcesCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetResource mocks base method. +func (m *MockState) SetResource(arg0 context.Context, arg1 resource0.SetResourceArgs) (resource0.Resource, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetResource", arg0, arg1) + ret0, _ := ret[0].(resource0.Resource) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetResource indicates an expected call of SetResource. +func (mr *MockStateMockRecorder) SetResource(arg0, arg1 any) *MockStateSetResourceCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetResource", reflect.TypeOf((*MockState)(nil).SetResource), arg0, arg1) + return &MockStateSetResourceCall{Call: call} +} + +// MockStateSetResourceCall wrap *gomock.Call +type MockStateSetResourceCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockStateSetResourceCall) Return(arg0 resource0.Resource, arg1 error) *MockStateSetResourceCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockStateSetResourceCall) Do(f func(context.Context, resource0.SetResourceArgs) (resource0.Resource, error)) *MockStateSetResourceCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockStateSetResourceCall) DoAndReturn(f func(context.Context, resource0.SetResourceArgs) (resource0.Resource, error)) *MockStateSetResourceCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetUnitResource mocks base method. +func (m *MockState) SetUnitResource(arg0 context.Context, arg1 resource0.SetUnitResourceArgs) (resource0.SetUnitResourceResult, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetUnitResource", arg0, arg1) + ret0, _ := ret[0].(resource0.SetUnitResourceResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetUnitResource indicates an expected call of SetUnitResource. +func (mr *MockStateMockRecorder) SetUnitResource(arg0, arg1 any) *MockStateSetUnitResourceCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetUnitResource", reflect.TypeOf((*MockState)(nil).SetUnitResource), arg0, arg1) + return &MockStateSetUnitResourceCall{Call: call} +} + +// MockStateSetUnitResourceCall wrap *gomock.Call +type MockStateSetUnitResourceCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockStateSetUnitResourceCall) Return(arg0 resource0.SetUnitResourceResult, arg1 error) *MockStateSetUnitResourceCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockStateSetUnitResourceCall) Do(f func(context.Context, resource0.SetUnitResourceArgs) (resource0.SetUnitResourceResult, error)) *MockStateSetUnitResourceCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockStateSetUnitResourceCall) DoAndReturn(f func(context.Context, resource0.SetUnitResourceArgs) (resource0.SetUnitResourceResult, error)) *MockStateSetUnitResourceCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// MockResourceStoreGetter is a mock of ResourceStoreGetter interface. +type MockResourceStoreGetter struct { + ctrl *gomock.Controller + recorder *MockResourceStoreGetterMockRecorder +} + +// MockResourceStoreGetterMockRecorder is the mock recorder for MockResourceStoreGetter. +type MockResourceStoreGetterMockRecorder struct { + mock *MockResourceStoreGetter +} + +// NewMockResourceStoreGetter creates a new mock instance. +func NewMockResourceStoreGetter(ctrl *gomock.Controller) *MockResourceStoreGetter { + mock := &MockResourceStoreGetter{ctrl: ctrl} + mock.recorder = &MockResourceStoreGetterMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockResourceStoreGetter) EXPECT() *MockResourceStoreGetterMockRecorder { + return m.recorder +} + +// AddStore mocks base method. +func (m *MockResourceStoreGetter) AddStore(arg0 resource1.Type, arg1 store.ResourceStore) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddStore", arg0, arg1) +} + +// AddStore indicates an expected call of AddStore. +func (mr *MockResourceStoreGetterMockRecorder) AddStore(arg0, arg1 any) *MockResourceStoreGetterAddStoreCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddStore", reflect.TypeOf((*MockResourceStoreGetter)(nil).AddStore), arg0, arg1) + return &MockResourceStoreGetterAddStoreCall{Call: call} +} + +// MockResourceStoreGetterAddStoreCall wrap *gomock.Call +type MockResourceStoreGetterAddStoreCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockResourceStoreGetterAddStoreCall) Return() *MockResourceStoreGetterAddStoreCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockResourceStoreGetterAddStoreCall) Do(f func(resource1.Type, store.ResourceStore)) *MockResourceStoreGetterAddStoreCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockResourceStoreGetterAddStoreCall) DoAndReturn(f func(resource1.Type, store.ResourceStore)) *MockResourceStoreGetterAddStoreCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// GetResourceStore mocks base method. +func (m *MockResourceStoreGetter) GetResourceStore(arg0 context.Context, arg1 resource1.Type) (store.ResourceStore, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetResourceStore", arg0, arg1) + ret0, _ := ret[0].(store.ResourceStore) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetResourceStore indicates an expected call of GetResourceStore. +func (mr *MockResourceStoreGetterMockRecorder) GetResourceStore(arg0, arg1 any) *MockResourceStoreGetterGetResourceStoreCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetResourceStore", reflect.TypeOf((*MockResourceStoreGetter)(nil).GetResourceStore), arg0, arg1) + return &MockResourceStoreGetterGetResourceStoreCall{Call: call} +} + +// MockResourceStoreGetterGetResourceStoreCall wrap *gomock.Call +type MockResourceStoreGetterGetResourceStoreCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockResourceStoreGetterGetResourceStoreCall) Return(arg0 store.ResourceStore, arg1 error) *MockResourceStoreGetterGetResourceStoreCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockResourceStoreGetterGetResourceStoreCall) Do(f func(context.Context, resource1.Type) (store.ResourceStore, error)) *MockResourceStoreGetterGetResourceStoreCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockResourceStoreGetterGetResourceStoreCall) DoAndReturn(f func(context.Context, resource1.Type) (store.ResourceStore, error)) *MockResourceStoreGetterGetResourceStoreCall { + c.Call = c.Call.DoAndReturn(f) + return c +} diff --git a/domain/resource/service/package_test.go b/domain/resource/service/package_test.go new file mode 100644 index 000000000000..b1f110beb413 --- /dev/null +++ b/domain/resource/service/package_test.go @@ -0,0 +1,16 @@ +// Copyright 2024 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package service + +import ( + "testing" + + gc "gopkg.in/check.v1" +) + +//go:generate go run go.uber.org/mock/mockgen -typed -package service -destination package_mock_test.go github.com/juju/juju/domain/resource/service State,ResourceStoreGetter + +func TestPackage(t *testing.T) { + gc.TestingT(t) +} diff --git a/domain/application/service/resource.go b/domain/resource/service/resource.go similarity index 80% rename from domain/application/service/resource.go rename to domain/resource/service/resource.go index 0521b1bc99b4..a70bc4fd03d9 100644 --- a/domain/application/service/resource.go +++ b/domain/resource/service/resource.go @@ -8,19 +8,18 @@ import ( "fmt" "io" - "github.com/juju/errors" - coreapplication "github.com/juju/juju/core/application" + "github.com/juju/juju/core/logger" coreresource "github.com/juju/juju/core/resource" "github.com/juju/juju/core/resource/store" coreunit "github.com/juju/juju/core/unit" - applicationerrors "github.com/juju/juju/domain/application/errors" - "github.com/juju/juju/domain/application/resource" + "github.com/juju/juju/domain/resource" + resourceerrors "github.com/juju/juju/domain/resource/errors" charmresource "github.com/juju/juju/internal/charm/resource" ) // ResourceState describes retrieval and persistence methods for resource. -type ResourceState interface { +type State interface { // GetApplicationResourceID returns the ID of the application resource // specified by natural key of application and resource name. GetApplicationResourceID(ctx context.Context, args resource.GetApplicationResourceIDArgs) (coreresource.UUID, error) @@ -59,14 +58,43 @@ type ResourceStoreGetter interface { GetResourceStore(context.Context, charmresource.Type) (store.ResourceStore, error) } +// Service provides the API for working with resources. +type Service struct { + st State + logger logger.Logger + + resourceStoreGetter ResourceStoreGetter +} + +// NewService returns a new service reference wrapping the input state. +func NewService( + st State, + resourceStoreGetter ResourceStoreGetter, + logger logger.Logger, +) *Service { + // Note: + // The store for container image resources is really a DQLite table today. + // Using AddStore is a compromise to avoid injecting one service into + // another, as would happen if NewResourceStoreFactory had a second + // argument to provide a containerImageResourceStore. + resourceStoreGetter.AddStore( + charmresource.TypeContainerImage, + nil, + ) + return &Service{ + st: st, + logger: logger, + } +} + // GetApplicationResourceID returns the ID of the application resource specified by // natural key of application and resource name. // // The following error types can be expected to be returned: -// - application.ResourceNameNotValid if no resource name is provided in +// - resourceerrors.ResourceNameNotValid if no resource name is provided in // the args. // - errors.NotValid is returned if the application ID is not valid. -// - application.ResourceNotFound if no resource with name exists for +// - resourceerrors.ResourceNotFound if no resource with name exists for // given application. func (s *Service) GetApplicationResourceID( ctx context.Context, @@ -76,7 +104,7 @@ func (s *Service) GetApplicationResourceID( return "", fmt.Errorf("application id: %w", err) } if args.Name == "" { - return "", applicationerrors.ResourceNameNotValid + return "", resourceerrors.ResourceNameNotValid } return s.st.GetApplicationResourceID(ctx, args) } @@ -126,7 +154,7 @@ func (s *Service) GetResource( // - errors.NotValid is returned if the resource is not valid. // - errors.NotValid is returned if the RetrievedByType is unknown while // RetrievedBy has a value. -// - application.ApplicationNotFound if the specified application does +// - resourceerrors.ApplicationNotFound if the specified application does // not exist. func (s *Service) SetResource( ctx context.Context, @@ -137,7 +165,7 @@ func (s *Service) SetResource( } if args.SuppliedBy != "" && args.SuppliedByType == resource.Unknown { return resource.Resource{}, - fmt.Errorf("%w RetrievedByType cannot be unknown if RetrievedBy set", errors.NotValid) + fmt.Errorf("RetrievedByType cannot be unknown if RetrievedBy set: %w", resourceerrors.ArgumentNotValid) } if err := args.Resource.Validate(); err != nil { return resource.Resource{}, fmt.Errorf("resource: %w", err) @@ -150,10 +178,10 @@ func (s *Service) SetResource( // The following error types can be expected to be returned: // - [errors.NotValid] is returned if the unit UUID is not valid. // - [errors.NotValid] is returned if the resource UUID is not valid. -// - [errors.NotValid] is returned if the RetrievedByType is unknown while +// - [resourceerrors.ArgumentNotValid] is returned if the RetrievedByType is unknown while // RetrievedBy has a value. -// - [applicationerrors.ResourceNotFound] if the specified resource doesn't exist -// - [applicationerrors.UnitNotFound] if the specified unit doesn't exist +// - [resourceerrors.ResourceNotFound] if the specified resource doesn't exist +// - [resourceerrors.UnitNotFound] if the specified unit doesn't exist func (s *Service) SetUnitResource( ctx context.Context, args resource.SetUnitResourceArgs, @@ -166,7 +194,7 @@ func (s *Service) SetUnitResource( } if args.RetrievedBy != "" && args.RetrievedByType == resource.Unknown { return resource.SetUnitResourceResult{}, - fmt.Errorf("%w RetrievedByType cannot be unknown if RetrievedBy set", errors.NotValid) + fmt.Errorf("RetrievedByType cannot be unknown if RetrievedBy set: %w", resourceerrors.ArgumentNotValid) } return s.st.SetUnitResource(ctx, args) } @@ -175,7 +203,7 @@ func (s *Service) SetUnitResource( // // The following error types can be expected to be returned: // - errors.NotValid is returned if the resource.UUID is not valid. -// - application.ResourceNotFound if the specified resource does +// - resourceerrors.ResourceNotFound if the specified resource does // not exist. func (s *Service) OpenApplicationResource( ctx context.Context, @@ -196,9 +224,9 @@ func (s *Service) OpenApplicationResource( // The following error types can be returned: // - errors.NotValid is returned if the resource.UUID is not valid. // - errors.NotValid is returned if the unit UUID is not valid. -// - application.ResourceNotFound if the specified resource does +// - resourceerrors.ResourceNotFound if the specified resource does // not exist. -// - application.UnitNotFound if the specified unit does +// - resourceerrors.UnitNotFound if the specified unit does // not exist. func (s *Service) OpenUnitResource( ctx context.Context, @@ -221,9 +249,9 @@ func (s *Service) OpenUnitResource( // // The following error types can be expected to be returned: // - errors.NotValid is returned if the Application ID is not valid. -// - errors.NotValid is returned if LastPolled is zero. -// - errors.NotValid is returned if the length of Info is zero. -// - application.ApplicationNotFound if the specified application does +// - resourceerrors.ArgumentNotValid is returned if LastPolled is zero. +// - resourceerrors.ArgumentNotValid is returned if the length of Info is zero. +// - resourceerrors.ApplicationNotFound if the specified application does // not exist. func (s *Service) SetRepositoryResources( ctx context.Context, @@ -233,7 +261,7 @@ func (s *Service) SetRepositoryResources( return fmt.Errorf("application id: %w", err) } if len(args.Info) == 0 { - return fmt.Errorf("empty Info %w", errors.NotValid) + return fmt.Errorf("empty Info: %w", resourceerrors.ArgumentNotValid) } for _, info := range args.Info { if err := info.Validate(); err != nil { @@ -241,7 +269,7 @@ func (s *Service) SetRepositoryResources( } } if args.LastPolled.IsZero() { - return fmt.Errorf("zero LastPolled %w", errors.NotValid) + return fmt.Errorf("zero LastPolled: %w", resourceerrors.ArgumentNotValid) } return s.st.SetRepositoryResources(ctx, args) } diff --git a/domain/application/service/resource_test.go b/domain/resource/service/resource_test.go similarity index 91% rename from domain/application/service/resource_test.go rename to domain/resource/service/resource_test.go index 302b43c4aa68..2266c1bf2432 100644 --- a/domain/application/service/resource_test.go +++ b/domain/resource/service/resource_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/juju/errors" + jujutesting "github.com/juju/testing" jc "github.com/juju/testing/checkers" "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" @@ -15,13 +16,19 @@ import ( applicationtesting "github.com/juju/juju/core/application/testing" resourcestesting "github.com/juju/juju/core/resource/testing" unittesting "github.com/juju/juju/core/unit/testing" - applicationerrors "github.com/juju/juju/domain/application/errors" - "github.com/juju/juju/domain/application/resource" + "github.com/juju/juju/domain/resource" + resourceerrors "github.com/juju/juju/domain/resource/errors" charmresource "github.com/juju/juju/internal/charm/resource" + loggertesting "github.com/juju/juju/internal/logger/testing" ) type resourceServiceSuite struct { - baseSuite + jujutesting.IsolationSuite + + state *MockState + resourceStoreGetter *MockResourceStoreGetter + + service *Service } var _ = gc.Suite(&resourceServiceSuite{}) @@ -60,7 +67,7 @@ func (s *resourceServiceSuite) TestGetApplicationResourceIDBadName(c *gc.C) { Name: "", } _, err := s.service.GetApplicationResourceID(context.Background(), args) - c.Assert(err, jc.ErrorIs, applicationerrors.ResourceNameNotValid) + c.Assert(err, jc.ErrorIs, resourceerrors.ResourceNameNotValid) } func (s *resourceServiceSuite) TestListResources(c *gc.C) { @@ -236,7 +243,6 @@ func (s *resourceServiceSuite) TestOpenUnitResource(c *gc.C) { obtainedRes, _, err := s.service.OpenUnitResource(context.Background(), resourceID, unitID) c.Assert(err, jc.ErrorIsNil) c.Assert(obtainedRes, gc.DeepEquals, obtainedRes) - } func (s *resourceServiceSuite) TestOpenUnitResourceBadUnitID(c *gc.C) { @@ -256,6 +262,7 @@ func (s *resourceServiceSuite) TestOpenUnitResourceBadResourceID(c *gc.C) { func (s *resourceServiceSuite) TestSetRepositoryResources(c *gc.C) { defer s.setupMocks(c).Finish() + fp, err := charmresource.NewFingerprint(fingerprint) c.Assert(err, jc.ErrorIsNil) args := resource.SetRepositoryResourcesArgs{ @@ -280,3 +287,15 @@ func (s *resourceServiceSuite) TestSetRepositoryResources(c *gc.C) { err = s.service.SetRepositoryResources(context.Background(), args) c.Assert(err, jc.ErrorIsNil) } + +func (s *resourceServiceSuite) setupMocks(c *gc.C) *gomock.Controller { + ctrl := gomock.NewController(c) + + s.state = NewMockState(ctrl) + s.resourceStoreGetter = NewMockResourceStoreGetter(ctrl) + s.resourceStoreGetter.EXPECT().AddStore(charmresource.TypeContainerImage, gomock.Any()) + + s.service = NewService(s.state, s.resourceStoreGetter, loggertesting.WrapCheckLog(c)) + + return ctrl +} diff --git a/domain/resource/state/package_test.go b/domain/resource/state/package_test.go new file mode 100644 index 000000000000..689a9b62b547 --- /dev/null +++ b/domain/resource/state/package_test.go @@ -0,0 +1,14 @@ +// Copyright 2024 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package state + +import ( + "testing" + + gc "gopkg.in/check.v1" +) + +func TestPackage(t *testing.T) { + gc.TestingT(t) +} diff --git a/domain/application/state/resource.go b/domain/resource/state/resource.go similarity index 90% rename from domain/application/state/resource.go rename to domain/resource/state/resource.go index 0a6b26db3ba7..82873dbc5e6a 100644 --- a/domain/application/state/resource.go +++ b/domain/resource/state/resource.go @@ -11,17 +11,36 @@ import ( "time" "github.com/canonical/sqlair" + "github.com/juju/clock" "github.com/juju/collections/set" "github.com/juju/juju/core/application" + "github.com/juju/juju/core/database" + "github.com/juju/juju/core/logger" coreresource "github.com/juju/juju/core/resource" coreunit "github.com/juju/juju/core/unit" - apperrors "github.com/juju/juju/domain/application/errors" - "github.com/juju/juju/domain/application/resource" + "github.com/juju/juju/domain" + "github.com/juju/juju/domain/resource" + resourceerrors "github.com/juju/juju/domain/resource/errors" charmresource "github.com/juju/juju/internal/charm/resource" "github.com/juju/juju/internal/errors" ) +type State struct { + *domain.StateBase + clock clock.Clock + logger logger.Logger +} + +// NewState returns a new state reference. +func NewState(factory database.TxnRunnerFactory, clock clock.Clock, logger logger.Logger) *State { + return &State{ + StateBase: domain.NewStateBase(factory), + clock: clock, + logger: logger, + } +} + // GetApplicationResourceID returns the ID of the application resource // specified by natural key of application and resource name. func (st *State) GetApplicationResourceID( @@ -55,7 +74,7 @@ AND application_uuid = $resourceIdentity.application_uuid err = db.Txn(ctx, func(ctx context.Context, tx *sqlair.TX) error { err := tx.Query(ctx, stmt, resource).Get(&resource) if errors.Is(err, sqlair.ErrNoRows) { - return apperrors.ResourceNotFound + return resourceerrors.ResourceNotFound } return errors.Capture(err) }) @@ -182,7 +201,7 @@ WHERE unit_resource.resource_uuid = $resourceIdentity.uuid` } // GetResource returns the identified resource. -// Returns a [apperrors.ResourceNotFound] if no such resource exists. +// Returns a [resourceerrors.ResourceNotFound] if no such resource exists. func (st *State) GetResource(ctx context.Context, resourceUUID coreresource.UUID) (resource.Resource, error) { db, err := st.DB() @@ -206,7 +225,7 @@ WHERE uuid = $resourceIdentity.uuid`, err = db.Txn(ctx, func(ctx context.Context, tx *sqlair.TX) error { err := tx.Query(ctx, stmt, resourceParam).Get(&resourceOutput) if errors.Is(err, sqlair.ErrNoRows) { - return apperrors.ResourceNotFound + return resourceerrors.ResourceNotFound } return errors.Capture(err) }) @@ -226,8 +245,8 @@ func (st *State) SetResource( } // SetUnitResource sets the resource metadata for a specific unit. -// Returns [apperrors.UnitNotFound] if the unit id doesn't belong to an existing unit. -// Returns [apperrors.ResourceNotFound] if the resource id doesn't belong to an existing resource. +// Returns [resourceerrors.UnitNotFound] if the unit id doesn't belong to an existing unit. +// Returns [resourceerrors.ResourceNotFound] if the resource id doesn't belong to an existing resource. func (st *State) SetUnitResource( ctx context.Context, config resource.SetUnitResourceArgs, @@ -335,14 +354,14 @@ VALUES ($unitResource.*)` // Check resource and unit exists. err = tx.Query(ctx, checkValidResourceStmt, resourceUUID).Get(&resourceUUID) if errors.Is(err, sqlair.ErrNoRows) { - return errors.Errorf("resource %s: %w", resourceUUID.UUID, apperrors.ResourceNotFound) + return errors.Errorf("resource %s: %w", resourceUUID.UUID, resourceerrors.ResourceNotFound) } if err != nil { return errors.Capture(err) } err = tx.Query(ctx, checkValidUnitStmt, unitUUID).Get(&unitUUID) if errors.Is(err, sqlair.ErrNoRows) { - return errors.Errorf("resource %s: %w", unitUUID.UnitUUID, apperrors.UnitNotFound) + return errors.Errorf("resource %s: %w", unitUUID.UnitUUID, resourceerrors.UnitNotFound) } if err != nil { return errors.Capture(err) @@ -358,7 +377,7 @@ VALUES ($unitResource.*)` if errors.Is(err, sqlair.ErrNoRows) { err = tx.Query(ctx, getRetrievedByTypeStmt, retrievedTypeParam).Get(&retrievedTypeParam) if errors.Is(err, sqlair.ErrNoRows) { - return apperrors.UnknownRetrievedByType + return resourceerrors.UnknownRetrievedByType } if err != nil { return errors.Capture(err) @@ -405,7 +424,7 @@ func (st *State) OpenUnitResource( // SetRepositoryResources sets the "polled" resources for the // application to the provided values. The current data for this // application/resource combination will be overwritten. -// Returns [apperrors.ApplicationNotFound] if the application id doesn't belong to a valid application. +// Returns [resourceerrors.ApplicationNotFound] if the application id doesn't belong to a valid application. func (st *State) SetRepositoryResources( ctx context.Context, config resource.SetRepositoryResourcesArgs, @@ -416,15 +435,15 @@ func (st *State) SetRepositoryResources( } // Prepare statement to check that the application exists. - appDetails := applicationDetails{ + appNameAndID := applicationNameAndID{ ApplicationID: config.ApplicationID, } getAppNameQuery := ` -SELECT name as &applicationDetails.name +SELECT name as &applicationNameAndID.name FROM application -WHERE uuid = $applicationDetails.uuid +WHERE uuid = $applicationNameAndID.uuid ` - getAppNameStmt, err := st.Prepare(getAppNameQuery, appDetails) + getAppNameStmt, err := st.Prepare(getAppNameQuery, appNameAndID) if err != nil { return errors.Capture(err) } @@ -465,9 +484,9 @@ WHERE uuid = $lastPolledResource.uuid var resIdentities []resourceIdentity err = db.Txn(ctx, func(ctx context.Context, tx *sqlair.TX) error { // Check application exists. - err := tx.Query(ctx, getAppNameStmt, appDetails).Get(&appDetails) + err := tx.Query(ctx, getAppNameStmt, appNameAndID).Get(&appNameAndID) if errors.Is(err, sqlair.ErrNoRows) { - return apperrors.ApplicationNotFound + return resourceerrors.ApplicationNotFound } if err != nil { return errors.Capture(err) @@ -485,7 +504,7 @@ WHERE uuid = $lastPolledResource.uuid foundResources.Add(res.Name) } st.logger.Errorf("Resource not found for application %s (%s), missing: %s", - appDetails.Name, config.ApplicationID, set.NewStrings(names...).Difference(foundResources).Values()) + appNameAndID.Name, config.ApplicationID, set.NewStrings(names...).Difference(foundResources).Values()) } // Update last polled resources. diff --git a/domain/application/state/resource_test.go b/domain/resource/state/resource_test.go similarity index 98% rename from domain/application/state/resource_test.go rename to domain/resource/state/resource_test.go index 7e9b664684a1..4d4356f5deb8 100644 --- a/domain/application/state/resource_test.go +++ b/domain/resource/state/resource_test.go @@ -16,8 +16,8 @@ import ( "github.com/juju/juju/core/application" coreresources "github.com/juju/juju/core/resource" "github.com/juju/juju/core/unit" - apperrors "github.com/juju/juju/domain/application/errors" - "github.com/juju/juju/domain/application/resource" + "github.com/juju/juju/domain/resource" + resourceerrors "github.com/juju/juju/domain/resource/errors" schematesting "github.com/juju/juju/domain/schema/testing" charmresource "github.com/juju/juju/internal/charm/resource" "github.com/juju/juju/internal/errors" @@ -127,7 +127,7 @@ func (s *resourceSuite) TestGetApplicationResourceIDNotFound(c *gc.C) { ApplicationID: application.ID(s.constants.fakeApplicationUUID1), Name: "resource-name-not-found", }) - c.Assert(err, jc.ErrorIs, apperrors.ResourceNotFound, gc.Commentf("(Act) unexpected error")) + c.Assert(err, jc.ErrorIs, resourceerrors.ResourceNotFound, gc.Commentf("(Act) unexpected error")) } // TestGetResourceNotFound verifies that attempting to retrieve a non-existent @@ -140,7 +140,7 @@ func (s *resourceSuite) TestGetResourceNotFound(c *gc.C) { _, err := s.state.GetResource(context.Background(), resID) // Assert - c.Assert(err, jc.ErrorIs, apperrors.ResourceNotFound, gc.Commentf("(Assert) unexpected error")) + c.Assert(err, jc.ErrorIs, resourceerrors.ResourceNotFound, gc.Commentf("(Assert) unexpected error")) } // TestGetResource verifies the successful retrieval of a resource from the @@ -331,7 +331,7 @@ func (s *resourceSuite) TestSetRepositoryResourceApplicationNotFound(c *gc.C) { }) // Assert: check expected error - c.Assert(err, jc.ErrorIs, apperrors.ApplicationNotFound, gc.Commentf("(Act) unexpected error: %v", errors.ErrorStack(err))) + c.Assert(err, jc.ErrorIs, resourceerrors.ApplicationNotFound, gc.Commentf("(Act) unexpected error: %v", errors.ErrorStack(err))) } // TestSetUnitResourceNotYetSupplied verifies that a unit resource is correctly @@ -511,7 +511,7 @@ func (s *resourceSuite) TestSetUnitResourceNotYetSuppliedExistingSupplierWrongTy }) // Assert: an error is returned, nothing is updated in the db - c.Check(err, jc.ErrorIs, apperrors.UnknownRetrievedByType) + c.Check(err, jc.ErrorIs, resourceerrors.UnknownRetrievedByType) err = s.TxnRunner().StdTxn(context.Background(), func(ctx context.Context, tx *sql.Tx) error { var discard string err = tx.QueryRow(`SELECT * FROM unit_resource`).Scan(&discard) @@ -539,7 +539,7 @@ func (s *resourceSuite) TestSetUnitResourceNotFound(c *gc.C) { }) // Assert: an error is returned, nothing is updated in the db - c.Check(err, jc.ErrorIs, apperrors.ResourceNotFound) + c.Check(err, jc.ErrorIs, resourceerrors.ResourceNotFound) err = s.TxnRunner().StdTxn(context.Background(), func(ctx context.Context, tx *sql.Tx) error { var discard string err = tx.QueryRow(`SELECT * FROM unit_resource`).Scan(&discard) @@ -576,7 +576,7 @@ func (s *resourceSuite) TestSetUnitResourceUnitNotFound(c *gc.C) { }) // Assert: an error is returned, nothing is updated in the db - c.Check(err, jc.ErrorIs, apperrors.UnitNotFound) + c.Check(err, jc.ErrorIs, resourceerrors.UnitNotFound) err = s.TxnRunner().StdTxn(context.Background(), func(ctx context.Context, tx *sql.Tx) error { var discard string err = tx.QueryRow(`SELECT * FROM unit_resource`).Scan(&discard) diff --git a/domain/resource/state/types.go b/domain/resource/state/types.go new file mode 100644 index 000000000000..812b9fbaca95 --- /dev/null +++ b/domain/resource/state/types.go @@ -0,0 +1,84 @@ +// Copyright 2024 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package state + +import ( + "time" + + coreapplication "github.com/juju/juju/core/application" + coreresource "github.com/juju/juju/core/resource" + coreunit "github.com/juju/juju/core/unit" + "github.com/juju/juju/domain/resource" + charmresource "github.com/juju/juju/internal/charm/resource" +) + +// resourceIdentity represents the unique identity of a resource within an application. +type resourceIdentity struct { + UUID string `db:"uuid"` + ApplicationUUID string `db:"application_uuid"` + Name string `db:"name"` +} + +// resourceView represents the view model for a resource entity. It contains +// all fields from v_resource table view +type resourceView struct { + UUID string `db:"uuid"` + ApplicationUUID string `db:"application_uuid"` + Name string `db:"name"` + CreatedAt time.Time `db:"created_at"` + Revision int `db:"revision"` + OriginTypeId int `db:"origin_type_id"` + RetrievedBy string `db:"retrieved_by"` + RetrievedByType string `db:"retrieved_by_type"` + Path string `db:"path"` + Description string `db:"description"` + KindId int `db:"kind_id"` +} + +// toCharmResource converts the resourceView struct to a charmresource.Resource, populating its fields accordingly. +func (rv resourceView) toCharmResource() charmresource.Resource { + return charmresource.Resource{ + Meta: charmresource.Meta{ + Name: rv.Name, + Type: charmresource.Type(rv.KindId), + Path: rv.Path, + Description: rv.Description, + }, + Origin: charmresource.Origin(rv.OriginTypeId), + Revision: rv.Revision, + // todo(gfouillet): deal with fingerprint & size + Fingerprint: charmresource.Fingerprint{}, + Size: 0, + } +} + +// toResource converts a resourceView object to a resource.Resource object including metadata and timestamps. +func (rv resourceView) toResource() resource.Resource { + return resource.Resource{ + Resource: rv.toCharmResource(), + UUID: coreresource.UUID(rv.UUID), + ApplicationID: coreapplication.ID(rv.ApplicationUUID), + RetrievedBy: rv.RetrievedBy, + RetrievedByType: resource.RetrievedByType(rv.RetrievedByType), + Timestamp: rv.CreatedAt, + } +} + +// unitResource represents the mapping of a resource to a unit. +type unitResource struct { + ResourceUUID string `db:"resource_uuid"` + UnitUUID string `db:"unit_uuid"` + AddedAt time.Time `db:"added_at"` +} + +// unitNameAndUUID store the name & uuid of a unit +type unitNameAndUUID struct { + UnitUUID coreunit.UUID `db:"uuid"` + Name coreunit.Name `db:"name"` +} + +type applicationNameAndID struct { + ApplicationID coreapplication.ID `db:"uuid"` + Name string `db:"name"` +} diff --git a/domain/application/resource/types.go b/domain/resource/types.go similarity index 100% rename from domain/application/resource/types.go rename to domain/resource/types.go diff --git a/domain/secret/service_test.go b/domain/secret/service_test.go index 2883bb3a78a7..4ffdfb4ef638 100644 --- a/domain/secret/service_test.go +++ b/domain/secret/service_test.go @@ -84,14 +84,6 @@ func (noopSecretDeleter) DeleteSecret(ctx domain.AtomicContext, uri *coresecrets return nil } -type noopResourceStoreGetter struct{} - -func (noopResourceStoreGetter) AddStore(t charmresource.Type, store store.ResourceStore) {} - -func (noopResourceStoreGetter) GetResourceStore(context.Context, charmresource.Type) (store.ResourceStore, error) { - return nil, nil -} - func (s *serviceSuite) createSecret(c *gc.C, data map[string]string, valueRef *coresecrets.ValueRef) *coresecrets.URI { ctx := context.Background() state := applicationstate.NewState(func() (database.TxnRunner, error) { @@ -105,7 +97,6 @@ func (s *serviceSuite) createSecret(c *gc.C, data map[string]string, valueRef *c return storage.NotImplementedProviderRegistry{} }), nil, - noopResourceStoreGetter{}, clock.WallClock, loggertesting.WrapCheckLog(c), ) diff --git a/domain/services/model.go b/domain/services/model.go index 82b9505e7707..75752efd2ddf 100644 --- a/domain/services/model.go +++ b/domain/services/model.go @@ -50,6 +50,8 @@ import ( portservice "github.com/juju/juju/domain/port/service" portstate "github.com/juju/juju/domain/port/state" proxy "github.com/juju/juju/domain/proxy/service" + resourceservice "github.com/juju/juju/domain/resource/service" + resourcestate "github.com/juju/juju/domain/resource/state" secretservice "github.com/juju/juju/domain/secret/service" secretstate "github.com/juju/juju/domain/secret/state" secretbackendservice "github.com/juju/juju/domain/secretbackend/service" @@ -174,7 +176,6 @@ func (s *ModelServices) Application() *applicationservice.WatchableService { applicationstate.NewState(changestream.NewTxnRunnerFactory(s.modelDB), s.clock, log), secretstate.NewState(changestream.NewTxnRunnerFactory(s.modelDB), log), s.storageRegistry, - store.NewResourceStoreFactory(s.objectstore), s.modelUUID, s.modelWatcherFactory("application"), modelagentstate.NewState(changestream.NewTxnRunnerFactory(s.controllerDB)), @@ -341,6 +342,20 @@ func (s *ModelServices) BlockCommand() *blockcommandservice.Service { ) } +// Resource returns the service for persisting and retrieving application +// resources for the current model. +func (s *ModelServices) Resource() *resourceservice.Service { + return resourceservice.NewService( + resourcestate.NewState( + changestream.NewTxnRunnerFactory(s.modelDB), + s.clock, + s.logger.Child("resource.state"), + ), + store.NewResourceStoreFactory(s.objectstore), + s.logger.Child("resource.service"), + ) +} + // Stub returns the stub service. A special service which collects temporary // methods required to wire together domains which are not completely implemented // or wired up.