[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
+16 -15
View File
@@ -5,12 +5,12 @@ import (
"net/url"
"github.com/CiscoM31/godata"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
cs3group "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
cs3user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
cs3rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
libregraph "github.com/owncloud/libre-graph-api-go"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
@@ -21,8 +21,9 @@ var (
)
type CS3 struct {
Config *shared.Reva
Logger *log.Logger
Config *shared.Reva
Logger *log.Logger
GatewaySelector pool.Selectable[gateway.GatewayAPIClient]
}
// CreateUser implements the Backend Interface. It's currently not supported for the CS3 backend
@@ -44,13 +45,13 @@ func (i *CS3) UpdateUser(ctx context.Context, nameOrID string, user libregraph.U
func (i *CS3) GetUser(ctx context.Context, userID string, _ *godata.GoDataRequest) (*libregraph.User, error) {
logger := i.Logger.SubloggerWithRequestID(ctx)
logger.Debug().Str("backend", "cs3").Msg("GetUser")
client, err := pool.GetGatewayServiceClient(i.Config.Address, i.Config.GetRevaOptions()...)
gatewayClient, err := i.GatewaySelector.Next()
if err != nil {
logger.Error().Str("backend", "cs3").Err(err).Msg("could not get client")
logger.Error().Str("backend", "cs3").Err(err).Msg("could not get gatewayClient")
return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
}
res, err := client.GetUserByClaim(ctx, &cs3user.GetUserByClaimRequest{
res, err := gatewayClient.GetUserByClaim(ctx, &cs3user.GetUserByClaimRequest{
Claim: "userid", // FIXME add consts to reva
Value: userID,
})
@@ -73,9 +74,9 @@ func (i *CS3) GetUser(ctx context.Context, userID string, _ *godata.GoDataReques
func (i *CS3) GetUsers(ctx context.Context, oreq *godata.GoDataRequest) ([]*libregraph.User, error) {
logger := i.Logger.SubloggerWithRequestID(ctx)
logger.Debug().Str("backend", "cs3").Msg("GetUsers")
client, err := pool.GetGatewayServiceClient(i.Config.Address, i.Config.GetRevaOptions()...)
gatewayClient, err := i.GatewaySelector.Next()
if err != nil {
logger.Error().Str("backend", "cs3").Err(err).Msg("could not get client")
logger.Error().Str("backend", "cs3").Err(err).Msg("could not get gatewayClient")
return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
}
@@ -84,7 +85,7 @@ func (i *CS3) GetUsers(ctx context.Context, oreq *godata.GoDataRequest) ([]*libr
return nil, err
}
res, err := client.FindUsers(ctx, &cs3user.FindUsersRequest{
res, err := gatewayClient.FindUsers(ctx, &cs3user.FindUsersRequest{
// FIXME presence match is currently not implemented, an empty search currently leads to
// Unwilling To Perform": Search Error: error parsing filter: (&(objectclass=posixAccount)(|(cn=*)(displayname=*)(mail=*))), error: Present filter match for cn not implemented
Filter: search,
@@ -114,9 +115,9 @@ func (i *CS3) GetUsers(ctx context.Context, oreq *godata.GoDataRequest) ([]*libr
func (i *CS3) GetGroups(ctx context.Context, queryParam url.Values) ([]*libregraph.Group, error) {
logger := i.Logger.SubloggerWithRequestID(ctx)
logger.Debug().Str("backend", "cs3").Msg("GetGroups")
client, err := pool.GetGatewayServiceClient(i.Config.Address, i.Config.GetRevaOptions()...)
gatewayClient, err := i.GatewaySelector.Next()
if err != nil {
logger.Error().Str("backend", "cs3").Err(err).Msg("could not get client")
logger.Error().Str("backend", "cs3").Err(err).Msg("could not get gatewayClient")
return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
}
@@ -125,7 +126,7 @@ func (i *CS3) GetGroups(ctx context.Context, queryParam url.Values) ([]*libregra
search = queryParam.Get("$search")
}
res, err := client.FindGroups(ctx, &cs3group.FindGroupsRequest{
res, err := gatewayClient.FindGroups(ctx, &cs3group.FindGroupsRequest{
// FIXME presence match is currently not implemented, an empty search currently leads to
// Unwilling To Perform": Search Error: error parsing filter: (&(objectclass=posixAccount)(|(cn=*)(displayname=*)(mail=*))), error: Present filter match for cn not implemented
Filter: search,
@@ -161,13 +162,13 @@ func (i *CS3) CreateGroup(ctx context.Context, group libregraph.Group) (*libregr
func (i *CS3) GetGroup(ctx context.Context, groupID string, queryParam url.Values) (*libregraph.Group, error) {
logger := i.Logger.SubloggerWithRequestID(ctx)
logger.Debug().Str("backend", "cs3").Msg("GetGroup")
client, err := pool.GetGatewayServiceClient(i.Config.Address, i.Config.GetRevaOptions()...)
gatewayClient, err := i.GatewaySelector.Next()
if err != nil {
logger.Error().Str("backend", "cs3").Err(err).Msg("could not get client")
logger.Error().Str("backend", "cs3").Err(err).Msg("could not get gatewayClient")
return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
}
res, err := client.GetGroupByClaim(ctx, &cs3group.GetGroupByClaimRequest{
res, err := gatewayClient.GetGroupByClaim(ctx, &cs3group.GetGroupByClaimRequest{
Claim: "groupid", // FIXME add consts to reva
Value: groupID,
})
+5 -4
View File
@@ -17,6 +17,7 @@ import (
ociscrypto "github.com/owncloud/ocis/v2/ocis-pkg/crypto"
"github.com/owncloud/ocis/v2/ocis-pkg/keycloak"
"github.com/owncloud/ocis/v2/ocis-pkg/middleware"
"github.com/owncloud/ocis/v2/ocis-pkg/registry"
"github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
"github.com/owncloud/ocis/v2/ocis-pkg/service/http"
"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -114,7 +115,7 @@ func Server(opts ...Option) (http.Service, error) {
// how do we secure the api?
var requireAdminMiddleware func(stdhttp.Handler) stdhttp.Handler
var roleService svc.RoleService
var gatewayClient gateway.GatewayAPIClient
var gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
grpcClient, err := grpc.NewClient(append(grpc.GetClientOptions(options.Config.GRPCClientTLS), grpc.WithTraceProvider(tracing.TraceProvider))...)
if err != nil {
return http.Service{}, err
@@ -126,9 +127,9 @@ func Server(opts ...Option) (http.Service, error) {
account.JWTSecret(options.Config.TokenManager.JWTSecret),
))
roleService = settingssvc.NewRoleService("com.owncloud.api.settings", grpcClient)
gatewayClient, err = pool.GetGatewayServiceClient(options.Config.Reva.Address, options.Config.Reva.GetRevaOptions()...)
gatewaySelector, err = pool.GatewaySelector(options.Config.Reva.Address, append(options.Config.Reva.GetRevaOptions(), pool.WithRegistry(registry.GetRegistry()))...)
if err != nil {
return http.Service{}, errors.Wrap(err, "could not initialize gateway client")
return http.Service{}, errors.Wrap(err, "could not initialize gateway selector")
}
} else {
middlewares = append(middlewares, graphMiddleware.Token(options.Config.HTTP.APIToken))
@@ -159,7 +160,7 @@ func Server(opts ...Option) (http.Service, error) {
svc.EventsPublisher(publisher),
svc.WithRoleService(roleService),
svc.WithRequireAdminMiddleware(requireAdminMiddleware),
svc.WithGatewayClient(gatewayClient),
svc.WithGatewaySelector(gatewaySelector),
svc.WithSearchService(searchsvc.NewSearchProviderService("com.owncloud.api.search", grpcClient)),
svc.KeycloakClient(keyCloakClient),
svc.EventHistoryClient(hClient),
@@ -7,13 +7,13 @@ import (
"net/http"
"net/http/httptest"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
"github.com/go-chi/chi/v5"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
libregraph "github.com/owncloud/libre-graph-api-go"
"github.com/stretchr/testify/mock"
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
settingsmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/settings/v0"
@@ -23,6 +23,8 @@ import (
"github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
identitymocks "github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
service "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
"github.com/stretchr/testify/mock"
"google.golang.org/grpc"
)
type applicationList struct {
@@ -35,6 +37,7 @@ var _ = Describe("Applications", func() {
ctx context.Context
cfg *config.Config
gatewayClient *cs3mocks.GatewayAPIClient
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
eventsPublisher mocks.Publisher
roleService *mocks.RoleService
identityBackend *identitymocks.Backend
@@ -47,7 +50,16 @@ var _ = Describe("Applications", func() {
identityBackend = &identitymocks.Backend{}
roleService = &mocks.RoleService{}
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
},
)
rr = httptest.NewRecorder()
ctx = context.Background()
@@ -62,7 +74,7 @@ var _ = Describe("Applications", func() {
_ = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
svc, _ = service.NewService(
service.Config(cfg),
service.WithGatewayClient(gatewayClient),
service.WithGatewaySelector(gatewaySelector),
service.EventsPublisher(&eventsPublisher),
service.WithIdentityBackend(identityBackend),
service.WithRoleService(roleService),
@@ -8,15 +8,15 @@ import (
"net/http"
"net/http/httptest"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
revactx "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
"github.com/go-chi/chi/v5"
"github.com/golang/protobuf/ptypes/empty"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/stretchr/testify/mock"
libregraph "github.com/owncloud/libre-graph-api-go"
ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
@@ -27,6 +27,8 @@ import (
"github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
identitymocks "github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
service "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
"github.com/stretchr/testify/mock"
"google.golang.org/grpc"
)
type assignmentList struct {
@@ -39,6 +41,7 @@ var _ = Describe("AppRoleAssignments", func() {
ctx context.Context
cfg *config.Config
gatewayClient *cs3mocks.GatewayAPIClient
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
eventsPublisher mocks.Publisher
roleService *mocks.RoleService
identityBackend *identitymocks.Backend
@@ -57,7 +60,16 @@ var _ = Describe("AppRoleAssignments", func() {
identityBackend = &identitymocks.Backend{}
roleService = &mocks.RoleService{}
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
},
)
rr = httptest.NewRecorder()
ctx = context.Background()
@@ -72,7 +84,7 @@ var _ = Describe("AppRoleAssignments", func() {
_ = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
svc, _ = service.NewService(
service.Config(cfg),
service.WithGatewayClient(gatewayClient),
service.WithGatewaySelector(gatewaySelector),
service.EventsPublisher(&eventsPublisher),
service.WithIdentityBackend(identityBackend),
service.WithRoleService(roleService),
+24 -9
View File
@@ -25,9 +25,14 @@ func (g Graph) GetRootDriveChildren(w http.ResponseWriter, r *http.Request) {
g.logger.Info().Msg("Calling GetRootDriveChildren")
ctx := r.Context()
client := g.GetGatewayClient()
gatewayClient, err := g.gatewaySelector.Next()
if err != nil {
g.logger.Error().Err(err).Msg("could not select next gateway client")
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "could not select next gateway client, aborting")
return
}
res, err := client.GetHome(ctx, &storageprovider.GetHomeRequest{})
res, err := gatewayClient.GetHome(ctx, &storageprovider.GetHomeRequest{})
switch {
case err != nil:
g.logger.Error().Err(err).Msg("error sending get home grpc request")
@@ -43,7 +48,7 @@ func (g Graph) GetRootDriveChildren(w http.ResponseWriter, r *http.Request) {
return
}
lRes, err := client.ListContainer(ctx, &storageprovider.ListContainerRequest{
lRes, err := gatewayClient.ListContainer(ctx, &storageprovider.ListContainerRequest{
Ref: &storageprovider.Reference{
Path: res.Path,
},
@@ -80,9 +85,12 @@ func (g Graph) GetRootDriveChildren(w http.ResponseWriter, r *http.Request) {
}
func (g Graph) getDriveItem(ctx context.Context, ref storageprovider.Reference) (*libregraph.DriveItem, error) {
client := g.GetGatewayClient()
gatewayClient, err := g.gatewaySelector.Next()
if err != nil {
return nil, err
}
res, err := client.Stat(ctx, &storageprovider.StatRequest{Ref: &ref})
res, err := gatewayClient.Stat(ctx, &storageprovider.StatRequest{Ref: &ref})
if err != nil {
return nil, err
}
@@ -94,12 +102,15 @@ func (g Graph) getDriveItem(ctx context.Context, ref storageprovider.Reference)
}
func (g Graph) getRemoteItem(ctx context.Context, root *storageprovider.ResourceId, baseURL *url.URL) (*libregraph.RemoteItem, error) {
client := g.GetGatewayClient()
gatewayClient, err := g.gatewaySelector.Next()
if err != nil {
return nil, err
}
ref := &storageprovider.Reference{
ResourceId: root,
}
res, err := client.Stat(ctx, &storageprovider.StatRequest{Ref: ref})
res, err := gatewayClient.Stat(ctx, &storageprovider.StatRequest{Ref: ref})
if err != nil {
return nil, err
}
@@ -204,8 +215,12 @@ func cs3ResourceToRemoteItem(res *storageprovider.ResourceInfo) (*libregraph.Rem
}
func (g Graph) getPathForResource(ctx context.Context, id storageprovider.ResourceId) (string, error) {
client := g.GetGatewayClient()
res, err := client.GetPath(ctx, &storageprovider.GetPathRequest{ResourceId: &id})
gatewayClient, err := g.gatewaySelector.Next()
if err != nil {
return "", err
}
res, err := gatewayClient.GetPath(ctx, &storageprovider.GetPathRequest{ResourceId: &id})
if err != nil {
return "", err
}
@@ -8,14 +8,14 @@ import (
"net/http/httptest"
"time"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/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/stretchr/testify/mock"
libregraph "github.com/owncloud/libre-graph-api-go"
ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
@@ -24,6 +24,8 @@ import (
"github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
identitymocks "github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
service "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
"github.com/stretchr/testify/mock"
"google.golang.org/grpc"
)
type itemsList struct {
@@ -36,6 +38,7 @@ var _ = Describe("Driveitems", func() {
ctx context.Context
cfg *config.Config
gatewayClient *cs3mocks.GatewayAPIClient
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
eventsPublisher mocks.Publisher
identityBackend *identitymocks.Backend
@@ -49,8 +52,17 @@ var _ = Describe("Driveitems", func() {
rr = httptest.NewRecorder()
identityBackend = &identitymocks.Backend{}
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
},
)
identityBackend = &identitymocks.Backend{}
newGroup = libregraph.NewGroup()
newGroup.SetMembersodataBind([]string{"/users/user1"})
newGroup.SetId("group1")
@@ -67,7 +79,7 @@ var _ = Describe("Driveitems", func() {
_ = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
svc, _ = service.NewService(
service.Config(cfg),
service.WithGatewayClient(gatewayClient),
service.WithGatewaySelector(gatewaySelector),
service.EventsPublisher(&eventsPublisher),
service.WithIdentityBackend(identityBackend),
)
+28 -10
View File
@@ -261,7 +261,13 @@ func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
return
}
client := g.GetGatewayClient()
gatewayClient, err := g.gatewaySelector.Next()
if err != nil {
logger.Error().Err(err).Msg("could not select next gateway client")
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "could not select next gateway client, aborting")
return
}
drive := libregraph.Drive{}
if err := StrictJSONUnmarshal(r.Body, &drive); err != nil {
logger.Debug().Err(err).Interface("body", r.Body).Msg("could not create drive: invalid body schema definition")
@@ -306,7 +312,7 @@ func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
csr.Owner = us
}
resp, err := client.CreateStorageSpace(r.Context(), &csr)
resp, err := gatewayClient.CreateStorageSpace(r.Context(), &csr)
if err != nil {
logger.Error().Err(err).Msg("could not create drive: transport error")
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
@@ -374,7 +380,12 @@ func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
}
root := &rid
client := g.GetGatewayClient()
gatewayClient, err := g.gatewaySelector.Next()
if err != nil {
g.logger.Error().Err(err).Msg("could not select next gateway client")
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "could not select next gateway client, aborting")
return
}
updateSpaceRequest := &storageprovider.UpdateStorageSpaceRequest{
// Prepare the object to apply the diff from. The properties on StorageSpace will overwrite
@@ -459,7 +470,7 @@ func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
}
logger.Debug().Interface("payload", updateSpaceRequest).Msg("calling update space on backend")
resp, err := client.UpdateStorageSpace(r.Context(), updateSpaceRequest)
resp, err := gatewayClient.UpdateStorageSpace(r.Context(), updateSpaceRequest)
if err != nil {
logger.Error().Err(err).Msg("could not update drive: transport error")
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "transport error")
@@ -581,7 +592,10 @@ func (g Graph) formatDrives(ctx context.Context, baseURL *url.URL, storageSpaces
// ListStorageSpacesWithFilters List Storage Spaces using filters
func (g Graph) ListStorageSpacesWithFilters(ctx context.Context, filters []*storageprovider.ListStorageSpacesRequest_Filter, unrestricted bool) (*storageprovider.ListStorageSpacesResponse, error) {
client := g.GetGatewayClient()
gatewayClient, err := g.gatewaySelector.Next()
if err != nil {
return nil, err
}
grpcClient, err := grpc.NewClient(append(grpc.GetClientOptions(g.config.GRPCClientTLS), grpc.WithTraceProvider(gtracing.TraceProvider))...)
if err != nil {
@@ -615,7 +629,7 @@ func (g Graph) ListStorageSpacesWithFilters(ctx context.Context, filters []*stor
}},
Filters: filters,
}
res, err := client.ListStorageSpaces(ctx, lReq)
res, err := gatewayClient.ListStorageSpaces(ctx, lReq)
return res, err
}
@@ -858,7 +872,10 @@ func (g Graph) getDriveQuota(ctx context.Context, space *storageprovider.Storage
if noQuotaInOpaque {
// we have to make a trip to the storage
// TODO only if quota property was requested
client := g.GetGatewayClient()
gatewayClient, err := g.gatewaySelector.Next()
if err != nil {
return libregraph.Quota{}, err
}
req := &gateway.GetQuotaRequest{
Ref: &storageprovider.Reference{
@@ -866,7 +883,8 @@ func (g Graph) getDriveQuota(ctx context.Context, space *storageprovider.Storage
Path: ".",
},
}
res, err := client.GetQuota(ctx, req)
res, err := gatewayClient.GetQuota(ctx, req)
switch {
case err != nil:
logger.Error().Err(err).Interface("ref", req.Ref).Msg("could not call GetQuota: transport error")
@@ -1041,8 +1059,8 @@ func (g Graph) DeleteDrive(w http.ResponseWriter, r *http.Request) {
},
}
}
dRes, err := g.gatewayClient.DeleteStorageSpace(r.Context(), &storageprovider.DeleteStorageSpaceRequest{
gatewayClient, _ := g.gatewaySelector.Next()
dRes, err := gatewayClient.DeleteStorageSpace(r.Context(), &storageprovider.DeleteStorageSpaceRequest{
Opaque: opaque,
Id: &storageprovider.StorageSpaceId{
OpaqueId: storagespace.FormatResourceID(rid),
@@ -9,14 +9,14 @@ import (
"net/http"
"net/http/httptest"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
revactx "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
"github.com/go-chi/chi/v5"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/test-go/testify/mock"
libregraph "github.com/owncloud/libre-graph-api-go"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
@@ -27,6 +27,8 @@ import (
identitymocks "github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
service "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
"github.com/test-go/testify/mock"
"google.golang.org/grpc"
)
var _ = Describe("EducationClass", func() {
@@ -35,6 +37,7 @@ var _ = Describe("EducationClass", func() {
ctx context.Context
cfg *config.Config
gatewayClient *cs3mocks.GatewayAPIClient
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
eventsPublisher mocks.Publisher
identityBackend *identitymocks.Backend
identityEducationBackend *identitymocks.EducationBackend
@@ -52,9 +55,18 @@ var _ = Describe("EducationClass", func() {
BeforeEach(func() {
eventsPublisher.On("Publish", mock.Anything, mock.Anything, mock.Anything).Return(nil)
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
},
)
identityEducationBackend = &identitymocks.EducationBackend{}
identityBackend = &identitymocks.Backend{}
gatewayClient = &cs3mocks.GatewayAPIClient{}
newClass = libregraph.NewEducationClass("math", "course")
newClass.SetMembersodataBind([]string{"/users/user1"})
newClass.SetId("math")
@@ -71,7 +83,7 @@ var _ = Describe("EducationClass", func() {
_ = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
svc, _ = service.NewService(
service.Config(cfg),
service.WithGatewayClient(gatewayClient),
service.WithGatewaySelector(gatewaySelector),
service.EventsPublisher(&eventsPublisher),
service.WithIdentityBackend(identityBackend),
service.WithIdentityEducationBackend(identityEducationBackend),
@@ -320,7 +332,7 @@ var _ = Describe("EducationClass", func() {
cfg.API.GroupMembersPatchLimit = 21
svc, _ = service.NewService(
service.Config(cfg),
service.WithGatewayClient(gatewayClient),
service.WithGatewaySelector(gatewaySelector),
service.EventsPublisher(&eventsPublisher),
service.WithIdentityBackend(identityBackend),
service.WithIdentityEducationBackend(identityEducationBackend),
@@ -9,13 +9,16 @@ import (
"net/http"
"net/http/httptest"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
"github.com/go-chi/chi/v5"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/test-go/testify/mock"
"google.golang.org/grpc"
libregraph "github.com/owncloud/libre-graph-api-go"
ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
@@ -37,6 +40,7 @@ var _ = Describe("Schools", func() {
ctx context.Context
cfg *config.Config
gatewayClient *cs3mocks.GatewayAPIClient
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
identityEducationBackend *identitymocks.EducationBackend
rr *httptest.ResponseRecorder
@@ -50,8 +54,17 @@ var _ = Describe("Schools", func() {
)
BeforeEach(func() {
identityEducationBackend = &identitymocks.EducationBackend{}
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
},
)
identityEducationBackend = &identitymocks.EducationBackend{}
newSchool = libregraph.NewEducationSchool()
newSchool.SetId("school1")
@@ -67,7 +80,7 @@ var _ = Describe("Schools", func() {
_ = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
svc, _ = service.NewService(
service.Config(cfg),
service.WithGatewayClient(gatewayClient),
service.WithGatewaySelector(gatewaySelector),
service.WithIdentityEducationBackend(identityEducationBackend),
)
})
+10 -4
View File
@@ -239,13 +239,19 @@ func (g Graph) DeleteEducationUser(w http.ResponseWriter, r *http.Request) {
e.Executant = currentUser.GetId()
}
if g.gatewayClient != nil {
if g.gatewaySelector != nil {
logger.Debug().
Str("user", user.GetId()).
Msg("calling list spaces with user filter to fetch the personal space for deletion")
opaque := utils.AppendPlainToOpaque(nil, "unrestricted", "T")
f := listStorageSpacesUserFilter(user.GetId())
lspr, err := g.gatewayClient.ListStorageSpaces(r.Context(), &storageprovider.ListStorageSpacesRequest{
client, err := g.gatewaySelector.Next()
if err != nil {
logger.Error().Err(err).Msg("could not select next gateway client")
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "could not select next gateway client, aborting")
return
}
lspr, err := client.ListStorageSpaces(r.Context(), &storageprovider.ListStorageSpacesRequest{
Opaque: opaque,
Filters: []*storageprovider.ListStorageSpacesRequest_Filter{f},
})
@@ -266,7 +272,7 @@ func (g Graph) DeleteEducationUser(w http.ResponseWriter, r *http.Request) {
// Deleting a space a two step process (1. disabling/trashing, 2. purging)
// Do the "disable/trash" step only if the space is not marked as trashed yet:
if _, ok := sp.Opaque.Map["trashed"]; !ok {
_, err := g.gatewayClient.DeleteStorageSpace(r.Context(), &storageprovider.DeleteStorageSpaceRequest{
_, err := client.DeleteStorageSpace(r.Context(), &storageprovider.DeleteStorageSpaceRequest{
Id: &storageprovider.StorageSpaceId{
OpaqueId: sp.Id.OpaqueId,
},
@@ -278,7 +284,7 @@ func (g Graph) DeleteEducationUser(w http.ResponseWriter, r *http.Request) {
}
}
purgeFlag := utils.AppendPlainToOpaque(nil, "purge", "")
_, err := g.gatewayClient.DeleteStorageSpace(r.Context(), &storageprovider.DeleteStorageSpaceRequest{
_, err := client.DeleteStorageSpace(r.Context(), &storageprovider.DeleteStorageSpaceRequest{
Opaque: purgeFlag,
Id: &storageprovider.StorageSpaceId{
OpaqueId: sp.Id.OpaqueId,
@@ -8,17 +8,17 @@ import (
"net/http"
"net/http/httptest"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
revactx "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/rgrpc/status"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
"github.com/go-chi/chi/v5"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/stretchr/testify/mock"
libregraph "github.com/owncloud/libre-graph-api-go"
ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
@@ -28,6 +28,8 @@ import (
"github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
identitymocks "github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
service "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
"github.com/stretchr/testify/mock"
"google.golang.org/grpc"
)
type educationUserList struct {
@@ -40,6 +42,7 @@ var _ = Describe("EducationUsers", func() {
ctx context.Context
cfg *config.Config
gatewayClient *cs3mocks.GatewayAPIClient
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
eventsPublisher mocks.Publisher
roleService *mocks.RoleService
identityEducationBackend *identitymocks.EducationBackend
@@ -56,9 +59,18 @@ var _ = Describe("EducationUsers", func() {
BeforeEach(func() {
eventsPublisher.On("Publish", mock.Anything, mock.Anything, mock.Anything).Return(nil)
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
},
)
identityEducationBackend = &identitymocks.EducationBackend{}
roleService = &mocks.RoleService{}
gatewayClient = &cs3mocks.GatewayAPIClient{}
rr = httptest.NewRecorder()
ctx = context.Background()
@@ -72,7 +84,7 @@ var _ = Describe("EducationUsers", func() {
_ = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
svc, _ = service.NewService(
service.Config(cfg),
service.WithGatewayClient(gatewayClient),
service.WithGatewaySelector(gatewaySelector),
service.EventsPublisher(&eventsPublisher),
service.WithIdentityEducationBackend(identityEducationBackend),
service.WithRoleService(roleService),
+2 -6
View File
@@ -10,6 +10,7 @@ import (
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
"github.com/cs3org/reva/v2/pkg/events"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/go-chi/chi/v5"
"github.com/jellydator/ttlcache/v3"
libregraph "github.com/owncloud/libre-graph-api-go"
@@ -62,7 +63,7 @@ type Graph struct {
logger *log.Logger
identityBackend identity.Backend
identityEducationBackend identity.EducationBackend
gatewayClient gateway.GatewayAPIClient
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
roleService RoleService
permissionsService Permissions
specialDriveItemsCache *ttlcache.Cache[string, interface{}]
@@ -86,11 +87,6 @@ func (g Graph) ServeHTTP(w http.ResponseWriter, r *http.Request) {
g.mux.ServeHTTP(w, r)
}
// GetGatewayClient returns a gateway client to talk to reva
func (g Graph) GetGatewayClient() gateway.GatewayAPIClient {
return g.gatewayClient
}
func (g Graph) publishEvent(ev interface{}) {
if g.eventsPublisher != nil {
if err := events.Publish(g.eventsPublisher, ev); err != nil {
@@ -3,10 +3,24 @@ package svc_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 TestGraph(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Graph Suite")
+12 -3
View File
@@ -16,13 +16,13 @@ import (
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
revactx "github.com/cs3org/reva/v2/pkg/ctx"
"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/go-chi/chi/v5"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
libregraph "github.com/owncloud/libre-graph-api-go"
ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
v0 "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/settings/v0"
settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
@@ -40,6 +40,7 @@ var _ = Describe("Graph", func() {
var (
svc service.Service
gatewayClient *cs3mocks.GatewayAPIClient
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
eventsPublisher mocks.Publisher
permissionService mocks.Permissions
ctx context.Context
@@ -63,13 +64,21 @@ var _ = Describe("Graph", func() {
cfg.Commons = &shared.Commons{}
cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
_ = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
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
},
)
eventsPublisher = mocks.Publisher{}
permissionService = mocks.Permissions{}
svc, _ = service.NewService(
service.Config(cfg),
service.WithGatewayClient(gatewayClient),
service.WithGatewaySelector(gatewaySelector),
service.EventsPublisher(&eventsPublisher),
service.PermissionService(&permissionService),
)
+17 -5
View File
@@ -9,14 +9,14 @@ import (
"net/http"
"net/http/httptest"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
revactx "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
"github.com/go-chi/chi/v5"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/test-go/testify/mock"
libregraph "github.com/owncloud/libre-graph-api-go"
ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
@@ -26,6 +26,8 @@ import (
identitymocks "github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
service "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
"github.com/test-go/testify/mock"
"google.golang.org/grpc"
)
type groupList struct {
@@ -38,6 +40,7 @@ var _ = Describe("Groups", func() {
ctx context.Context
cfg *config.Config
gatewayClient *cs3mocks.GatewayAPIClient
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
eventsPublisher mocks.Publisher
identityBackend *identitymocks.Backend
@@ -54,8 +57,17 @@ var _ = Describe("Groups", func() {
BeforeEach(func() {
eventsPublisher.On("Publish", mock.Anything, mock.Anything, mock.Anything).Return(nil)
identityBackend = &identitymocks.Backend{}
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
},
)
identityBackend = &identitymocks.Backend{}
newGroup = libregraph.NewGroup()
newGroup.SetMembersodataBind([]string{"/users/user1"})
newGroup.SetId("group1")
@@ -72,7 +84,7 @@ var _ = Describe("Groups", func() {
_ = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
svc, _ = service.NewService(
service.Config(cfg),
service.WithGatewayClient(gatewayClient),
service.WithGatewaySelector(gatewaySelector),
service.EventsPublisher(&eventsPublisher),
service.WithIdentityBackend(identityBackend),
)
@@ -316,7 +328,7 @@ var _ = Describe("Groups", func() {
cfg.API.GroupMembersPatchLimit = 21
svc, _ = service.NewService(
service.Config(cfg),
service.WithGatewayClient(gatewayClient),
service.WithGatewaySelector(gatewaySelector),
service.EventsPublisher(&eventsPublisher),
service.WithIdentityBackend(identityBackend),
)
+5 -4
View File
@@ -5,6 +5,7 @@ import (
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
"github.com/cs3org/reva/v2/pkg/events"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/owncloud/ocis/v2/ocis-pkg/keycloak"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/ocis-pkg/roles"
@@ -24,7 +25,7 @@ type Options struct {
Config *config.Config
Middleware []func(http.Handler) http.Handler
RequireAdminMiddleware func(http.Handler) http.Handler
GatewayClient gateway.GatewayAPIClient
GatewaySelector pool.Selectable[gateway.GatewayAPIClient]
IdentityBackend identity.Backend
IdentityEducationBackend identity.EducationBackend
RoleService RoleService
@@ -75,10 +76,10 @@ func WithRequireAdminMiddleware(val func(http.Handler) http.Handler) Option {
}
}
// WithGatewayClient provides a function to set the gateway client option.
func WithGatewayClient(val gateway.GatewayAPIClient) Option {
// WithGatewaySelector provides a function to set the gateway client option.
func WithGatewaySelector(val pool.Selectable[gateway.GatewayAPIClient]) Option {
return func(o *Options) {
o.GatewayClient = val
o.GatewaySelector = val
}
}
+6 -1
View File
@@ -61,7 +61,12 @@ func (g Graph) ChangeOwnPassword(w http.ResponseWriter, r *http.Request) {
ClientId: u.Username,
ClientSecret: currentPw,
}
authRes, err := g.gatewayClient.Authenticate(r.Context(), authReq)
client, err := g.gatewaySelector.Next()
if err != nil {
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "could not select next gateway client, aborting")
return
}
authRes, err := client.Authenticate(r.Context(), authReq)
if err != nil {
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, err.Error())
return
+13 -1
View File
@@ -12,6 +12,7 @@ import (
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
revactx "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/rgrpc/status"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
"github.com/go-ldap/ldap/v3"
. "github.com/onsi/ginkgo/v2"
@@ -25,12 +26,14 @@ import (
"github.com/owncloud/ocis/v2/services/graph/pkg/identity"
service "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
"github.com/stretchr/testify/mock"
"google.golang.org/grpc"
)
var _ = Describe("Users changing their own password", func() {
var (
svc service.Service
gatewayClient *cs3mocks.GatewayAPIClient
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
ldapClient *mocks.Client
ldapConfig config.LDAP
identityBackend identity.Backend
@@ -47,7 +50,16 @@ var _ = Describe("Users changing their own password", func() {
cfg.TokenManager.JWTSecret = "loremipsum"
cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
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
},
)
ldapClient = mockedLDAPClient()
ldapConfig = config.LDAP{
@@ -68,7 +80,7 @@ var _ = Describe("Users changing their own password", func() {
eventsPublisher = mocks.Publisher{}
svc, _ = service.NewService(
service.Config(cfg),
service.WithGatewayClient(gatewayClient),
service.WithGatewaySelector(gatewaySelector),
service.WithIdentityBackend(identityBackend),
service.EventsPublisher(&eventsPublisher),
)
+29 -5
View File
@@ -10,6 +10,8 @@ import (
"path/filepath"
"strconv"
"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
@@ -68,8 +70,15 @@ func (g Graph) ExportPersonalData(w http.ResponseWriter, r *http.Request) {
Path: loc,
}
gatewayClient, err := g.gatewaySelector.Next()
if err != nil {
g.logger.Error().Err(err).Msg("could not select next gateway client")
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "could not select next gateway client, aborting")
return
}
// touch file
if err := mustTouchFile(ctx, ref, g.GetGatewayClient()); err != nil {
if err := mustTouchFile(ctx, ref, gatewayClient); err != nil {
g.logger.Error().Err(err).Msg("error touching file")
w.WriteHeader(http.StatusInternalServerError)
return
@@ -83,8 +92,14 @@ func (g Graph) ExportPersonalData(w http.ResponseWriter, r *http.Request) {
// GatherPersonalData will all gather all personal data of the user and save it to a file in the users personal space
func (g Graph) GatherPersonalData(usr *user.User, ref *provider.Reference, token string, marsh Marshaller) {
gatewayClient, err := g.gatewaySelector.Next()
if err != nil {
g.logger.Error().Err(err).Msg("could not select next gateway client")
return
}
// the context might already be cancelled. We need to impersonate the acting user again
ctx, err := utils.ImpersonateUser(usr, g.gatewayClient, g.config.MachineAuthAPIKey)
ctx, err := utils.ImpersonateUser(usr, gatewayClient, g.config.MachineAuthAPIKey)
if err != nil {
g.logger.Error().Err(err).Str("userID", usr.GetId().GetOpaqueId()).Msg("cannot impersonate user")
}
@@ -141,13 +156,22 @@ func (g Graph) upload(u *user.User, data []byte, ref *provider.Reference, th str
Opaque: utils.AppendPlainToOpaque(nil, "Upload-Length", strconv.FormatUint(uint64(len(data)), 10)),
}
gwc := g.GetGatewayClient()
ctx, err := utils.ImpersonateUser(u, gwc, g.config.MachineAuthAPIKey)
gatewayClient, err := g.gatewaySelector.Next()
if err != nil {
g.logger.Error().Err(err).Msg("could not select next gateway client")
return err
}
ctx, err := utils.ImpersonateUser(u, gatewayClient, g.config.MachineAuthAPIKey)
if err != nil {
return err
}
client, err := g.gatewaySelector.Next()
if err != nil {
return err
}
ctx = revactx.ContextSetToken(ctx, th)
uRes, err := gwc.InitiateFileUpload(ctx, uReq)
uRes, err := client.InitiateFileUpload(ctx, uReq)
if err != nil {
return err
}
+14 -3
View File
@@ -10,6 +10,7 @@ import (
"strconv"
"time"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/store"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
@@ -17,6 +18,7 @@ import (
"github.com/jellydator/ttlcache/v3"
libregraph "github.com/owncloud/libre-graph-api-go"
ocisldap "github.com/owncloud/ocis/v2/ocis-pkg/ldap"
"github.com/owncloud/ocis/v2/ocis-pkg/registry"
"github.com/owncloud/ocis/v2/ocis-pkg/roles"
"github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
@@ -144,7 +146,7 @@ func NewService(opts ...Option) (Graph, error) {
usersCache: usersCache,
groupsCache: groupsCache,
eventsPublisher: options.EventsPublisher,
gatewayClient: options.GatewayClient,
gatewaySelector: options.GatewaySelector,
searchService: options.SearchService,
identityEducationBackend: options.IdentityEducationBackend,
keycloakClient: options.KeycloakClient,
@@ -316,9 +318,18 @@ func setIdentityBackends(options Options, svc *Graph) error {
if options.IdentityBackend == nil {
switch options.Config.Identity.Backend {
case "cs3":
gatewaySelector, err := pool.GatewaySelector(
options.Config.Reva.Address,
append(options.Config.Reva.GetRevaOptions(), pool.WithRegistry(registry.GetRegistry()))...,
)
if err != nil {
return err
}
svc.identityBackend = &identity.CS3{
Config: options.Config.Reva,
Logger: &options.Logger,
Config: options.Config.Reva,
Logger: &options.Logger,
GatewaySelector: gatewaySelector,
}
case "ldap":
var err error
+16 -4
View File
@@ -66,7 +66,13 @@ func (g Graph) AssignTags(w http.ResponseWriter, r *http.Request) {
return
}
sres, err := g.gatewayClient.Stat(ctx, &provider.StatRequest{
client, err := g.gatewaySelector.Next()
if err != nil {
g.logger.Error().Err(err).Msg("error selecting next gateway client")
w.WriteHeader(http.StatusInternalServerError)
return
}
sres, err := client.Stat(ctx, &provider.StatRequest{
Ref: &provider.Reference{ResourceId: &rid},
})
if err != nil {
@@ -105,7 +111,7 @@ func (g Graph) AssignTags(w http.ResponseWriter, r *http.Request) {
return
}
resp, err := g.gatewayClient.SetArbitraryMetadata(ctx, &provider.SetArbitraryMetadataRequest{
resp, err := client.SetArbitraryMetadata(ctx, &provider.SetArbitraryMetadataRequest{
Ref: &provider.Reference{ResourceId: &rid},
ArbitraryMetadata: &provider.ArbitraryMetadata{
Metadata: map[string]string{
@@ -155,7 +161,13 @@ func (g Graph) UnassignTags(w http.ResponseWriter, r *http.Request) {
return
}
sres, err := g.gatewayClient.Stat(ctx, &provider.StatRequest{
client, err := g.gatewaySelector.Next()
if err != nil {
g.logger.Error().Err(err).Msg("error selecting next gateway client")
w.WriteHeader(http.StatusInternalServerError)
return
}
sres, err := client.Stat(ctx, &provider.StatRequest{
Ref: &provider.Reference{ResourceId: &rid},
})
if err != nil {
@@ -194,7 +206,7 @@ func (g Graph) UnassignTags(w http.ResponseWriter, r *http.Request) {
return
}
resp, err := g.gatewayClient.SetArbitraryMetadata(ctx, &provider.SetArbitraryMetadataRequest{
resp, err := client.SetArbitraryMetadata(ctx, &provider.SetArbitraryMetadataRequest{
Ref: &provider.Reference{ResourceId: &rid},
ArbitraryMetadata: &provider.ArbitraryMetadata{
Metadata: map[string]string{
+19 -5
View File
@@ -427,10 +427,18 @@ func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) {
return
}
logger.Debug().Str("id", user.GetId()).Msg("calling list storage spaces with filter")
// use the unrestricted flag to get all possible spaces
// users with the canListAllSpaces permission should see all spaces
client, err := g.gatewaySelector.Next()
if err != nil {
logger.Error().Err(err).Msg("error selecting next gateway client")
render.Status(r, http.StatusInternalServerError)
return
}
opaque := utils.AppendPlainToOpaque(nil, "unrestricted", "T")
lspr, err := g.gatewayClient.ListStorageSpaces(r.Context(), &storageprovider.ListStorageSpacesRequest{
lspr, err := client.ListStorageSpaces(r.Context(), &storageprovider.ListStorageSpacesRequest{
Opaque: opaque,
Filters: filters,
})
@@ -545,13 +553,19 @@ func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) {
e.Executant = currentUser.GetId()
}
if g.gatewayClient != nil {
if g.gatewaySelector != nil {
logger.Debug().
Str("user", user.GetId()).
Msg("calling list spaces with user filter to fetch the personal space for deletion")
opaque := utils.AppendPlainToOpaque(nil, "unrestricted", "T")
f := listStorageSpacesUserFilter(user.GetId())
lspr, err := g.gatewayClient.ListStorageSpaces(r.Context(), &storageprovider.ListStorageSpacesRequest{
client, err := g.gatewaySelector.Next()
if err != nil {
logger.Error().Err(err).Msg("error selecting next gateway client")
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "error selecting next gateway client, aborting")
return
}
lspr, err := client.ListStorageSpaces(r.Context(), &storageprovider.ListStorageSpacesRequest{
Opaque: opaque,
Filters: []*storageprovider.ListStorageSpacesRequest_Filter{f},
})
@@ -572,7 +586,7 @@ func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) {
// Deleting a space a two step process (1. disabling/trashing, 2. purging)
// Do the "disable/trash" step only if the space is not marked as trashed yet:
if _, ok := sp.Opaque.Map["trashed"]; !ok {
_, err := g.gatewayClient.DeleteStorageSpace(r.Context(), &storageprovider.DeleteStorageSpaceRequest{
_, err := client.DeleteStorageSpace(r.Context(), &storageprovider.DeleteStorageSpaceRequest{
Id: &storageprovider.StorageSpaceId{
OpaqueId: sp.Id.OpaqueId,
},
@@ -584,7 +598,7 @@ func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) {
}
}
purgeFlag := utils.AppendPlainToOpaque(nil, "purge", "")
_, err := g.gatewayClient.DeleteStorageSpace(r.Context(), &storageprovider.DeleteStorageSpaceRequest{
_, err := client.DeleteStorageSpace(r.Context(), &storageprovider.DeleteStorageSpaceRequest{
Opaque: purgeFlag,
Id: &storageprovider.StorageSpaceId{
OpaqueId: sp.Id.OpaqueId,
+18 -6
View File
@@ -9,18 +9,17 @@ import (
"net/http/httptest"
"net/url"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
revactx "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/rgrpc/status"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
"github.com/go-chi/chi/v5"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/stretchr/testify/mock"
"go-micro.dev/v4/client"
libregraph "github.com/owncloud/libre-graph-api-go"
ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
@@ -31,6 +30,9 @@ import (
"github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
identitymocks "github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
service "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
"github.com/stretchr/testify/mock"
"go-micro.dev/v4/client"
"google.golang.org/grpc"
)
type userList struct {
@@ -43,6 +45,7 @@ var _ = Describe("Users", func() {
ctx context.Context
cfg *config.Config
gatewayClient *cs3mocks.GatewayAPIClient
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
eventsPublisher mocks.Publisher
roleService *mocks.RoleService
identityBackend *identitymocks.Backend
@@ -59,9 +62,18 @@ var _ = Describe("Users", func() {
BeforeEach(func() {
eventsPublisher.On("Publish", mock.Anything, mock.Anything, mock.Anything).Return(nil)
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
},
)
identityBackend = &identitymocks.Backend{}
roleService = &mocks.RoleService{}
gatewayClient = &cs3mocks.GatewayAPIClient{}
rr = httptest.NewRecorder()
ctx = context.Background()
@@ -76,7 +88,7 @@ var _ = Describe("Users", func() {
_ = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
svc, _ = service.NewService(
service.Config(cfg),
service.WithGatewayClient(gatewayClient),
service.WithGatewaySelector(gatewaySelector),
service.EventsPublisher(&eventsPublisher),
service.WithIdentityBackend(identityBackend),
service.WithRoleService(roleService),
@@ -681,7 +693,7 @@ var _ = Describe("Users", func() {
_ = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
localSvc, _ := service.NewService(
service.Config(localCfg),
service.WithGatewayClient(gatewayClient),
service.WithGatewaySelector(gatewaySelector),
service.EventsPublisher(&eventsPublisher),
service.WithIdentityBackend(identityBackend),
service.WithRoleService(roleService),