[full-ci] enhancement: use reva client pool selectors (#6452)

* enhancement: use reva client pool selectors

register mock service to registry and pass tests

* enhancement: bump reva

* Fix a couple of linter issues

---------

Co-authored-by: Ralf Haferkamp <rhaferkamp@owncloud.com>
This commit is contained in:
Florian Schade
2023-06-08 12:41:04 +02:00
committed by GitHub
co-authored by Ralf Haferkamp
parent 021c9fcdd9
commit 4f26424db6
157 changed files with 2845 additions and 1901 deletions
+15 -17
View File
@@ -11,7 +11,7 @@ import (
"github.com/gofrs/uuid"
"github.com/oklog/run"
"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
"github.com/owncloud/ocis/v2/ocis-pkg/service/external"
"github.com/owncloud/ocis/v2/ocis-pkg/registry"
"github.com/owncloud/ocis/v2/ocis-pkg/sync"
"github.com/owncloud/ocis/v2/ocis-pkg/version"
"github.com/owncloud/ocis/v2/services/storage-users/pkg/config"
@@ -44,12 +44,16 @@ func Server(cfg *config.Config) *cli.Command {
defer cancel()
pidFile := path.Join(os.TempDir(), "revad-"+cfg.Service.Name+"-"+uuid.Must(uuid.NewV4()).String()+".pid")
rcfg := revaconfig.StorageUsersConfigFromStruct(cfg)
gr.Add(func() error {
runtime.RunWithOptions(rcfg, pidFile, runtime.WithLogger(&logger.Logger))
pidFile := path.Join(os.TempDir(), "revad-"+cfg.Service.Name+"-"+uuid.Must(uuid.NewV4()).String()+".pid")
rCfg := revaconfig.StorageUsersConfigFromStruct(cfg)
reg := registry.GetRegistry()
runtime.RunWithOptions(rCfg, pidFile,
runtime.WithLogger(&logger.Logger),
runtime.WithRegistry(reg),
)
return nil
}, func(err error) {
logger.Error().
@@ -79,15 +83,9 @@ func Server(cfg *config.Config) *cli.Command {
sync.Trap(&gr, cancel)
}
if err := external.RegisterGRPCEndpoint(
ctx,
cfg.GRPC.Namespace+"."+cfg.Service.Name,
uuid.Must(uuid.NewV4()).String(),
cfg.GRPC.Addr,
version.GetString(),
logger,
); err != nil {
logger.Fatal().Err(err).Msg("failed to register the grpc endpoint")
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, uuid.Must(uuid.NewV4()).String(), cfg.GRPC.Addr, version.GetString())
if err := registry.RegisterService(ctx, grpcSvc, logger); err != nil {
logger.Fatal().Err(err).Msg("failed to register the grpc service")
}
{
@@ -96,12 +94,12 @@ func Server(cfg *config.Config) *cli.Command {
logger.Fatal().Err(err).Msg("can't connect to nats")
}
gw, err := pool.GetGatewayServiceClient(cfg.Reva.Address)
selector, err := pool.GatewaySelector(cfg.Reva.Address, pool.WithRegistry(registry.GetRegistry()))
if err != nil {
return err
}
eventSVC, err := event.NewService(gw, stream, logger, *cfg)
eventSVC, err := event.NewService(selector, stream, logger, *cfg)
if err != nil {
logger.Fatal().Err(err).Msg("can't create event service")
}
@@ -58,7 +58,7 @@ func DefaultConfig() *config.Config {
DBHost: "",
DBPort: 3306,
DBName: "owncloud",
UsersProviderEndpoint: "localhost:9144",
UsersProviderEndpoint: "com.owncloud.api.users",
},
S3NG: config.S3NGDriver{
MetadataBackend: "messagepack",
@@ -68,7 +68,7 @@ func DefaultConfig() *config.Config {
Region: "default",
PersonalSpaceAliasTemplate: "{{.SpaceType}}/{{.User.Username | lower}}",
GeneralSpaceAliasTemplate: "{{.SpaceType}}/{{.SpaceName | replace \" \" \"-\" | lower}}",
PermissionsEndpoint: "127.0.0.1:9191",
PermissionsEndpoint: "com.owncloud.api.settings",
MaxAcquireLockCycles: 20,
LockCycleDurationFactor: 30,
},
@@ -79,7 +79,7 @@ func DefaultConfig() *config.Config {
UserLayout: "{{.Id.OpaqueId}}",
PersonalSpaceAliasTemplate: "{{.SpaceType}}/{{.User.Username | lower}}",
GeneralSpaceAliasTemplate: "{{.SpaceType}}/{{.SpaceName | replace \" \" \"-\" | lower}}",
PermissionsEndpoint: "127.0.0.1:9191",
PermissionsEndpoint: "com.owncloud.api.settings",
MaxAcquireLockCycles: 20,
LockCycleDurationFactor: 30,
},
+11 -10
View File
@@ -6,6 +6,7 @@ import (
apiGateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
apiUser "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
"github.com/cs3org/reva/v2/pkg/events"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/services/storage-users/pkg/config"
"github.com/owncloud/ocis/v2/services/storage-users/pkg/task"
@@ -17,19 +18,19 @@ const (
// Service wraps all common logic that is needed to react to incoming events.
type Service struct {
gatewayClient apiGateway.GatewayAPIClient
eventStream events.Stream
logger log.Logger
config config.Config
gatewaySelector pool.Selectable[apiGateway.GatewayAPIClient]
eventStream events.Stream
logger log.Logger
config config.Config
}
// NewService prepares and returns a Service implementation.
func NewService(gatewayClient apiGateway.GatewayAPIClient, eventStream events.Stream, logger log.Logger, conf config.Config) (Service, error) {
func NewService(gatewaySelector pool.Selectable[apiGateway.GatewayAPIClient], eventStream events.Stream, logger log.Logger, conf config.Config) (Service, error) {
svc := Service{
gatewayClient: gatewayClient,
eventStream: eventStream,
logger: logger,
config: conf,
gatewaySelector: gatewaySelector,
eventStream: eventStream,
logger: logger,
config: conf,
}
return svc, nil
@@ -69,7 +70,7 @@ func (s Service) Run() error {
continue
}
if err = task.PurgeTrashBin(executantID, deleteBefore, spaceType, s.gatewayClient, s.config.Commons.MachineAuthAPIKey); err != nil {
if err = task.PurgeTrashBin(executantID, deleteBefore, spaceType, s.gatewaySelector, s.config.Commons.MachineAuthAPIKey); err != nil {
errs = append(errs, err)
}
}
@@ -3,10 +3,23 @@ package task_test
import (
"testing"
"github.com/owncloud/ocis/v2/ocis-pkg/registry"
mRegistry "go-micro.dev/v4/registry"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func init() {
registry.Configure("memory")
r := registry.GetRegistry()
service := registry.BuildGRPCService("com.owncloud.api.gateway", "", "", "")
service.Nodes = []*mRegistry.Node{{
Address: "any",
}}
_ = r.Register(service)
}
func TestTask(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Task Suite")
+12 -6
View File
@@ -9,6 +9,7 @@ import (
apiRpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
apiProvider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/v2/pkg/errtypes"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/utils"
)
@@ -16,13 +17,18 @@ import (
// the provided executantID must have space access.
// removeBefore specifies how long an item must be in the trash-bin to be deleted,
// items that stay there for a shorter time are ignored and kept in place.
func PurgeTrashBin(executantID *apiUser.UserId, deleteBefore time.Time, spaceType SpaceType, gwc apiGateway.GatewayAPIClient, machineAuthAPIKey string) error {
executantCtx, _, err := utils.Impersonate(executantID, gwc, machineAuthAPIKey)
func PurgeTrashBin(executantID *apiUser.UserId, deleteBefore time.Time, spaceType SpaceType, gatewaySelector pool.Selectable[apiGateway.GatewayAPIClient], machineAuthAPIKey string) error {
gatewayClient, err := gatewaySelector.Next()
if err != nil {
return err
}
listStorageSpacesResponse, err := gwc.ListStorageSpaces(executantCtx, &apiProvider.ListStorageSpacesRequest{
executantCtx, _, err := utils.Impersonate(executantID, gatewayClient, machineAuthAPIKey)
if err != nil {
return err
}
listStorageSpacesResponse, err := gatewayClient.ListStorageSpaces(executantCtx, &apiProvider.ListStorageSpacesRequest{
Filters: []*apiProvider.ListStorageSpacesRequest_Filter{
{
Type: apiProvider.ListStorageSpacesRequest_Filter_TYPE_SPACE_TYPE,
@@ -77,12 +83,12 @@ func PurgeTrashBin(executantID *apiUser.UserId, deleteBefore time.Time, spaceTyp
return fmt.Errorf("can't impersonate space user for space: %s", storageSpace.GetId().GetOpaqueId())
}
impersonatedCtx, _, err := utils.Impersonate(impersonationID, gwc, machineAuthAPIKey)
impersonatedCtx, _, err := utils.Impersonate(impersonationID, gatewayClient, machineAuthAPIKey)
if err != nil {
return err
}
listRecycleResponse, err := gwc.ListRecycle(impersonatedCtx, &apiProvider.ListRecycleRequest{Ref: storageSpaceReference})
listRecycleResponse, err := gatewayClient.ListRecycle(impersonatedCtx, &apiProvider.ListRecycleRequest{Ref: storageSpaceReference})
if err != nil {
return err
}
@@ -93,7 +99,7 @@ func PurgeTrashBin(executantID *apiUser.UserId, deleteBefore time.Time, spaceTyp
continue
}
purgeRecycleResponse, err := gwc.PurgeRecycle(impersonatedCtx, &apiProvider.PurgeRecycleRequest{
purgeRecycleResponse, err := gatewayClient.PurgeRecycle(impersonatedCtx, &apiProvider.PurgeRecycleRequest{
Ref: storageSpaceReference,
Key: recycleItem.Key,
})
@@ -4,21 +4,23 @@ import (
"context"
"encoding/json"
"errors"
"google.golang.org/grpc"
"time"
apiGateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
apiUser "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
apiRpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
apiProvider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
apiTypes "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva/v2/pkg/rgrpc/status"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/utils"
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/owncloud/ocis/v2/services/storage-users/pkg/task"
"github.com/stretchr/testify/mock"
"google.golang.org/grpc"
)
func MustMarshal(v any) []byte {
@@ -31,7 +33,8 @@ func MustMarshal(v any) []byte {
var _ = Describe("trash", func() {
var (
gwc *cs3mocks.GatewayAPIClient
gatewayClient *cs3mocks.GatewayAPIClient
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
ctx context.Context
now time.Time
genericError error
@@ -45,7 +48,16 @@ var _ = Describe("trash", func() {
)
BeforeEach(func() {
gwc = &cs3mocks.GatewayAPIClient{}
pool.RemoveSelector("GatewaySelector" + "com.owncloud.api.gateway")
gatewayClient = &cs3mocks.GatewayAPIClient{}
gatewaySelector = pool.GetSelector[gateway.GatewayAPIClient](
"GatewaySelector",
"com.owncloud.api.gateway",
func(cc *grpc.ClientConn) gateway.GatewayAPIClient {
return gatewayClient
},
)
ctx = context.Background()
now = time.Now()
genericError = errors.New("any")
@@ -100,36 +112,36 @@ var _ = Describe("trash", func() {
Describe("PurgeTrashBin", func() {
It("throws an error if the user cannot authenticate", func() {
gwc.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gwc.On("Authenticate", mock.Anything, mock.Anything).Return(nil, genericError)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("Authenticate", mock.Anything, mock.Anything).Return(nil, genericError)
err := task.PurgeTrashBin(user.Id, now, task.Project, gwc, "")
err := task.PurgeTrashBin(user.Id, now, task.Project, gatewaySelector, "")
Expect(err).To(HaveOccurred())
})
It("throws an error if space listing fails", func() {
gwc.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gwc.On("Authenticate", mock.Anything, mock.Anything).Return(authenticateResponse, nil)
gwc.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(nil, genericError)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("Authenticate", mock.Anything, mock.Anything).Return(authenticateResponse, nil)
gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(nil, genericError)
err := task.PurgeTrashBin(user.Id, now, task.Project, gwc, "")
err := task.PurgeTrashBin(user.Id, now, task.Project, gatewaySelector, "")
Expect(err).To(HaveOccurred())
})
It("throws an error if a personal space user can't be impersonated", func() {
listStorageSpacesResponse.StorageSpaces = []*apiProvider.StorageSpace{personalSpace}
gwc.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gwc.On("Authenticate", mock.Anything, mock.Anything).Return(authenticateResponse, nil)
gwc.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(listStorageSpacesResponse, nil)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("Authenticate", mock.Anything, mock.Anything).Return(authenticateResponse, nil)
gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(listStorageSpacesResponse, nil)
err := task.PurgeTrashBin(user.Id, now, task.Project, gwc, "")
err := task.PurgeTrashBin(user.Id, now, task.Project, gatewaySelector, "")
Expect(err).To(MatchError(errors.New("can't impersonate space user for space: personal")))
})
It("throws an error if a project space user can't be impersonated", func() {
listStorageSpacesResponse.StorageSpaces = []*apiProvider.StorageSpace{projectSpace}
gwc.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gwc.On("Authenticate", mock.Anything, mock.Anything).Return(authenticateResponse, nil)
gwc.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(listStorageSpacesResponse, nil)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("Authenticate", mock.Anything, mock.Anything).Return(authenticateResponse, nil)
gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(listStorageSpacesResponse, nil)
err := task.PurgeTrashBin(user.Id, now, task.Project, gwc, "")
err := task.PurgeTrashBin(user.Id, now, task.Project, gatewaySelector, "")
Expect(err).To(MatchError(errors.New("can't impersonate space user for space: project")))
})
It("throws an error if a project space has no user with delete permissions", func() {
@@ -143,11 +155,11 @@ var _ = Describe("trash", func() {
}),
},
}
gwc.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gwc.On("Authenticate", mock.Anything, mock.Anything).Return(authenticateResponse, nil)
gwc.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(listStorageSpacesResponse, nil)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("Authenticate", mock.Anything, mock.Anything).Return(authenticateResponse, nil)
gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(listStorageSpacesResponse, nil)
err := task.PurgeTrashBin(user.Id, now, task.Project, gwc, "")
err := task.PurgeTrashBin(user.Id, now, task.Project, gatewaySelector, "")
Expect(err).To(MatchError(errors.New("can't impersonate space user for space: project")))
})
It("only deletes items older than the specified period", func() {
@@ -188,17 +200,17 @@ var _ = Describe("trash", func() {
},
}
gwc.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gwc.On("Authenticate", mock.Anything, mock.Anything).Return(authenticateResponse, nil)
gwc.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(listStorageSpacesResponse, nil)
gwc.On("ListRecycle", mock.Anything, mock.Anything).Return(
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("Authenticate", mock.Anything, mock.Anything).Return(authenticateResponse, nil)
gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(listStorageSpacesResponse, nil)
gatewayClient.On("ListRecycle", mock.Anything, mock.Anything).Return(
func(_ context.Context, req *apiProvider.ListRecycleRequest, _ ...grpc.CallOption) *apiProvider.ListRecycleResponse {
return &apiProvider.ListRecycleResponse{
RecycleItems: recycleItems[req.Ref.ResourceId.OpaqueId],
}
}, nil,
)
gwc.On("PurgeRecycle", mock.Anything, mock.Anything).Return(
gatewayClient.On("PurgeRecycle", mock.Anything, mock.Anything).Return(
func(_ context.Context, req *apiProvider.PurgeRecycleRequest, _ ...grpc.CallOption) *apiProvider.PurgeRecycleResponse {
var items []*apiProvider.RecycleItem
for _, item := range recycleItems[req.Ref.ResourceId.OpaqueId] {
@@ -219,7 +231,7 @@ var _ = Describe("trash", func() {
}, nil,
)
err := task.PurgeTrashBin(user.Id, now, task.Project, gwc, "")
err := task.PurgeTrashBin(user.Id, now, task.Project, gatewaySelector, "")
Expect(err).To(BeNil())
Expect(recycleItems["personal"]).To(HaveLen(2))
Expect(recycleItems["project"]).To(HaveLen(2))