diff --git a/.drone.star b/.drone.star
index c9b608b4a..cefd1492d 100644
--- a/.drone.star
+++ b/.drone.star
@@ -2144,7 +2144,7 @@ def ocisServer(storage, accounts_hash_difficulty = 4, volumes = [], depends_on =
"IDM_ADMIN_PASSWORD": "admin", # override the random admin password from `ocis init`
"FRONTEND_SEARCH_MIN_LENGTH": "2",
"GATEWAY_GRPC_ADDR": "0.0.0.0:9142", # make gateway available to wopi server
- "APP_PROVIDER_EXTERNAL_ADDR": "127.0.0.1:9164",
+ "APP_PROVIDER_EXTERNAL_ADDR": "com.owncloud.api.app-provider",
"APP_PROVIDER_DRIVER": "wopi",
"APP_PROVIDER_WOPI_APP_NAME": "FakeOffice",
"APP_PROVIDER_WOPI_APP_URL": "http://fakeoffice:8080",
diff --git a/changelog/unreleased/client-selector-pool.md b/changelog/unreleased/client-selector-pool.md
new file mode 100644
index 000000000..975c9928e
--- /dev/null
+++ b/changelog/unreleased/client-selector-pool.md
@@ -0,0 +1,8 @@
+Enhancement: Use reva client selectors
+
+Use reva client selectors instead of the static clients, this introduces the ocis service registry in reva.
+The service discovery now resolves reva services by name and the client selectors pick a random registered service node.
+
+https://github.com/owncloud/ocis/pull/6452
+https://github.com/cs3org/reva/pull/3939
+https://github.com/cs3org/reva/pull/3953
diff --git a/go.mod b/go.mod
index 4c8076bc3..7ec2524a4 100644
--- a/go.mod
+++ b/go.mod
@@ -13,7 +13,7 @@ require (
github.com/coreos/go-oidc v2.2.1+incompatible
github.com/coreos/go-oidc/v3 v3.6.0
github.com/cs3org/go-cs3apis v0.0.0-20230516150832-730ac860c71d
- github.com/cs3org/reva/v2 v2.14.0
+ github.com/cs3org/reva/v2 v2.14.1-0.20230607220921-238a03c2f795
github.com/disintegration/imaging v1.6.2
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
github.com/egirna/icap-client v0.1.1
diff --git a/go.sum b/go.sum
index e0cfe0ea5..f7e567be7 100644
--- a/go.sum
+++ b/go.sum
@@ -629,8 +629,8 @@ github.com/crewjam/httperr v0.2.0 h1:b2BfXR8U3AlIHwNeFFvZ+BV1LFvKLlzMjzaTnZMybNo
github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3pglZ5oH4=
github.com/crewjam/saml v0.4.13 h1:TYHggH/hwP7eArqiXSJUvtOPNzQDyQ7vwmwEqlFWhMc=
github.com/crewjam/saml v0.4.13/go.mod h1:igEejV+fihTIlHXYP8zOec3V5A8y3lws5bQBFsTm4gA=
-github.com/cs3org/reva/v2 v2.14.0 h1:X5da4chnEPzqUb76y/DDDawFloRAG7Gy/BMpeYh7vu8=
-github.com/cs3org/reva/v2 v2.14.0/go.mod h1:vMQqSn30fEPHO/GKC2WmGimlOPqvfSy4gdhRSpbvrWc=
+github.com/cs3org/reva/v2 v2.14.1-0.20230607220921-238a03c2f795 h1:uyzA03PcmG7mjd+3KJrkws0IXuXQCvHEn25xXBmO2QI=
+github.com/cs3org/reva/v2 v2.14.1-0.20230607220921-238a03c2f795/go.mod h1:E32krZG159YflDSjDWfx/QGIC2529PS5LiPnGNHu3d0=
github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI=
github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY=
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
diff --git a/ocis-pkg/registry/register.go b/ocis-pkg/registry/register.go
new file mode 100644
index 000000000..e4e55837f
--- /dev/null
+++ b/ocis-pkg/registry/register.go
@@ -0,0 +1,47 @@
+package registry
+
+import (
+ "context"
+ "time"
+
+ "github.com/owncloud/ocis/v2/ocis-pkg/log"
+ mRegistry "go-micro.dev/v4/registry"
+)
+
+// RegisterService publishes an arbitrary endpoint to the service-registry. This allows querying nodes of
+// non-micro services like reva. No health-checks are done, thus the caller is responsible for canceling.
+func RegisterService(ctx context.Context, service *mRegistry.Service, logger log.Logger) error {
+ registry := GetRegistry()
+ node := service.Nodes[0]
+
+ logger.Info().Msgf("registering external service %v@%v", node.Id, node.Address)
+
+ rOpts := []mRegistry.RegisterOption{mRegistry.RegisterTTL(time.Minute)}
+ if err := registry.Register(service, rOpts...); err != nil {
+ logger.Fatal().Err(err).Msgf("Registration error for external service %v", service.Name)
+ }
+
+ t := time.NewTicker(time.Second * 30)
+
+ go func() {
+ for {
+ select {
+ case <-t.C:
+ logger.Debug().Interface("service", service).Msg("refreshing external service-registration")
+ err := registry.Register(service, rOpts...)
+ if err != nil {
+ logger.Error().Err(err).Msgf("registration error for external service %v", service.Name)
+ }
+ case <-ctx.Done():
+ logger.Debug().Interface("service", service).Msg("unregistering")
+ t.Stop()
+ err := registry.Deregister(service)
+ if err != nil {
+ logger.Err(err).Msgf("Error unregistering external service %v", service.Name)
+ }
+ }
+ }
+ }()
+
+ return nil
+}
diff --git a/ocis-pkg/service/external/external_test.go b/ocis-pkg/registry/register_test.go
similarity index 99%
rename from ocis-pkg/service/external/external_test.go
rename to ocis-pkg/registry/register_test.go
index 637d8601c..291670042 100644
--- a/ocis-pkg/service/external/external_test.go
+++ b/ocis-pkg/registry/register_test.go
@@ -1,4 +1,4 @@
-package external
+package registry
//
//import (
diff --git a/ocis-pkg/registry/registry.go b/ocis-pkg/registry/registry.go
index 6f048e448..6b4ccda01 100644
--- a/ocis-pkg/registry/registry.go
+++ b/ocis-pkg/registry/registry.go
@@ -6,14 +6,14 @@ import (
"sync"
"time"
+ rRegistry "github.com/cs3org/reva/v2/pkg/registry"
consulr "github.com/go-micro/plugins/v4/registry/consul"
etcdr "github.com/go-micro/plugins/v4/registry/etcd"
kubernetesr "github.com/go-micro/plugins/v4/registry/kubernetes"
mdnsr "github.com/go-micro/plugins/v4/registry/mdns"
memr "github.com/go-micro/plugins/v4/registry/memory"
natsr "github.com/go-micro/plugins/v4/registry/nats"
-
- "go-micro.dev/v4/registry"
+ mRegistry "go-micro.dev/v4/registry"
"go-micro.dev/v4/registry/cache"
)
@@ -25,7 +25,7 @@ const (
var (
once sync.Once
regPlugin string
- reg registry.Registry
+ reg mRegistry.Registry
)
func Configure(plugin string) {
@@ -37,7 +37,7 @@ func Configure(plugin string) {
// GetRegistry returns a configured micro registry based on Micro env vars.
// It defaults to mDNS, so mind that systems with mDNS disabled by default (i.e SUSE) will have a hard time
// and it needs to explicitly use etcd. Os awareness for providing a working registry out of the box should be done.
-func GetRegistry() registry.Registry {
+func GetRegistry() mRegistry.Registry {
once.Do(func() {
addresses := strings.Split(os.Getenv(registryAddressEnv), ",")
// prefer env of setting from Configure()
@@ -49,29 +49,33 @@ func GetRegistry() registry.Registry {
switch plugin {
case "nats":
reg = natsr.NewRegistry(
- registry.Addrs(addresses...),
+ mRegistry.Addrs(addresses...),
)
case "kubernetes":
reg = kubernetesr.NewRegistry(
- registry.Addrs(addresses...),
+ mRegistry.Addrs(addresses...),
)
case "etcd":
reg = etcdr.NewRegistry(
- registry.Addrs(addresses...),
+ mRegistry.Addrs(addresses...),
)
case "consul":
reg = consulr.NewRegistry(
- registry.Addrs(addresses...),
+ mRegistry.Addrs(addresses...),
)
case "memory":
reg = memr.NewRegistry()
default:
reg = mdnsr.NewRegistry()
}
+
// No cache needed for in-memory registry
if plugin != "memory" {
- reg = cache.New(reg, cache.WithTTL(20*time.Second))
+ reg = cache.New(reg, cache.WithTTL(30*time.Second))
}
+
+ // fixme: lazy initialization of reva registry, needs refactor to a explicit call per service
+ _ = rRegistry.Init(reg)
})
// always use cached registry to prevent registry
// lookup for every request
diff --git a/ocis-pkg/registry/service.go b/ocis-pkg/registry/service.go
new file mode 100644
index 000000000..da80a8912
--- /dev/null
+++ b/ocis-pkg/registry/service.go
@@ -0,0 +1,83 @@
+package registry
+
+import (
+ "fmt"
+ "net"
+ "strconv"
+ "strings"
+
+ mRegistry "go-micro.dev/v4/registry"
+ "go-micro.dev/v4/util/addr"
+)
+
+func BuildGRPCService(serviceID, uuid, address string, version string) *mRegistry.Service {
+ var host string
+ var port int
+
+ parts := strings.Split(address, ":")
+ if len(parts) > 1 {
+ host = strings.Join(parts[:len(parts)-1], ":")
+ port, _ = strconv.Atoi(parts[len(parts)-1])
+ } else {
+ host = parts[0]
+ }
+
+ addr, err := addr.Extract(host)
+ if err != nil {
+ addr = host
+ }
+
+ node := &mRegistry.Node{
+ Id: serviceID + "-" + uuid,
+ Address: net.JoinHostPort(addr, fmt.Sprint(port)),
+ Metadata: make(map[string]string),
+ }
+
+ node.Metadata["registry"] = GetRegistry().String()
+ node.Metadata["server"] = "grpc"
+ node.Metadata["transport"] = "grpc"
+ node.Metadata["protocol"] = "grpc"
+
+ return &mRegistry.Service{
+ Name: serviceID,
+ Version: version,
+ Nodes: []*mRegistry.Node{node},
+ Endpoints: make([]*mRegistry.Endpoint, 0),
+ }
+}
+
+func BuildHTTPService(serviceID, uuid, address string, version string) *mRegistry.Service {
+ var host string
+ var port int
+
+ parts := strings.Split(address, ":")
+ if len(parts) > 1 {
+ host = strings.Join(parts[:len(parts)-1], ":")
+ port, _ = strconv.Atoi(parts[len(parts)-1])
+ } else {
+ host = parts[0]
+ }
+
+ addr, err := addr.Extract(host)
+ if err != nil {
+ addr = host
+ }
+
+ node := &mRegistry.Node{
+ Id: serviceID + "-" + uuid,
+ Address: net.JoinHostPort(addr, fmt.Sprint(port)),
+ Metadata: make(map[string]string),
+ }
+
+ node.Metadata["registry"] = GetRegistry().String()
+ node.Metadata["server"] = "http"
+ node.Metadata["transport"] = "http"
+ node.Metadata["protocol"] = "http"
+
+ return &mRegistry.Service{
+ Name: serviceID,
+ Version: version,
+ Nodes: []*mRegistry.Node{node},
+ Endpoints: make([]*mRegistry.Endpoint, 0),
+ }
+}
diff --git a/ocis-pkg/service/external/external.go b/ocis-pkg/service/external/external.go
deleted file mode 100644
index 7b90fe7fb..000000000
--- a/ocis-pkg/service/external/external.go
+++ /dev/null
@@ -1,120 +0,0 @@
-package external
-
-import (
- "context"
- "time"
-
- "github.com/owncloud/ocis/v2/ocis-pkg/log"
- oregistry "github.com/owncloud/ocis/v2/ocis-pkg/registry"
- "go-micro.dev/v4/registry"
-)
-
-// RegisterGRPCEndpoint publishes an arbitrary endpoint to the service-registry. This allows querying nodes of
-// non-micro GRPC-services like reva. No health-checks are done, thus the caller is responsible for canceling.
-func RegisterGRPCEndpoint(ctx context.Context, serviceID, uuid, addr string, version string, logger log.Logger) error {
- node := ®istry.Node{
- Id: serviceID + "-" + uuid,
- Address: addr,
- Metadata: make(map[string]string),
- }
- ocisRegistry := oregistry.GetRegistry()
-
- node.Metadata["registry"] = ocisRegistry.String()
- node.Metadata["server"] = "grpc"
- node.Metadata["transport"] = "grpc"
- node.Metadata["protocol"] = "grpc"
-
- service := ®istry.Service{
- Name: serviceID,
- Version: version,
- Nodes: []*registry.Node{node},
- Endpoints: make([]*registry.Endpoint, 0),
- }
-
- logger.Info().Msgf("registering external service %v@%v", node.Id, node.Address)
-
- rOpts := []registry.RegisterOption{registry.RegisterTTL(time.Minute)}
- if err := ocisRegistry.Register(service, rOpts...); err != nil {
- logger.Fatal().Err(err).Msgf("Registration error for external service %v", serviceID)
- }
-
- t := time.NewTicker(time.Second * 30)
-
- go func() {
- for {
- select {
- case <-t.C:
- logger.Debug().Interface("service", service).Msg("refreshing external service-registration")
- err := ocisRegistry.Register(service, rOpts...)
- if err != nil {
- logger.Error().Err(err).Msgf("registration error for external service %v", serviceID)
- }
- case <-ctx.Done():
- logger.Debug().Interface("service", service).Msg("unregistering")
- t.Stop()
- err := ocisRegistry.Deregister(service)
- if err != nil {
- logger.Err(err).Msgf("Error unregistering external service %v", serviceID)
- }
-
- }
- }
- }()
-
- return nil
-}
-
-// RegisterHTTPEndpoint publishes an arbitrary endpoint to the service-registry. This allows querying nodes of
-// non-micro HTTP-services like reva. No health-checks are done, thus the caller is responsible for canceling.
-func RegisterHTTPEndpoint(ctx context.Context, serviceID, uuid, addr string, version string, logger log.Logger) error {
- node := ®istry.Node{
- Id: serviceID + "-" + uuid,
- Address: addr,
- Metadata: make(map[string]string),
- }
- ocisRegistry := oregistry.GetRegistry()
-
- node.Metadata["registry"] = ocisRegistry.String()
- node.Metadata["server"] = "http"
- node.Metadata["transport"] = "http"
- node.Metadata["protocol"] = "http"
-
- service := ®istry.Service{
- Name: serviceID,
- Version: version,
- Nodes: []*registry.Node{node},
- Endpoints: make([]*registry.Endpoint, 0),
- }
-
- logger.Info().Msgf("registering external service %v@%v", node.Id, node.Address)
-
- rOpts := []registry.RegisterOption{registry.RegisterTTL(time.Minute)}
- if err := ocisRegistry.Register(service, rOpts...); err != nil {
- logger.Fatal().Err(err).Msgf("Registration error for external service %v", serviceID)
- }
-
- t := time.NewTicker(time.Second * 30)
-
- go func() {
- for {
- select {
- case <-t.C:
- logger.Debug().Interface("service", service).Msg("refreshing external service-registration")
- err := ocisRegistry.Register(service, rOpts...)
- if err != nil {
- logger.Error().Err(err).Msgf("registration error for external service %v", serviceID)
- }
- case <-ctx.Done():
- logger.Debug().Interface("service", service).Msg("unregistering")
- t.Stop()
- err := ocisRegistry.Deregister(service)
- if err != nil {
- logger.Err(err).Msgf("Error unregistering external service %v", serviceID)
- }
-
- }
- }
- }()
-
- return nil
-}
diff --git a/ocis-pkg/shared/reva.go b/ocis-pkg/shared/reva.go
index cc3837090..a4a9f5555 100644
--- a/ocis-pkg/shared/reva.go
+++ b/ocis-pkg/shared/reva.go
@@ -1,9 +1,11 @@
package shared
-import "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
+import (
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
+)
var defaultRevaConfig = Reva{
- Address: "127.0.0.1:9142",
+ Address: "com.owncloud.api.gateway",
}
func DefaultRevaConfig() *Reva {
diff --git a/services/app-provider/pkg/command/server.go b/services/app-provider/pkg/command/server.go
index a7fc216d0..902c29386 100644
--- a/services/app-provider/pkg/command/server.go
+++ b/services/app-provider/pkg/command/server.go
@@ -10,7 +10,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/app-provider/pkg/config"
@@ -42,12 +42,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.AppProviderConfigFromStruct(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.AppProviderConfigFromStruct(cfg)
+ reg := registry.GetRegistry()
+
+ runtime.RunWithOptions(rCfg, pidFile,
+ runtime.WithLogger(&logger.Logger),
+ runtime.WithRegistry(reg),
+ )
+
return nil
}, func(err error) {
logger.Error().
@@ -77,15 +81,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")
}
return gr.Run()
diff --git a/services/app-registry/pkg/command/server.go b/services/app-registry/pkg/command/server.go
index aa230570f..3fae646d8 100644
--- a/services/app-registry/pkg/command/server.go
+++ b/services/app-registry/pkg/command/server.go
@@ -10,7 +10,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/version"
"github.com/owncloud/ocis/v2/services/app-registry/pkg/config"
"github.com/owncloud/ocis/v2/services/app-registry/pkg/config/parser"
@@ -41,12 +41,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.AppRegistryConfigFromStruct(cfg, logger)
-
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.AppRegistryConfigFromStruct(cfg, logger)
+ reg := registry.GetRegistry()
+
+ runtime.RunWithOptions(rCfg, pidFile,
+ runtime.WithLogger(&logger.Logger),
+ runtime.WithRegistry(reg),
+ )
+
return nil
}, func(err error) {
logger.Error().
@@ -72,15 +76,9 @@ func Server(cfg *config.Config) *cli.Command {
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")
}
return gr.Run()
diff --git a/services/app-registry/pkg/revaconfig/config.go b/services/app-registry/pkg/revaconfig/config.go
index 8698f2fb7..68215a328 100644
--- a/services/app-registry/pkg/revaconfig/config.go
+++ b/services/app-registry/pkg/revaconfig/config.go
@@ -1,9 +1,8 @@
package revaconfig
import (
- "github.com/owncloud/ocis/v2/ocis-pkg/log"
-
"github.com/mitchellh/mapstructure"
+ "github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/services/app-registry/pkg/config"
)
diff --git a/services/auth-basic/pkg/command/server.go b/services/auth-basic/pkg/command/server.go
index 4dc4ffba2..f137ae5b5 100644
--- a/services/auth-basic/pkg/command/server.go
+++ b/services/auth-basic/pkg/command/server.go
@@ -11,7 +11,7 @@ import (
"github.com/oklog/run"
"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
"github.com/owncloud/ocis/v2/ocis-pkg/ldap"
- "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/auth-basic/pkg/config"
@@ -43,10 +43,6 @@ 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.AuthBasicConfigFromStruct(cfg)
-
// the reva runtime calls os.Exit in the case of a failure and there is no way for the oCIS
// runtime to catch it and restart a reva service. Therefore we need to ensure the service has
// everything it needs, before starting the service.
@@ -60,7 +56,15 @@ func Server(cfg *config.Config) *cli.Command {
}
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.AuthBasicConfigFromStruct(cfg)
+ reg := registry.GetRegistry()
+
+ runtime.RunWithOptions(rCfg, pidFile,
+ runtime.WithLogger(&logger.Logger),
+ runtime.WithRegistry(reg),
+ )
+
return nil
}, func(err error) {
logger.Error().
@@ -90,15 +94,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")
}
return gr.Run()
diff --git a/services/auth-basic/pkg/revaconfig/config.go b/services/auth-basic/pkg/revaconfig/config.go
index 7fe28fd67..ad3932694 100644
--- a/services/auth-basic/pkg/revaconfig/config.go
+++ b/services/auth-basic/pkg/revaconfig/config.go
@@ -1,6 +1,8 @@
package revaconfig
-import "github.com/owncloud/ocis/v2/services/auth-basic/pkg/config"
+import (
+ "github.com/owncloud/ocis/v2/services/auth-basic/pkg/config"
+)
// AuthBasicConfigFromStruct will adapt an oCIS config struct into a reva mapstructure to start a reva service.
func AuthBasicConfigFromStruct(cfg *config.Config) map[string]interface{} {
diff --git a/services/auth-bearer/pkg/command/server.go b/services/auth-bearer/pkg/command/server.go
index 4c181bfab..50d97b785 100644
--- a/services/auth-bearer/pkg/command/server.go
+++ b/services/auth-bearer/pkg/command/server.go
@@ -10,7 +10,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/auth-bearer/pkg/config"
@@ -42,12 +42,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.AuthBearerConfigFromStruct(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.AuthBearerConfigFromStruct(cfg)
+ reg := registry.GetRegistry()
+
+ runtime.RunWithOptions(rCfg, pidFile,
+ runtime.WithLogger(&logger.Logger),
+ runtime.WithRegistry(reg),
+ )
+
return nil
}, func(err error) {
logger.Error().
@@ -77,15 +81,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")
}
return gr.Run()
diff --git a/services/auth-bearer/pkg/revaconfig/config.go b/services/auth-bearer/pkg/revaconfig/config.go
index 6c19622e6..82cd79f1b 100644
--- a/services/auth-bearer/pkg/revaconfig/config.go
+++ b/services/auth-bearer/pkg/revaconfig/config.go
@@ -1,6 +1,9 @@
+// Package revaconfig transfers the config struct to reva config map
package revaconfig
-import "github.com/owncloud/ocis/v2/services/auth-bearer/pkg/config"
+import (
+ "github.com/owncloud/ocis/v2/services/auth-bearer/pkg/config"
+)
// AuthBearerConfigFromStruct will adapt an oCIS config struct into a reva mapstructure to start a reva service.
func AuthBearerConfigFromStruct(cfg *config.Config) map[string]interface{} {
diff --git a/services/auth-machine/pkg/command/server.go b/services/auth-machine/pkg/command/server.go
index bf2ad19cc..168947664 100644
--- a/services/auth-machine/pkg/command/server.go
+++ b/services/auth-machine/pkg/command/server.go
@@ -10,7 +10,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/auth-machine/pkg/config"
@@ -42,12 +42,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.AuthMachineConfigFromStruct(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.AuthMachineConfigFromStruct(cfg)
+ reg := registry.GetRegistry()
+
+ runtime.RunWithOptions(rCfg, pidFile,
+ runtime.WithLogger(&logger.Logger),
+ runtime.WithRegistry(reg),
+ )
+
return nil
}, func(err error) {
logger.Error().
@@ -77,15 +81,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")
}
return gr.Run()
diff --git a/services/frontend/pkg/command/server.go b/services/frontend/pkg/command/server.go
index 650879969..d899fa027 100644
--- a/services/frontend/pkg/command/server.go
+++ b/services/frontend/pkg/command/server.go
@@ -10,7 +10,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/frontend/pkg/config"
@@ -42,15 +42,20 @@ 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, err := revaconfig.FrontendConfigFromStruct(cfg)
+ rCfg, err := revaconfig.FrontendConfigFromStruct(cfg)
if err != nil {
return err
}
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")
+ reg := registry.GetRegistry()
+
+ runtime.RunWithOptions(rCfg, pidFile,
+ runtime.WithLogger(&logger.Logger),
+ runtime.WithRegistry(reg),
+ )
+
return nil
}, func(err error) {
logger.Error().
@@ -80,15 +85,9 @@ func Server(cfg *config.Config) *cli.Command {
sync.Trap(&gr, cancel)
}
- if err := external.RegisterHTTPEndpoint(
- ctx,
- cfg.HTTP.Namespace+"."+cfg.Service.Name,
- uuid.Must(uuid.NewV4()).String(),
- cfg.HTTP.Addr,
- version.GetString(),
- logger,
- ); err != nil {
- logger.Fatal().Err(err).Msg("failed to register the http endpoint")
+ httpSvc := registry.BuildHTTPService(cfg.HTTP.Namespace+"."+cfg.Service.Name, uuid.Must(uuid.NewV4()).String(), cfg.HTTP.Addr, version.GetString())
+ if err := registry.RegisterService(ctx, httpSvc, logger); err != nil {
+ logger.Fatal().Err(err).Msg("failed to register the http service")
}
return gr.Run()
diff --git a/services/gateway/pkg/command/server.go b/services/gateway/pkg/command/server.go
index f2ddf03af..37c34c976 100644
--- a/services/gateway/pkg/command/server.go
+++ b/services/gateway/pkg/command/server.go
@@ -10,7 +10,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/version"
"github.com/owncloud/ocis/v2/services/gateway/pkg/config"
"github.com/owncloud/ocis/v2/services/gateway/pkg/config/parser"
@@ -41,12 +41,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.GatewayConfigFromStruct(cfg, logger)
-
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.GatewayConfigFromStruct(cfg, logger)
+ reg := registry.GetRegistry()
+
+ runtime.RunWithOptions(rCfg, pidFile,
+ runtime.WithLogger(&logger.Logger),
+ runtime.WithRegistry(reg),
+ )
+
return nil
}, func(err error) {
logger.Error().
@@ -72,15 +76,9 @@ func Server(cfg *config.Config) *cli.Command {
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")
}
return gr.Run()
diff --git a/services/gateway/pkg/config/defaults/defaultconfig.go b/services/gateway/pkg/config/defaults/defaultconfig.go
index f776c55a2..3e0fd026e 100644
--- a/services/gateway/pkg/config/defaults/defaultconfig.go
+++ b/services/gateway/pkg/config/defaults/defaultconfig.go
@@ -52,16 +52,16 @@ func DefaultConfig() *config.Config {
FrontendPublicURL: "https://localhost:9200",
- AppRegistryEndpoint: "localhost:9242",
- AuthBasicEndpoint: "localhost:9146",
- AuthMachineEndpoint: "localhost:9166",
- GroupsEndpoint: "localhost:9160",
- PermissionsEndpoint: "localhost:9191",
- SharingEndpoint: "localhost:9150",
- StoragePublicLinkEndpoint: "localhost:9178",
- StorageSharesEndpoint: "localhost:9154",
- StorageUsersEndpoint: "localhost:9157",
- UsersEndpoint: "localhost:9144",
+ AppRegistryEndpoint: "com.owncloud.api.app-registry",
+ AuthBasicEndpoint: "com.owncloud.api.auth-basic",
+ AuthMachineEndpoint: "com.owncloud.api.auth-machine",
+ GroupsEndpoint: "com.owncloud.api.groups",
+ PermissionsEndpoint: "com.owncloud.api.settings",
+ SharingEndpoint: "com.owncloud.api.sharing",
+ StoragePublicLinkEndpoint: "com.owncloud.api.storage-publiclink",
+ StorageSharesEndpoint: "com.owncloud.api.storage-shares",
+ StorageUsersEndpoint: "com.owncloud.api.storage-users",
+ UsersEndpoint: "com.owncloud.api.users",
StorageRegistry: config.StorageRegistry{
Driver: "spaces",
diff --git a/services/gateway/pkg/revaconfig/config.go b/services/gateway/pkg/revaconfig/config.go
index 7654d3ea9..d9c5df0d9 100644
--- a/services/gateway/pkg/revaconfig/config.go
+++ b/services/gateway/pkg/revaconfig/config.go
@@ -6,9 +6,8 @@ import (
"strings"
"time"
- "github.com/owncloud/ocis/v2/ocis-pkg/log"
-
"github.com/cs3org/reva/v2/pkg/utils"
+ "github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/services/gateway/pkg/config"
)
diff --git a/services/graph/pkg/identity/cs3.go b/services/graph/pkg/identity/cs3.go
index 1f03170d1..a21ef4bbc 100644
--- a/services/graph/pkg/identity/cs3.go
+++ b/services/graph/pkg/identity/cs3.go
@@ -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,
})
diff --git a/services/graph/pkg/server/http/server.go b/services/graph/pkg/server/http/server.go
index 213cc7577..203ac1ee7 100644
--- a/services/graph/pkg/server/http/server.go
+++ b/services/graph/pkg/server/http/server.go
@@ -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),
diff --git a/services/graph/pkg/service/v0/application_test.go b/services/graph/pkg/service/v0/application_test.go
index 851e2ebed..dc136709c 100644
--- a/services/graph/pkg/service/v0/application_test.go
+++ b/services/graph/pkg/service/v0/application_test.go
@@ -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),
diff --git a/services/graph/pkg/service/v0/approleassignments_test.go b/services/graph/pkg/service/v0/approleassignments_test.go
index 7f37975a5..b67165c52 100644
--- a/services/graph/pkg/service/v0/approleassignments_test.go
+++ b/services/graph/pkg/service/v0/approleassignments_test.go
@@ -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),
diff --git a/services/graph/pkg/service/v0/driveitems.go b/services/graph/pkg/service/v0/driveitems.go
index 3c9d412b6..5a09f2876 100644
--- a/services/graph/pkg/service/v0/driveitems.go
+++ b/services/graph/pkg/service/v0/driveitems.go
@@ -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
}
diff --git a/services/graph/pkg/service/v0/driveitems_test.go b/services/graph/pkg/service/v0/driveitems_test.go
index b830cb14a..c907ec670 100644
--- a/services/graph/pkg/service/v0/driveitems_test.go
+++ b/services/graph/pkg/service/v0/driveitems_test.go
@@ -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),
)
diff --git a/services/graph/pkg/service/v0/drives.go b/services/graph/pkg/service/v0/drives.go
index 5cb2a4662..306da720f 100644
--- a/services/graph/pkg/service/v0/drives.go
+++ b/services/graph/pkg/service/v0/drives.go
@@ -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),
diff --git a/services/graph/pkg/service/v0/educationclasses_test.go b/services/graph/pkg/service/v0/educationclasses_test.go
index 50564cf8e..009d14d45 100644
--- a/services/graph/pkg/service/v0/educationclasses_test.go
+++ b/services/graph/pkg/service/v0/educationclasses_test.go
@@ -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),
diff --git a/services/graph/pkg/service/v0/educationschools_test.go b/services/graph/pkg/service/v0/educationschools_test.go
index 3bf5157fa..83358243f 100644
--- a/services/graph/pkg/service/v0/educationschools_test.go
+++ b/services/graph/pkg/service/v0/educationschools_test.go
@@ -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),
)
})
diff --git a/services/graph/pkg/service/v0/educationuser.go b/services/graph/pkg/service/v0/educationuser.go
index 3ddaf2374..ace630795 100644
--- a/services/graph/pkg/service/v0/educationuser.go
+++ b/services/graph/pkg/service/v0/educationuser.go
@@ -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,
diff --git a/services/graph/pkg/service/v0/educationuser_test.go b/services/graph/pkg/service/v0/educationuser_test.go
index 1d4a10407..80e5ed41d 100644
--- a/services/graph/pkg/service/v0/educationuser_test.go
+++ b/services/graph/pkg/service/v0/educationuser_test.go
@@ -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),
diff --git a/services/graph/pkg/service/v0/graph.go b/services/graph/pkg/service/v0/graph.go
index eab4903d4..86045e00a 100644
--- a/services/graph/pkg/service/v0/graph.go
+++ b/services/graph/pkg/service/v0/graph.go
@@ -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 {
diff --git a/services/graph/pkg/service/v0/graph_suite_test.go b/services/graph/pkg/service/v0/graph_suite_test.go
index 6b34ae063..7b6ed5b23 100644
--- a/services/graph/pkg/service/v0/graph_suite_test.go
+++ b/services/graph/pkg/service/v0/graph_suite_test.go
@@ -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")
diff --git a/services/graph/pkg/service/v0/graph_test.go b/services/graph/pkg/service/v0/graph_test.go
index 0b244d505..61a08d27b 100644
--- a/services/graph/pkg/service/v0/graph_test.go
+++ b/services/graph/pkg/service/v0/graph_test.go
@@ -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),
)
diff --git a/services/graph/pkg/service/v0/groups_test.go b/services/graph/pkg/service/v0/groups_test.go
index 2712641b6..598cbabef 100644
--- a/services/graph/pkg/service/v0/groups_test.go
+++ b/services/graph/pkg/service/v0/groups_test.go
@@ -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),
)
diff --git a/services/graph/pkg/service/v0/option.go b/services/graph/pkg/service/v0/option.go
index 51581ade7..a13714f54 100644
--- a/services/graph/pkg/service/v0/option.go
+++ b/services/graph/pkg/service/v0/option.go
@@ -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
}
}
diff --git a/services/graph/pkg/service/v0/password.go b/services/graph/pkg/service/v0/password.go
index 551c0e29f..231204088 100644
--- a/services/graph/pkg/service/v0/password.go
+++ b/services/graph/pkg/service/v0/password.go
@@ -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
diff --git a/services/graph/pkg/service/v0/password_test.go b/services/graph/pkg/service/v0/password_test.go
index 72bf4a07f..cb54ab6e5 100644
--- a/services/graph/pkg/service/v0/password_test.go
+++ b/services/graph/pkg/service/v0/password_test.go
@@ -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),
)
diff --git a/services/graph/pkg/service/v0/personaldata.go b/services/graph/pkg/service/v0/personaldata.go
index de263ea86..77bba3ab4 100644
--- a/services/graph/pkg/service/v0/personaldata.go
+++ b/services/graph/pkg/service/v0/personaldata.go
@@ -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
}
diff --git a/services/graph/pkg/service/v0/service.go b/services/graph/pkg/service/v0/service.go
index 86fe823dd..404e10a48 100644
--- a/services/graph/pkg/service/v0/service.go
+++ b/services/graph/pkg/service/v0/service.go
@@ -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
diff --git a/services/graph/pkg/service/v0/tags.go b/services/graph/pkg/service/v0/tags.go
index b3e95ef5e..786eb0e49 100644
--- a/services/graph/pkg/service/v0/tags.go
+++ b/services/graph/pkg/service/v0/tags.go
@@ -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{
diff --git a/services/graph/pkg/service/v0/users.go b/services/graph/pkg/service/v0/users.go
index be24c2ccc..7a8c0df04 100644
--- a/services/graph/pkg/service/v0/users.go
+++ b/services/graph/pkg/service/v0/users.go
@@ -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,
diff --git a/services/graph/pkg/service/v0/users_test.go b/services/graph/pkg/service/v0/users_test.go
index 4719f366e..5dbe88f5f 100644
--- a/services/graph/pkg/service/v0/users_test.go
+++ b/services/graph/pkg/service/v0/users_test.go
@@ -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),
diff --git a/services/groups/pkg/command/server.go b/services/groups/pkg/command/server.go
index 6605c3dfd..55a69ddfa 100644
--- a/services/groups/pkg/command/server.go
+++ b/services/groups/pkg/command/server.go
@@ -11,7 +11,7 @@ import (
"github.com/oklog/run"
"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
"github.com/owncloud/ocis/v2/ocis-pkg/ldap"
- "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/groups/pkg/config"
@@ -43,10 +43,6 @@ 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.GroupsConfigFromStruct(cfg)
-
// the reva runtime calls os.Exit in the case of a failure and there is no way for the oCIS
// runtime to catch it and restart a reva service. Therefore we need to ensure the service has
// everything it needs, before starting the service.
@@ -60,7 +56,15 @@ func Server(cfg *config.Config) *cli.Command {
}
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.GroupsConfigFromStruct(cfg)
+ reg := registry.GetRegistry()
+
+ runtime.RunWithOptions(rCfg, pidFile,
+ runtime.WithLogger(&logger.Logger),
+ runtime.WithRegistry(reg),
+ )
+
return nil
}, func(err error) {
logger.Error().
@@ -90,15 +94,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")
}
return gr.Run()
diff --git a/services/notifications/pkg/command/server.go b/services/notifications/pkg/command/server.go
index f1b623c2b..cfdd7a57a 100644
--- a/services/notifications/pkg/command/server.go
+++ b/services/notifications/pkg/command/server.go
@@ -15,6 +15,7 @@ import (
"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
"github.com/owncloud/ocis/v2/ocis-pkg/crypto"
"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
+ "github.com/owncloud/ocis/v2/ocis-pkg/registry"
"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
"github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -122,16 +123,17 @@ func Server(cfg *config.Config) *cli.Command {
if err != nil {
return err
}
- gwclient, err := pool.GetGatewayServiceClient(
+ gatewaySelector, err := pool.GatewaySelector(
cfg.Notifications.RevaGateway,
pool.WithTLSCACert(cfg.Notifications.GRPCClientTLS.CACert),
pool.WithTLSMode(tm),
+ pool.WithRegistry(registry.GetRegistry()),
)
if err != nil {
- logger.Fatal().Err(err).Str("addr", cfg.Notifications.RevaGateway).Msg("could not get reva client")
+ logger.Fatal().Err(err).Str("addr", cfg.Notifications.RevaGateway).Msg("could not get reva gateway selector")
}
valueService := settingssvc.NewValueService("com.owncloud.api.settings", grpc.DefaultClient())
- svc := service.NewEventsNotifier(evts, channel, logger, gwclient, valueService, cfg.Notifications.MachineAuthAPIKey, cfg.Notifications.EmailTemplatePath, cfg.WebUIURL)
+ svc := service.NewEventsNotifier(evts, channel, logger, gatewaySelector, valueService, cfg.Notifications.MachineAuthAPIKey, cfg.Notifications.EmailTemplatePath, cfg.WebUIURL)
gr.Add(svc.Run, func(error) {
cancel()
diff --git a/services/notifications/pkg/service/notification_suite_test.go b/services/notifications/pkg/service/notification_suite_test.go
index 5735c73ff..dc3c1f425 100644
--- a/services/notifications/pkg/service/notification_suite_test.go
+++ b/services/notifications/pkg/service/notification_suite_test.go
@@ -3,10 +3,24 @@ package service_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 TestNotifications(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Notification Suite")
diff --git a/services/notifications/pkg/service/service.go b/services/notifications/pkg/service/service.go
index b187f81dd..c55eef6af 100644
--- a/services/notifications/pkg/service/service.go
+++ b/services/notifications/pkg/service/service.go
@@ -16,6 +16,7 @@ import (
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/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/ocis-pkg/middleware"
settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
@@ -38,7 +39,7 @@ func NewEventsNotifier(
events <-chan events.Event,
channel channels.Channel,
logger log.Logger,
- gwClient gateway.GatewayAPIClient,
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient],
valueService settingssvc.ValueService,
machineAuthAPIKey, emailTemplatePath, ocisURL string) Service {
@@ -47,7 +48,7 @@ func NewEventsNotifier(
channel: channel,
events: events,
signals: make(chan os.Signal, 1),
- gwClient: gwClient,
+ gatewaySelector: gatewaySelector,
valueService: valueService,
machineAuthAPIKey: machineAuthAPIKey,
emailTemplatePath: emailTemplatePath,
@@ -60,7 +61,7 @@ type eventsNotifier struct {
channel channels.Channel
events <-chan events.Event
signals chan os.Signal
- gwClient gateway.GatewayAPIClient
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
valueService settingssvc.ValueService
machineAuthAPIKey string
emailTemplatePath string
@@ -137,7 +138,12 @@ func (s eventsNotifier) getGranteeList(ctx context.Context, executant, u *user.U
}
return []*user.User{usr}, nil
case g != nil:
- res, err := s.gwClient.GetGroup(ctx, &group.GetGroupRequest{GroupId: g})
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ res, err := gatewayClient.GetGroup(ctx, &group.GetGroupRequest{GroupId: g})
if err != nil {
return nil, err
}
@@ -171,7 +177,11 @@ func (s eventsNotifier) getUser(ctx context.Context, u *user.UserId) (*user.User
if u == nil {
return nil, errors.New("need at least one non-nil grantee")
}
- r, err := s.gwClient.GetUser(ctx, &user.GetUserRequest{UserId: u})
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ r, err := gatewayClient.GetUser(ctx, &user.GetUserRequest{UserId: u})
if err != nil {
return nil, err
}
@@ -213,7 +223,12 @@ func (s eventsNotifier) disableEmails(ctx context.Context, u *user.UserId) bool
func (s eventsNotifier) getResourceInfo(ctx context.Context, resourceID *provider.ResourceId, fieldmask *fieldmaskpb.FieldMask) (*provider.ResourceInfo, error) {
// TODO: maybe cache this stat to reduce storage iops
- md, err := s.gwClient.Stat(ctx, &provider.StatRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ md, err := gatewayClient.Stat(ctx, &provider.StatRequest{
Ref: &provider.Reference{
ResourceId: resourceID,
},
diff --git a/services/notifications/pkg/service/service_test.go b/services/notifications/pkg/service/service_test.go
index 925fcc4bb..8497d75d5 100644
--- a/services/notifications/pkg/service/service_test.go
+++ b/services/notifications/pkg/service/service_test.go
@@ -9,6 +9,7 @@ import (
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/v2/pkg/events"
+ "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"
@@ -22,13 +23,15 @@ import (
"github.com/owncloud/ocis/v2/services/notifications/pkg/service"
"github.com/test-go/testify/mock"
"go-micro.dev/v4/client"
+ "google.golang.org/grpc"
)
var _ = Describe("Notifications", func() {
var (
- gwc *cs3mocks.GatewayAPIClient
- vs *settingssvc.MockValueService
- sharer = &user.User{
+ gatewayClient *cs3mocks.GatewayAPIClient
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
+ vs *settingssvc.MockValueService
+ sharer = &user.User{
Id: &user.UserId{
OpaqueId: "sharer",
},
@@ -50,11 +53,20 @@ var _ = Describe("Notifications", func() {
)
BeforeEach(func() {
- gwc = &cs3mocks.GatewayAPIClient{}
- gwc.On("GetUser", mock.Anything, mock.Anything).Return(&user.GetUserResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}, User: sharer}, nil).Once()
- gwc.On("GetUser", mock.Anything, mock.Anything).Return(&user.GetUserResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}, User: sharee}, nil).Once()
- gwc.On("Authenticate", mock.Anything, mock.Anything).Return(&gateway.AuthenticateResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}, User: sharer}, nil)
- gwc.On("Stat", mock.Anything, mock.Anything).Return(&provider.StatResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}, Info: &provider.ResourceInfo{Name: "secrets of the board", Space: &provider.StorageSpace{Name: "secret space"}}}, 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
+ },
+ )
+
+ gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(&user.GetUserResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}, User: sharer}, nil).Once()
+ gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(&user.GetUserResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}, User: sharee}, nil).Once()
+ gatewayClient.On("Authenticate", mock.Anything, mock.Anything).Return(&gateway.AuthenticateResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}, User: sharer}, nil)
+ gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(&provider.StatResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}, Info: &provider.ResourceInfo{Name: "secrets of the board", Space: &provider.StorageSpace{Name: "secret space"}}}, nil)
vs = &settingssvc.MockValueService{}
vs.GetValueByUniqueIdentifiersFunc = func(ctx context.Context, req *settingssvc.GetValueByUniqueIdentifiersRequest, opts ...client.CallOption) (*settingssvc.GetValueResponse, error) {
return nil, nil
@@ -67,7 +79,7 @@ var _ = Describe("Notifications", func() {
cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
_ = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
ch := make(chan events.Event)
- evts := service.NewEventsNotifier(ch, tc, log.NewLogger(), gwc, vs, "", "", "")
+ evts := service.NewEventsNotifier(ch, tc, log.NewLogger(), gatewaySelector, vs, "", "", "")
go evts.Run()
ch <- ev
@@ -210,9 +222,10 @@ https://owncloud.com
var _ = Describe("Notifications X-Site Scripting", func() {
var (
- gwc *cs3mocks.GatewayAPIClient
- vs *settingssvc.MockValueService
- sharer = &user.User{
+ gatewayClient *cs3mocks.GatewayAPIClient
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
+ vs *settingssvc.MockValueService
+ sharer = &user.User{
Id: &user.UserId{
OpaqueId: "sharer",
},
@@ -234,11 +247,20 @@ var _ = Describe("Notifications X-Site Scripting", func() {
)
BeforeEach(func() {
- gwc = &cs3mocks.GatewayAPIClient{}
- gwc.On("GetUser", mock.Anything, mock.Anything).Return(&user.GetUserResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}, User: sharer}, nil).Once()
- gwc.On("GetUser", mock.Anything, mock.Anything).Return(&user.GetUserResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}, User: sharee}, nil).Once()
- gwc.On("Authenticate", mock.Anything, mock.Anything).Return(&gateway.AuthenticateResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}, User: sharer}, nil)
- gwc.On("Stat", mock.Anything, mock.Anything).Return(&provider.StatResponse{
+ 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
+ },
+ )
+
+ gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(&user.GetUserResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}, User: sharer}, nil).Once()
+ gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(&user.GetUserResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}, User: sharee}, nil).Once()
+ gatewayClient.On("Authenticate", mock.Anything, mock.Anything).Return(&gateway.AuthenticateResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}, User: sharer}, nil)
+ gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(&provider.StatResponse{
Status: &rpc.Status{Code: rpc.Code_CODE_OK},
Info: &provider.ResourceInfo{
Name: "",
@@ -256,7 +278,7 @@ var _ = Describe("Notifications X-Site Scripting", func() {
cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
_ = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
ch := make(chan events.Event)
- evts := service.NewEventsNotifier(ch, tc, log.NewLogger(), gwc, vs, "", "", "")
+ evts := service.NewEventsNotifier(ch, tc, log.NewLogger(), gatewaySelector, vs, "", "", "")
go evts.Run()
ch <- ev
diff --git a/services/notifications/pkg/service/shares.go b/services/notifications/pkg/service/shares.go
index c4349436e..9328c7f88 100644
--- a/services/notifications/pkg/service/shares.go
+++ b/services/notifications/pkg/service/shares.go
@@ -13,7 +13,13 @@ func (s eventsNotifier) handleShareCreated(e events.ShareCreated) {
Str("itemid", e.ItemID.OpaqueId).
Logger()
- ownerCtx, owner, err := utils.Impersonate(e.Sharer, s.gwClient, s.machineAuthAPIKey)
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ logger.Error().Err(err).Msg("could not select next gateway client")
+ return
+ }
+
+ ownerCtx, owner, err := utils.Impersonate(e.Sharer, gatewayClient, s.machineAuthAPIKey)
if err != nil {
logger.Error().Err(err).Msg("Could not impersonate sharer")
return
@@ -62,7 +68,13 @@ func (s eventsNotifier) handleShareExpired(e events.ShareExpired) {
Str("itemid", e.ItemID.GetOpaqueId()).
Logger()
- ownerCtx, owner, err := utils.Impersonate(e.ShareOwner, s.gwClient, s.machineAuthAPIKey)
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ logger.Error().Err(err).Msg("could not select next gateway client")
+ return
+ }
+
+ ownerCtx, owner, err := utils.Impersonate(e.ShareOwner, gatewayClient, s.machineAuthAPIKey)
if err != nil {
logger.Error().Err(err).Msg("Could not impersonate sharer")
return
diff --git a/services/notifications/pkg/service/spaces.go b/services/notifications/pkg/service/spaces.go
index d764e9f5a..cd8f07278 100644
--- a/services/notifications/pkg/service/spaces.go
+++ b/services/notifications/pkg/service/spaces.go
@@ -13,7 +13,13 @@ func (s eventsNotifier) handleSpaceShared(e events.SpaceShared) {
Str("itemid", e.ID.OpaqueId).
Logger()
- executantCtx, executant, err := utils.Impersonate(e.Executant, s.gwClient, s.machineAuthAPIKey)
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ logger.Error().Err(err).Msg("could not select next gateway client")
+ return
+ }
+
+ executantCtx, executant, err := utils.Impersonate(e.Executant, gatewayClient, s.machineAuthAPIKey)
if err != nil {
logger.Error().
Err(err).
@@ -75,7 +81,13 @@ func (s eventsNotifier) handleSpaceUnshared(e events.SpaceUnshared) {
Str("itemid", e.ID.OpaqueId).
Logger()
- executantCtx, executant, err := utils.Impersonate(e.Executant, s.gwClient, s.machineAuthAPIKey)
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ logger.Error().Err(err).Msg("could not select next gateway client")
+ return
+ }
+
+ executantCtx, executant, err := utils.Impersonate(e.Executant, gatewayClient, s.machineAuthAPIKey)
if err != nil {
logger.Error().Err(err).Msg("could not handle space unshared event")
return
@@ -135,7 +147,13 @@ func (s eventsNotifier) handleSpaceMembershipExpired(e events.SpaceMembershipExp
Str("itemid", e.SpaceID.GetOpaqueId()).
Logger()
- ownerCtx, owner, err := utils.Impersonate(e.SpaceOwner, s.gwClient, s.machineAuthAPIKey)
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ logger.Error().Err(err).Msg("could not select next gateway client")
+ return
+ }
+
+ ownerCtx, owner, err := utils.Impersonate(e.SpaceOwner, gatewayClient, s.machineAuthAPIKey)
if err != nil {
logger.Error().Err(err).Msg("Could not impersonate sharer")
return
diff --git a/services/proxy/pkg/command/server.go b/services/proxy/pkg/command/server.go
index 11b18850d..5c89ffa51 100644
--- a/services/proxy/pkg/command/server.go
+++ b/services/proxy/pkg/command/server.go
@@ -20,6 +20,7 @@ import (
"github.com/owncloud/ocis/v2/ocis-pkg/log"
pkgmiddleware "github.com/owncloud/ocis/v2/ocis-pkg/middleware"
"github.com/owncloud/ocis/v2/ocis-pkg/oidc"
+ "github.com/owncloud/ocis/v2/ocis-pkg/registry"
"github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
"github.com/owncloud/ocis/v2/ocis-pkg/version"
settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
@@ -276,9 +277,9 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config,
logger.Fatal().Err(err).Msg("Failed to get gateway client")
}
rolesClient := settingssvc.NewRoleService("com.owncloud.api.settings", grpcClient)
- revaClient, err := pool.GetGatewayServiceClient(cfg.Reva.Address, cfg.Reva.GetRevaOptions()...)
+ gatewaySelector, err := pool.GatewaySelector(cfg.Reva.Address, append(cfg.Reva.GetRevaOptions(), pool.WithRegistry(registry.GetRegistry()))...)
if err != nil {
- logger.Fatal().Err(err).Msg("Failed to get gateway client")
+ logger.Fatal().Err(err).Msg("Failed to get gateway selector")
}
tokenManager, err := jwt.New(map[string]interface{}{
"secret": cfg.TokenManager.JWTSecret,
@@ -291,10 +292,9 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config,
var userProvider backend.UserBackend
switch cfg.AccountBackend {
case "cs3":
-
userProvider = backend.NewCS3UserBackend(
backend.WithLogger(logger),
- backend.WithRevaAuthenticator(revaClient),
+ backend.WithRevaGatewaySelector(gatewaySelector),
backend.WithMachineAuthAPIKey(cfg.MachineAuthAPIKey),
backend.WithOIDCissuer(cfg.OIDC.Issuer),
backend.WithAutoProvisonCreator(autoProvsionCreator),
@@ -364,8 +364,8 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config,
)),
))
authenticators = append(authenticators, middleware.PublicShareAuthenticator{
- Logger: logger,
- RevaGatewayClient: revaClient,
+ Logger: logger,
+ RevaGatewaySelector: gatewaySelector,
})
authenticators = append(authenticators, middleware.SignedURLAuthenticator{
Logger: logger,
@@ -412,7 +412,7 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config,
// finally, trigger home creation when a user logs in
middleware.CreateHome(
middleware.Logger(logger),
- middleware.RevaGatewayClient(revaClient),
+ middleware.WithRevaGatewaySelector(gatewaySelector),
middleware.RoleQuotas(cfg.RoleQuotas),
),
)
diff --git a/services/proxy/pkg/middleware/create_home.go b/services/proxy/pkg/middleware/create_home.go
index cc4abf778..f7da59a0e 100644
--- a/services/proxy/pkg/middleware/create_home.go
+++ b/services/proxy/pkg/middleware/create_home.go
@@ -10,6 +10,7 @@ import (
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/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"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
@@ -23,19 +24,19 @@ func CreateHome(optionSetters ...Option) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return &createHome{
- next: next,
- logger: logger,
- revaGatewayClient: options.RevaGatewayClient,
- roleQuotas: options.RoleQuotas,
+ next: next,
+ logger: logger,
+ revaGatewaySelector: options.RevaGatewaySelector,
+ roleQuotas: options.RoleQuotas,
}
}
}
type createHome struct {
- next http.Handler
- logger log.Logger
- revaGatewayClient gateway.GatewayAPIClient
- roleQuotas map[string]uint64
+ next http.Handler
+ logger log.Logger
+ revaGatewaySelector pool.Selectable[gateway.GatewayAPIClient]
+ roleQuotas map[string]uint64
}
func (m createHome) ServeHTTP(w http.ResponseWriter, req *http.Request) {
@@ -64,14 +65,18 @@ func (m createHome) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
}
- createHomeRes, err := m.revaGatewayClient.CreateHome(ctx, createHomeReq)
-
+ client, err := m.revaGatewaySelector.Next()
if err != nil {
- m.logger.Err(err).Msg("error calling CreateHome")
- } else if createHomeRes.Status.Code != rpc.Code_CODE_OK {
- err := status.NewErrorFromCode(createHomeRes.Status.Code, "gateway")
- if createHomeRes.Status.Code != rpc.Code_CODE_ALREADY_EXISTS {
- m.logger.Err(err).Msg("error when calling Createhome")
+ m.logger.Err(err).Msg("error selecting next gateway client")
+ } else {
+ createHomeRes, err := client.CreateHome(ctx, createHomeReq)
+ if err != nil {
+ m.logger.Err(err).Msg("error calling CreateHome")
+ } else if createHomeRes.Status.Code != rpc.Code_CODE_OK {
+ err := status.NewErrorFromCode(createHomeRes.Status.Code, "gateway")
+ if createHomeRes.Status.Code != rpc.Code_CODE_ALREADY_EXISTS {
+ m.logger.Err(err).Msg("error when calling Createhome")
+ }
}
}
diff --git a/services/proxy/pkg/middleware/options.go b/services/proxy/pkg/middleware/options.go
index d4759079f..edfb39fc8 100644
--- a/services/proxy/pkg/middleware/options.go
+++ b/services/proxy/pkg/middleware/options.go
@@ -5,6 +5,7 @@ import (
"time"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/ocis-pkg/oidc"
settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
@@ -38,8 +39,8 @@ type Options struct {
OIDCClient oidc.OIDCClient
// OIDCIss is the oidcAuth-issuer
OIDCIss string
- // RevaGatewayClient to send requests to the reva gateway
- RevaGatewayClient gateway.GatewayAPIClient
+ // RevaGatewaySelector to send requests to the reva gateway
+ RevaGatewaySelector pool.Selectable[gateway.GatewayAPIClient]
// Store for persisting data
Store storesvc.StoreService
// PreSignedURLConfig to configure the middleware
@@ -135,10 +136,10 @@ func CredentialsByUserAgent(v map[string]string) Option {
}
}
-// RevaGatewayClient provides a function to set the the reva gateway service client option.
-func RevaGatewayClient(gc gateway.GatewayAPIClient) Option {
+// WithRevaGatewaySelector provides a function to set the the reva gateway service selector option.
+func WithRevaGatewaySelector(val pool.Selectable[gateway.GatewayAPIClient]) Option {
return func(o *Options) {
- o.RevaGatewayClient = gc
+ o.RevaGatewaySelector = val
}
}
diff --git a/services/proxy/pkg/middleware/public_share_auth.go b/services/proxy/pkg/middleware/public_share_auth.go
index 0f7d8004c..f66e030a0 100644
--- a/services/proxy/pkg/middleware/public_share_auth.go
+++ b/services/proxy/pkg/middleware/public_share_auth.go
@@ -5,6 +5,7 @@ import (
"strings"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
)
@@ -21,8 +22,8 @@ const (
// PublicShareAuthenticator is the authenticator which can authenticate public share requests.
// It will add the share owner into the request context.
type PublicShareAuthenticator struct {
- Logger log.Logger
- RevaGatewayClient gateway.GatewayAPIClient
+ Logger log.Logger
+ RevaGatewaySelector pool.Selectable[gateway.GatewayAPIClient]
}
// The archiver is able to create archives from public shares in which case it needs to use the
@@ -83,7 +84,18 @@ func (a PublicShareAuthenticator) Authenticate(r *http.Request) (*http.Request,
}
}
- authResp, err := a.RevaGatewayClient.Authenticate(r.Context(), &gateway.AuthenticateRequest{
+ client, err := a.RevaGatewaySelector.Next()
+ if err != nil {
+ a.Logger.Error().
+ Err(err).
+ Str("authenticator", "public_share").
+ Str("public_share_token", shareToken).
+ Str("path", r.URL.Path).
+ Msg("could not select next gateway client")
+ return nil, false
+ }
+
+ authResp, err := client.Authenticate(r.Context(), &gateway.AuthenticateRequest{
Type: authenticationType,
ClientId: shareToken,
ClientSecret: sharePassword,
diff --git a/services/proxy/pkg/middleware/public_share_auth_test.go b/services/proxy/pkg/middleware/public_share_auth_test.go
index 4df9a47ca..5c3aad445 100644
--- a/services/proxy/pkg/middleware/public_share_auth_test.go
+++ b/services/proxy/pkg/middleware/public_share_auth_test.go
@@ -5,8 +5,10 @@ import (
"net/http"
"net/http/httptest"
+ gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
@@ -18,23 +20,29 @@ var _ = Describe("Authenticating requests", Label("PublicShareAuthenticator"), f
BeforeEach(func() {
authenticator = PublicShareAuthenticator{
Logger: log.NewLogger(),
- RevaGatewayClient: mockGatewayClient{
- AuthenticateFunc: func(authType, clientID, clientSecret string) (string, rpcv1beta1.Code) {
- if authType != "publicshares" {
- return "", rpcv1beta1.Code_CODE_NOT_FOUND
- }
+ RevaGatewaySelector: pool.GetSelector[gateway.GatewayAPIClient](
+ "GatewaySelector",
+ "com.owncloud.api.gateway",
+ func(cc *grpc.ClientConn) gateway.GatewayAPIClient {
+ return mockGatewayClient{
+ AuthenticateFunc: func(authType, clientID, clientSecret string) (string, rpcv1beta1.Code) {
+ if authType != "publicshares" {
+ return "", rpcv1beta1.Code_CODE_NOT_FOUND
+ }
- if clientID == "sharetoken" && (clientSecret == "password|examples3cr3t" || clientSecret == "signature|examplesignature|exampleexpiration") {
- return "exampletoken", rpcv1beta1.Code_CODE_OK
- }
+ if clientID == "sharetoken" && (clientSecret == "password|examples3cr3t" || clientSecret == "signature|examplesignature|exampleexpiration") {
+ return "exampletoken", rpcv1beta1.Code_CODE_OK
+ }
- if clientID == "sharetoken" && clientSecret == "password|" {
- return "otherexampletoken", rpcv1beta1.Code_CODE_OK
- }
+ if clientID == "sharetoken" && clientSecret == "password|" {
+ return "otherexampletoken", rpcv1beta1.Code_CODE_OK
+ }
- return "", rpcv1beta1.Code_CODE_NOT_FOUND
+ return "", rpcv1beta1.Code_CODE_NOT_FOUND
+ },
+ }
},
- },
+ ),
}
})
When("the request contains correct data", func() {
diff --git a/services/proxy/pkg/user/backend/backend.go b/services/proxy/pkg/user/backend/backend.go
index efce21d55..8ff2c254a 100644
--- a/services/proxy/pkg/user/backend/backend.go
+++ b/services/proxy/pkg/user/backend/backend.go
@@ -4,9 +4,7 @@ import (
"context"
"errors"
- gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
cs3 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
- "google.golang.org/grpc"
)
var (
@@ -26,8 +24,3 @@ type UserBackend interface {
Authenticate(ctx context.Context, username string, password string) (*cs3.User, string, error)
CreateUserFromClaims(ctx context.Context, claims map[string]interface{}) (*cs3.User, error)
}
-
-// RevaAuthenticator helper interface to mock auth-method from reva gateway-client.
-type RevaAuthenticator interface {
- Authenticate(ctx context.Context, in *gateway.AuthenticateRequest, opts ...grpc.CallOption) (*gateway.AuthenticateResponse, error)
-}
diff --git a/services/proxy/pkg/user/backend/cs3.go b/services/proxy/pkg/user/backend/cs3.go
index 0dcbc8fd1..6a006fb9c 100644
--- a/services/proxy/pkg/user/backend/cs3.go
+++ b/services/proxy/pkg/user/backend/cs3.go
@@ -11,6 +11,7 @@ import (
cs3 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
revactx "github.com/cs3org/reva/v2/pkg/ctx"
+ "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/oidc"
@@ -31,7 +32,7 @@ type Option func(o *Options)
// Options defines the available options for this package.
type Options struct {
logger log.Logger
- authProvider RevaAuthenticator
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
machineAuthAPIKey string
oidcISS string
autoProvsionCreator autoprovision.Creator
@@ -44,10 +45,10 @@ func WithLogger(l log.Logger) Option {
}
}
-// WithRevaAuthenticator set the RevaAuthenticator option
-func WithRevaAuthenticator(ra RevaAuthenticator) Option {
+// WithRevaGatewaySelector set the gatewaySelector option
+func WithRevaGatewaySelector(selectable pool.Selectable[gateway.GatewayAPIClient]) Option {
return func(o *Options) {
- o.authProvider = ra
+ o.gatewaySelector = selectable
}
}
@@ -91,7 +92,12 @@ func NewCS3UserBackend(opts ...Option) UserBackend {
}
func (c *cs3backend) GetUserByClaims(ctx context.Context, claim, value string) (*cs3.User, string, error) {
- res, err := c.authProvider.Authenticate(ctx, &gateway.AuthenticateRequest{
+ gatewayClient, err := c.gatewaySelector.Next()
+ if err != nil {
+ return nil, "", fmt.Errorf("could not obtain gatewayClient: %s", err)
+ }
+
+ res, err := gatewayClient.Authenticate(ctx, &gateway.AuthenticateRequest{
Type: "machine",
ClientId: claim + ":" + value,
ClientSecret: c.machineAuthAPIKey,
@@ -113,7 +119,12 @@ func (c *cs3backend) GetUserByClaims(ctx context.Context, claim, value string) (
}
func (c *cs3backend) Authenticate(ctx context.Context, username string, password string) (*cs3.User, string, error) {
- res, err := c.authProvider.Authenticate(ctx, &gateway.AuthenticateRequest{
+ gatewayClient, err := c.gatewaySelector.Next()
+ if err != nil {
+ return nil, "", fmt.Errorf("could not obtain gatewayClient: %s", err)
+ }
+
+ res, err := gatewayClient.Authenticate(ctx, &gateway.AuthenticateRequest{
Type: "basic",
ClientId: username,
ClientSecret: password,
diff --git a/services/proxy/pkg/userroles/defaultrole.go b/services/proxy/pkg/userroles/defaultrole.go
index d1a59eb2d..29125177f 100644
--- a/services/proxy/pkg/userroles/defaultrole.go
+++ b/services/proxy/pkg/userroles/defaultrole.go
@@ -35,7 +35,7 @@ func (d defaultRoleAssigner) UpdateUserRoleAssignment(ctx context.Context, user
var err error
roleIDs, err = loadRolesIDs(ctx, user.Id.OpaqueId, d.roleService)
if err != nil {
- d.logger.Error().Err(err).Msgf("Could not load roles")
+ d.logger.Error().Err(err).Msg("Could not load roles")
return nil, err
}
@@ -68,7 +68,7 @@ func (d defaultRoleAssigner) UpdateUserRoleAssignment(ctx context.Context, user
func (d defaultRoleAssigner) ApplyUserRole(ctx context.Context, user *cs3.User) (*cs3.User, error) {
roleIDs, err := loadRolesIDs(ctx, user.Id.OpaqueId, d.roleService)
if err != nil {
- d.logger.Error().Err(err).Msgf("Could not load roles")
+ d.logger.Error().Err(err).Msg("Could not load roles")
return nil, err
}
diff --git a/services/proxy/pkg/userroles/oidcroles.go b/services/proxy/pkg/userroles/oidcroles.go
index 0d36c922f..65a5a2aa0 100644
--- a/services/proxy/pkg/userroles/oidcroles.go
+++ b/services/proxy/pkg/userroles/oidcroles.go
@@ -120,7 +120,7 @@ func (ra oidcRoleAssigner) UpdateUserRoleAssignment(ctx context.Context, user *c
func (ra oidcRoleAssigner) ApplyUserRole(ctx context.Context, user *cs3.User) (*cs3.User, error) {
roleIDs, err := loadRolesIDs(ctx, user.Id.OpaqueId, ra.roleService)
if err != nil {
- ra.logger.Error().Err(err).Msgf("Could not load roles")
+ ra.logger.Error().Err(err).Msg("Could not load roles")
return nil, err
}
diff --git a/services/search/pkg/content/cs3.go b/services/search/pkg/content/cs3.go
index 9d2332fdc..4a90e85a9 100644
--- a/services/search/pkg/content/cs3.go
+++ b/services/search/pkg/content/cs3.go
@@ -11,24 +11,25 @@ import (
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
revactx "github.com/cs3org/reva/v2/pkg/ctx"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
)
type cs3 struct {
- httpClient http.Client
- gwClient gateway.GatewayAPIClient
- logger log.Logger
+ httpClient http.Client
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
+ logger log.Logger
}
-func newCS3Retriever(client gateway.GatewayAPIClient, logger log.Logger, insecure bool) cs3 {
+func newCS3Retriever(gatewaySelector pool.Selectable[gateway.GatewayAPIClient], logger log.Logger, insecure bool) cs3 {
return cs3{
httpClient: http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: insecure}, //nolint:gosec
},
},
- gwClient: client,
- logger: logger,
+ gatewaySelector: gatewaySelector,
+ logger: logger,
}
}
@@ -40,7 +41,13 @@ func (s cs3) Retrieve(ctx context.Context, rID *provider.ResourceId) (io.ReadClo
return nil, fmt.Errorf("context without %s", revactx.TokenHeader)
}
- res, err := s.gwClient.InitiateFileDownload(ctx, &provider.InitiateFileDownloadRequest{Ref: &provider.Reference{ResourceId: rID, Path: "."}})
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ s.logger.Error().Err(err).Msg("could not get reva gatewayClient")
+ return nil, err
+ }
+
+ res, err := gatewayClient.InitiateFileDownload(ctx, &provider.InitiateFileDownloadRequest{Ref: &provider.Reference{ResourceId: rID, Path: "."}})
if err != nil {
return nil, err
}
diff --git a/services/search/pkg/content/tika.go b/services/search/pkg/content/tika.go
index 46283a4c1..1979cdbcd 100644
--- a/services/search/pkg/content/tika.go
+++ b/services/search/pkg/content/tika.go
@@ -8,6 +8,7 @@ import (
"github.com/bbalet/stopwords"
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/todo/pool"
"github.com/google/go-tika/tika"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/services/search/pkg/config"
@@ -23,7 +24,7 @@ type Tika struct {
}
// NewTikaExtractor creates a new Tika instance.
-func NewTikaExtractor(gw gateway.GatewayAPIClient, logger log.Logger, cfg *config.Config) (*Tika, error) {
+func NewTikaExtractor(gatewaySelector pool.Selectable[gateway.GatewayAPIClient], logger log.Logger, cfg *config.Config) (*Tika, error) {
basic, err := NewBasicExtractor(logger)
if err != nil {
return nil, err
@@ -38,7 +39,7 @@ func NewTikaExtractor(gw gateway.GatewayAPIClient, logger log.Logger, cfg *confi
return &Tika{
Basic: basic,
- Retriever: newCS3Retriever(gw, logger, cfg.Extractor.CS3AllowInsecure),
+ Retriever: newCS3Retriever(gatewaySelector, logger, cfg.Extractor.CS3AllowInsecure),
tika: tika.NewClient(nil, cfg.Extractor.Tika.TikaURL),
contentExtractionSizeLimit: cfg.ContentExtractionSizeLimit,
}, nil
diff --git a/services/search/pkg/search/search.go b/services/search/pkg/search/search.go
index 4dbd89241..b4a1ad749 100644
--- a/services/search/pkg/search/search.go
+++ b/services/search/pkg/search/search.go
@@ -12,6 +12,7 @@ import (
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/errtypes"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/utils"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
searchmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/search/v0"
@@ -20,12 +21,17 @@ import (
)
// ResolveReference makes sure the path is relative to the space root
-func ResolveReference(ctx context.Context, ref *provider.Reference, ri *provider.ResourceInfo, gw gateway.GatewayAPIClient) (*provider.Reference, error) {
+func ResolveReference(ctx context.Context, ref *provider.Reference, ri *provider.ResourceInfo, gatewaySelector pool.Selectable[gateway.GatewayAPIClient]) (*provider.Reference, error) {
if ref.GetResourceId().GetOpaqueId() == ref.GetResourceId().GetSpaceId() {
return ref, nil
}
- gpRes, err := gw.GetPath(ctx, &provider.GetPathRequest{
+ gatewayClient, err := gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ gpRes, err := gatewayClient.GetPath(ctx, &provider.GetPathRequest{
ResourceId: ri.Id,
})
if err != nil || gpRes.Status.Code != rpc.Code_CODE_OK {
@@ -61,9 +67,15 @@ func logDocCount(engine engine.Engine, logger log.Logger) {
logger.Debug().Interface("count", c).Msg("new document count")
}
-func getAuthContext(owner *user.User, gw gateway.GatewayAPIClient, secret string, logger log.Logger) (context.Context, error) {
+func getAuthContext(owner *user.User, gatewaySelector pool.Selectable[gateway.GatewayAPIClient], secret string, logger log.Logger) (context.Context, error) {
+ gatewayClient, err := gatewaySelector.Next()
+ if err != nil {
+ logger.Error().Err(err).Msg("could not get reva gatewayClient")
+ return nil, err
+ }
+
ownerCtx := ctxpkg.ContextSetUser(context.Background(), owner)
- authRes, err := gw.Authenticate(ownerCtx, &gateway.AuthenticateRequest{
+ authRes, err := gatewayClient.Authenticate(ownerCtx, &gateway.AuthenticateRequest{
Type: "machine",
ClientId: "userid:" + owner.GetId().GetOpaqueId(),
ClientSecret: secret,
@@ -81,8 +93,13 @@ func getAuthContext(owner *user.User, gw gateway.GatewayAPIClient, secret string
return metadata.AppendToOutgoingContext(ownerCtx, ctxpkg.TokenHeader, authRes.Token), nil
}
-func statResource(ctx context.Context, ref *provider.Reference, gw gateway.GatewayAPIClient, logger log.Logger) (*provider.StatResponse, error) {
- res, err := gw.Stat(ctx, &provider.StatRequest{Ref: ref})
+func statResource(ctx context.Context, ref *provider.Reference, gatewaySelector pool.Selectable[gateway.GatewayAPIClient], logger log.Logger) (*provider.StatResponse, error) {
+ gatewayClient, err := gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ res, err := gatewayClient.Stat(ctx, &provider.StatRequest{Ref: ref})
if err != nil {
logger.Error().Err(err).Msg("failed to stat the moved resource")
return nil, err
diff --git a/services/search/pkg/search/search_suite_test.go b/services/search/pkg/search/search_suite_test.go
index 9b2060ec0..75873d6da 100644
--- a/services/search/pkg/search/search_suite_test.go
+++ b/services/search/pkg/search/search_suite_test.go
@@ -3,10 +3,23 @@ package search_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 TestSearch(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Search Suite")
diff --git a/services/search/pkg/search/service.go b/services/search/pkg/search/service.go
index 8407ae67f..9367d7e49 100644
--- a/services/search/pkg/search/service.go
+++ b/services/search/pkg/search/service.go
@@ -13,6 +13,7 @@ import (
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "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"
sdk "github.com/cs3org/reva/v2/pkg/sdk/common"
"github.com/cs3org/reva/v2/pkg/storage/utils/walker"
"github.com/cs3org/reva/v2/pkg/storagespace"
@@ -46,23 +47,23 @@ type Searcher interface {
// Service is responsible for indexing spaces and pass on a search
// to it's underlying engine.
type Service struct {
- logger log.Logger
- gateway gateway.GatewayAPIClient
- engine engine.Engine
- extractor content.Extractor
- secret string
+ logger log.Logger
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
+ engine engine.Engine
+ extractor content.Extractor
+ secret string
}
var errSkipSpace error
// NewService creates a new Provider instance.
-func NewService(gw gateway.GatewayAPIClient, eng engine.Engine, extractor content.Extractor, logger log.Logger, cfg *config.Config) *Service {
+func NewService(gatewaySelector pool.Selectable[gateway.GatewayAPIClient], eng engine.Engine, extractor content.Extractor, logger log.Logger, cfg *config.Config) *Service {
var s = &Service{
- gateway: gw,
- engine: eng,
- secret: cfg.MachineAuthAPIKey,
- logger: logger,
- extractor: extractor,
+ gatewaySelector: gatewaySelector,
+ engine: eng,
+ secret: cfg.MachineAuthAPIKey,
+ logger: logger,
+ extractor: extractor,
}
return s
@@ -75,7 +76,12 @@ func (s *Service) Search(ctx context.Context, req *searchsvc.SearchRequest) (*se
}
s.logger.Debug().Str("query", req.Query).Msg("performing a search")
- listSpacesRes, err := s.gateway.ListStorageSpaces(ctx, &provider.ListStorageSpacesRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ listSpacesRes, err := gatewayClient.ListStorageSpaces(ctx, &provider.ListStorageSpacesRequest{
Filters: []*provider.ListStorageSpacesRequest_Filter{
{
Type: provider.ListStorageSpacesRequest_Filter_TYPE_SPACE_TYPE,
@@ -227,7 +233,13 @@ func (s *Service) searchIndex(ctx context.Context, req *searchsvc.SearchRequest,
s.logger.Warn().Interface("space", space).Msg("could not find mountpoint space for grant space")
return nil, errSkipSpace
}
- gpRes, err := s.gateway.GetPath(ctx, &provider.GetPathRequest{
+
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ gpRes, err := gatewayClient.GetPath(ctx, &provider.GetPathRequest{
ResourceId: space.Root,
})
if err != nil {
@@ -296,7 +308,7 @@ func (s *Service) searchIndex(ctx context.Context, req *searchsvc.SearchRequest,
// IndexSpace (re)indexes all resources of a given space.
func (s *Service) IndexSpace(spaceID *provider.StorageSpaceId, uID *user.UserId) error {
- ownerCtx, err := getAuthContext(&user.User{Id: uID}, s.gateway, s.secret, s.logger)
+ ownerCtx, err := getAuthContext(&user.User{Id: uID}, s.gatewaySelector, s.secret, s.logger)
if err != nil {
return err
}
@@ -312,7 +324,7 @@ func (s *Service) IndexSpace(spaceID *provider.StorageSpaceId, uID *user.UserId)
}
rootID.OpaqueId = rootID.SpaceId
- w := walker.NewWalker(s.gateway)
+ w := walker.NewWalker(s.gatewaySelector)
err = w.Walk(ownerCtx, &rootID, func(wd string, info *provider.ResourceInfo, err error) error {
if err != nil {
s.logger.Error().Err(err).Msg("error walking the tree")
@@ -426,17 +438,17 @@ func (s *Service) MoveItem(ref *provider.Reference, uID *user.UserId) {
}
func (s *Service) resInfo(uID *user.UserId, ref *provider.Reference) (context.Context, *provider.StatResponse, string) {
- ownerCtx, err := getAuthContext(&user.User{Id: uID}, s.gateway, s.secret, s.logger)
+ ownerCtx, err := getAuthContext(&user.User{Id: uID}, s.gatewaySelector, s.secret, s.logger)
if err != nil {
return nil, nil, ""
}
- statRes, err := statResource(ownerCtx, ref, s.gateway, s.logger)
+ statRes, err := statResource(ownerCtx, ref, s.gatewaySelector, s.logger)
if err != nil {
return nil, nil, ""
}
- r, err := ResolveReference(ownerCtx, ref, statRes.GetInfo(), s.gateway)
+ r, err := ResolveReference(ownerCtx, ref, statRes.GetInfo(), s.gatewaySelector)
if err != nil {
return nil, nil, ""
}
diff --git a/services/search/pkg/search/service_test.go b/services/search/pkg/search/service_test.go
index fc374c7e1..b6b0eb2c2 100644
--- a/services/search/pkg/search/service_test.go
+++ b/services/search/pkg/search/service_test.go
@@ -8,6 +8,7 @@ import (
sprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
typesv1beta1 "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"
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
@@ -20,17 +21,19 @@ import (
engineMocks "github.com/owncloud/ocis/v2/services/search/pkg/engine/mocks"
"github.com/owncloud/ocis/v2/services/search/pkg/search"
"github.com/stretchr/testify/mock"
+ "google.golang.org/grpc"
)
var _ = Describe("Searchprovider", func() {
var (
- s search.Searcher
- extractor *contentMocks.Extractor
- gw *cs3mocks.GatewayAPIClient
- indexClient *engineMocks.Engine
- ctx context.Context
- logger = log.NewLogger()
- user = &userv1beta1.User{
+ s search.Searcher
+ extractor *contentMocks.Extractor
+ gatewayClient *cs3mocks.GatewayAPIClient
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
+ indexClient *engineMocks.Engine
+ ctx context.Context
+ logger = log.NewLogger()
+ user = &userv1beta1.User{
Id: &userv1beta1.UserId{
OpaqueId: "user",
},
@@ -70,22 +73,31 @@ var _ = Describe("Searchprovider", func() {
)
BeforeEach(func() {
+ 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()
- gw = &cs3mocks.GatewayAPIClient{}
indexClient = &engineMocks.Engine{}
extractor = &contentMocks.Extractor{}
- s = search.NewService(gw, indexClient, extractor, logger, &config.Config{})
+ s = search.NewService(gatewaySelector, indexClient, extractor, logger, &config.Config{})
- gw.On("Authenticate", mock.Anything, mock.Anything).Return(&gateway.AuthenticateResponse{
+ gatewayClient.On("Authenticate", mock.Anything, mock.Anything).Return(&gateway.AuthenticateResponse{
Status: status.NewOK(ctx),
Token: "authtoken",
}, nil)
- gw.On("Stat", mock.Anything, mock.Anything).Return(&sprovider.StatResponse{
+ gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(&sprovider.StatResponse{
Status: status.NewOK(context.Background()),
Info: ri,
}, nil)
- gw.On("GetPath", mock.Anything, mock.MatchedBy(func(req *sprovider.GetPathRequest) bool {
+ gatewayClient.On("GetPath", mock.Anything, mock.MatchedBy(func(req *sprovider.GetPathRequest) bool {
return req.ResourceId.OpaqueId == ri.Id.OpaqueId
})).Return(&sprovider.GetPathResponse{
Status: status.NewOK(context.Background()),
@@ -96,14 +108,14 @@ var _ = Describe("Searchprovider", func() {
Describe("New", func() {
It("returns a new instance", func() {
- s := search.NewService(gw, indexClient, extractor, logger, &config.Config{})
+ s := search.NewService(gatewaySelector, indexClient, extractor, logger, &config.Config{})
Expect(s).ToNot(BeNil())
})
})
Describe("IndexSpace", func() {
It("walks the space and indexes all files", func() {
- gw.On("GetUserByClaim", mock.Anything, mock.Anything).Return(&userv1beta1.GetUserByClaimResponse{
+ gatewayClient.On("GetUserByClaim", mock.Anything, mock.Anything).Return(&userv1beta1.GetUserByClaimResponse{
Status: status.NewOK(context.Background()),
User: user,
}, nil)
@@ -127,7 +139,7 @@ var _ = Describe("Searchprovider", func() {
Context("with a personal space", func() {
BeforeEach(func() {
- gw.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(&sprovider.ListStorageSpacesResponse{
+ gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(&sprovider.ListStorageSpacesResponse{
Status: status.NewOK(ctx),
StorageSpaces: []*sprovider.StorageSpace{personalSpace},
}, nil)
@@ -210,14 +222,14 @@ var _ = Describe("Searchprovider", func() {
},
},
}
- gw.On("GetPath", mock.Anything, mock.Anything).Return(&sprovider.GetPathResponse{
+ gatewayClient.On("GetPath", mock.Anything, mock.Anything).Return(&sprovider.GetPathResponse{
Status: status.NewOK(ctx),
Path: "/grant/path",
}, nil)
})
It("searches the received spaces", func() {
- gw.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(&sprovider.ListStorageSpacesResponse{
+ gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(&sprovider.ListStorageSpacesResponse{
Status: status.NewOK(ctx),
StorageSpaces: []*sprovider.StorageSpace{grantSpace, mountpointSpace},
}, nil)
@@ -259,7 +271,7 @@ var _ = Describe("Searchprovider", func() {
Context("when searching both spaces", func() {
BeforeEach(func() {
- gw.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(&sprovider.ListStorageSpacesResponse{
+ gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(&sprovider.ListStorageSpacesResponse{
Status: status.NewOK(ctx),
StorageSpaces: []*sprovider.StorageSpace{personalSpace, grantSpace, mountpointSpace},
}, nil)
diff --git a/services/search/pkg/service/grpc/v0/service.go b/services/search/pkg/service/grpc/v0/service.go
index 38e55d133..1cb9e89c9 100644
--- a/services/search/pkg/service/grpc/v0/service.go
+++ b/services/search/pkg/service/grpc/v0/service.go
@@ -19,6 +19,7 @@ import (
"github.com/jellydator/ttlcache/v2"
ociscrypto "github.com/owncloud/ocis/v2/ocis-pkg/crypto"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
+ "github.com/owncloud/ocis/v2/ocis-pkg/registry"
v0 "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/search/v0"
searchsvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/search/v0"
"github.com/owncloud/ocis/v2/services/search/pkg/content"
@@ -55,9 +56,9 @@ func NewHandler(opts ...Option) (searchsvc.SearchProviderHandler, func(), error)
}
// initialize gateway
- gw, err := pool.GetGatewayServiceClient(cfg.Reva.Address)
+ selector, err := pool.GatewaySelector(cfg.Reva.Address, pool.WithRegistry(registry.GetRegistry()))
if err != nil {
- logger.Fatal().Err(err).Str("addr", cfg.Reva.Address).Msg("could not get reva client")
+ logger.Fatal().Err(err).Msg("could not get reva gateway selector")
return nil, teardown, err
}
// initialize search content extractor
@@ -68,7 +69,7 @@ func NewHandler(opts ...Option) (searchsvc.SearchProviderHandler, func(), error)
return nil, teardown, err
}
case "tika":
- if extractor, err = content.NewTikaExtractor(gw, logger, cfg); err != nil {
+ if extractor, err = content.NewTikaExtractor(selector, logger, cfg); err != nil {
return nil, teardown, err
}
default:
@@ -106,7 +107,7 @@ func NewHandler(opts ...Option) (searchsvc.SearchProviderHandler, func(), error)
return nil, teardown, err
}
- ss := search.NewService(gw, eng, extractor, logger, cfg)
+ ss := search.NewService(selector, eng, extractor, logger, cfg)
// setup event handling
if err := search.HandleEvents(ss, bus, logger, cfg); err != nil {
diff --git a/services/settings/pkg/config/defaults/defaultconfig.go b/services/settings/pkg/config/defaults/defaultconfig.go
index d5fd3ab5e..64866ae3f 100644
--- a/services/settings/pkg/config/defaults/defaultconfig.go
+++ b/services/settings/pkg/config/defaults/defaultconfig.go
@@ -53,8 +53,8 @@ func DefaultConfig() *config.Config {
DataPath: path.Join(defaults.BaseDataPath(), "settings"),
SetupDefaultAssignments: false,
Metadata: config.Metadata{
- GatewayAddress: "127.0.0.1:9215", // system storage
- StorageAddress: "127.0.0.1:9215",
+ GatewayAddress: "com.owncloud.api.storage-system",
+ StorageAddress: "com.owncloud.api.storage-system",
SystemUserIDP: "internal",
Cache: &config.Cache{
Store: "memory",
diff --git a/services/sharing/pkg/command/server.go b/services/sharing/pkg/command/server.go
index 6154ff20b..11a521b0c 100644
--- a/services/sharing/pkg/command/server.go
+++ b/services/sharing/pkg/command/server.go
@@ -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/sharing/pkg/config"
@@ -55,12 +55,16 @@ func Server(cfg *config.Config) *cli.Command {
}
}
- pidFile := path.Join(os.TempDir(), "revad-"+cfg.Service.Name+"-"+uuid.Must(uuid.NewV4()).String()+".pid")
-
- rcfg := revaconfig.SharingConfigFromStruct(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.SharingConfigFromStruct(cfg)
+ reg := registry.GetRegistry()
+
+ runtime.RunWithOptions(rCfg, pidFile,
+ runtime.WithLogger(&logger.Logger),
+ runtime.WithRegistry(reg),
+ )
+
return nil
}, func(err error) {
logger.Error().
@@ -90,15 +94,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")
}
return gr.Run()
diff --git a/services/sharing/pkg/config/defaults/defaultconfig.go b/services/sharing/pkg/config/defaults/defaultconfig.go
index 044e4694a..3a2d450d2 100644
--- a/services/sharing/pkg/config/defaults/defaultconfig.go
+++ b/services/sharing/pkg/config/defaults/defaultconfig.go
@@ -41,11 +41,11 @@ func DefaultConfig() *config.Config {
File: filepath.Join(defaults.BaseDataPath(), "storage", "shares.json"),
},
CS3: config.UserSharingCS3Driver{
- ProviderAddr: "127.0.0.1:9215", // system storage
+ ProviderAddr: "com.owncloud.api.storage-system",
SystemUserIDP: "internal",
},
JSONCS3: config.UserSharingJSONCS3Driver{
- ProviderAddr: "127.0.0.1:9215", // system storage
+ ProviderAddr: "com.owncloud.api.storage-system",
SystemUserIDP: "internal",
},
OwnCloudSQL: config.UserSharingOwnCloudSQLDriver{
@@ -61,11 +61,11 @@ func DefaultConfig() *config.Config {
File: filepath.Join(defaults.BaseDataPath(), "storage", "publicshares.json"),
},
CS3: config.PublicSharingCS3Driver{
- ProviderAddr: "127.0.0.1:9215", // system storage
+ ProviderAddr: "com.owncloud.api.storage-system", // system storage
SystemUserIDP: "internal",
},
JSONCS3: config.PublicSharingJSONCS3Driver{
- ProviderAddr: "127.0.0.1:9215", // system storage
+ ProviderAddr: "com.owncloud.api.storage-system", // system storage
SystemUserIDP: "internal",
},
// TODO implement and add owncloudsql publicshare driver
diff --git a/services/storage-publiclink/pkg/command/server.go b/services/storage-publiclink/pkg/command/server.go
index 1c731ee52..9eb75d21d 100644
--- a/services/storage-publiclink/pkg/command/server.go
+++ b/services/storage-publiclink/pkg/command/server.go
@@ -10,7 +10,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-publiclink/pkg/config"
@@ -42,12 +42,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.StoragePublicLinkConfigFromStruct(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.StoragePublicLinkConfigFromStruct(cfg)
+ reg := registry.GetRegistry()
+
+ runtime.RunWithOptions(rCfg, pidFile,
+ runtime.WithLogger(&logger.Logger),
+ runtime.WithRegistry(reg),
+ )
+
return nil
}, func(err error) {
logger.Error().
@@ -77,15 +81,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")
}
return gr.Run()
diff --git a/services/storage-shares/pkg/command/server.go b/services/storage-shares/pkg/command/server.go
index d3e507e2b..78e546f0e 100644
--- a/services/storage-shares/pkg/command/server.go
+++ b/services/storage-shares/pkg/command/server.go
@@ -10,7 +10,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-shares/pkg/config"
@@ -42,12 +42,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.StorageSharesConfigFromStruct(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.StorageSharesConfigFromStruct(cfg)
+ reg := registry.GetRegistry()
+
+ runtime.RunWithOptions(rCfg, pidFile,
+ runtime.WithLogger(&logger.Logger),
+ runtime.WithRegistry(reg),
+ )
+
return nil
}, func(err error) {
logger.Error().
@@ -77,15 +81,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")
}
return gr.Run()
diff --git a/services/storage-shares/pkg/config/defaults/defaultconfig.go b/services/storage-shares/pkg/config/defaults/defaultconfig.go
index 44680f424..202cc0241 100644
--- a/services/storage-shares/pkg/config/defaults/defaultconfig.go
+++ b/services/storage-shares/pkg/config/defaults/defaultconfig.go
@@ -34,7 +34,7 @@ func DefaultConfig() *config.Config {
Reva: shared.DefaultRevaConfig(),
MountID: "7639e57c-4433-4a12-8201-722fd0009154",
ReadOnly: false,
- SharesProviderEndpoint: "localhost:9150",
+ SharesProviderEndpoint: "com.owncloud.api.sharing",
}
}
diff --git a/services/storage-system/pkg/command/server.go b/services/storage-system/pkg/command/server.go
index de6095a66..03e5ab825 100644
--- a/services/storage-system/pkg/command/server.go
+++ b/services/storage-system/pkg/command/server.go
@@ -10,7 +10,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-system/pkg/config"
@@ -42,12 +42,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.StorageSystemFromStruct(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.StorageSystemFromStruct(cfg)
+ reg := registry.GetRegistry()
+
+ runtime.RunWithOptions(rCfg, pidFile,
+ runtime.WithLogger(&logger.Logger),
+ runtime.WithRegistry(reg),
+ )
+
return nil
}, func(err error) {
logger.Error().
@@ -77,26 +81,14 @@ 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")
}
- if err := external.RegisterHTTPEndpoint(
- ctx,
- cfg.HTTP.Namespace+"."+cfg.Service.Name,
- uuid.Must(uuid.NewV4()).String(),
- cfg.HTTP.Addr,
- version.GetString(),
- logger,
- ); err != nil {
- logger.Fatal().Err(err).Msg("failed to register the http endpoint")
+ httpScv := registry.BuildHTTPService(cfg.HTTP.Namespace+"."+cfg.Service.Name, uuid.Must(uuid.NewV4()).String(), cfg.HTTP.Addr, version.GetString())
+ if err := registry.RegisterService(ctx, httpScv, logger); err != nil {
+ logger.Fatal().Err(err).Msg("failed to register the http service")
}
return gr.Run()
diff --git a/services/storage-system/pkg/revaconfig/config.go b/services/storage-system/pkg/revaconfig/config.go
index 3f9ebd1b2..7f079e768 100644
--- a/services/storage-system/pkg/revaconfig/config.go
+++ b/services/storage-system/pkg/revaconfig/config.go
@@ -34,12 +34,12 @@ func StorageSystemFromStruct(cfg *config.Config) map[string]interface{} {
"services": map[string]interface{}{
"gateway": map[string]interface{}{
// registries are located on the gateway
- "authregistrysvc": cfg.GRPC.Addr,
- "storageregistrysvc": cfg.GRPC.Addr,
+ "authregistrysvc": "com.owncloud.api.storage-system",
+ "storageregistrysvc": "com.owncloud.api.storage-system",
// user metadata is located on the users services
- "userprovidersvc": cfg.GRPC.Addr,
- "groupprovidersvc": cfg.GRPC.Addr,
- "permissionssvc": cfg.GRPC.Addr,
+ "userprovidersvc": "com.owncloud.api.storage-system",
+ "groupprovidersvc": "com.owncloud.api.storage-system",
+ "permissionssvc": "com.owncloud.api.storage-system",
// other
"disable_home_creation_on_login": true, // metadata manually creates a space
// metadata always uses the simple upload, so no transfer secret or datagateway needed
@@ -69,7 +69,7 @@ func StorageSystemFromStruct(cfg *config.Config) map[string]interface{} {
"drivers": map[string]interface{}{
"static": map[string]interface{}{
"rules": map[string]interface{}{
- "machine": cfg.GRPC.Addr,
+ "machine": "com.owncloud.api.storage-system",
},
},
},
@@ -79,7 +79,7 @@ func StorageSystemFromStruct(cfg *config.Config) map[string]interface{} {
"auth_managers": map[string]interface{}{
"machine": map[string]interface{}{
"api_key": cfg.SystemUserAPIKey,
- "gateway_addr": cfg.GRPC.Addr,
+ "gateway_addr": "com.owncloud.api.storage-system",
},
},
},
@@ -95,7 +95,7 @@ func StorageSystemFromStruct(cfg *config.Config) map[string]interface{} {
"static": map[string]interface{}{
"rules": map[string]interface{}{
"/": map[string]interface{}{
- "address": cfg.GRPC.Addr,
+ "address": "com.owncloud.api.storage-system",
},
},
},
@@ -161,7 +161,7 @@ func metadataDrivers(cfg *config.Config) map[string]interface{} {
"user_layout": "{{.Id.OpaqueId}}",
"treetime_accounting": false,
"treesize_accounting": false,
- "permissionssvc": cfg.GRPC.Addr,
+ "permissionssvc": "com.owncloud.api.storage-system",
"max_acquire_lock_cycles": cfg.Drivers.OCIS.MaxAcquireLockCycles,
"lock_cycle_duration_factor": cfg.Drivers.OCIS.LockCycleDurationFactor,
"statcache": map[string]interface{}{
diff --git a/services/storage-users/pkg/command/server.go b/services/storage-users/pkg/command/server.go
index ffff3afe2..d7fa6b986 100644
--- a/services/storage-users/pkg/command/server.go
+++ b/services/storage-users/pkg/command/server.go
@@ -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")
}
diff --git a/services/storage-users/pkg/config/defaults/defaultconfig.go b/services/storage-users/pkg/config/defaults/defaultconfig.go
index 30a174f33..f8673c23e 100644
--- a/services/storage-users/pkg/config/defaults/defaultconfig.go
+++ b/services/storage-users/pkg/config/defaults/defaultconfig.go
@@ -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,
},
diff --git a/services/storage-users/pkg/event/service.go b/services/storage-users/pkg/event/service.go
index b546a13b1..91384f75d 100644
--- a/services/storage-users/pkg/event/service.go
+++ b/services/storage-users/pkg/event/service.go
@@ -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)
}
}
diff --git a/services/storage-users/pkg/task/task_suite_test.go b/services/storage-users/pkg/task/task_suite_test.go
index dbcb7996a..5b904e7e3 100644
--- a/services/storage-users/pkg/task/task_suite_test.go
+++ b/services/storage-users/pkg/task/task_suite_test.go
@@ -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")
diff --git a/services/storage-users/pkg/task/trash_bin.go b/services/storage-users/pkg/task/trash_bin.go
index 354f9cf09..daf49fad1 100644
--- a/services/storage-users/pkg/task/trash_bin.go
+++ b/services/storage-users/pkg/task/trash_bin.go
@@ -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,
})
diff --git a/services/storage-users/pkg/task/trash_bin_test.go b/services/storage-users/pkg/task/trash_bin_test.go
index 1da8c231d..1066565c9 100644
--- a/services/storage-users/pkg/task/trash_bin_test.go
+++ b/services/storage-users/pkg/task/trash_bin_test.go
@@ -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))
diff --git a/services/thumbnails/pkg/server/grpc/server.go b/services/thumbnails/pkg/server/grpc/server.go
index a783d18fa..26d10bc71 100644
--- a/services/thumbnails/pkg/server/grpc/server.go
+++ b/services/thumbnails/pkg/server/grpc/server.go
@@ -2,6 +2,7 @@ package grpc
import (
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
+ "github.com/owncloud/ocis/v2/ocis-pkg/registry"
"github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
"github.com/owncloud/ocis/v2/ocis-pkg/version"
thumbnailssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/thumbnails/v0"
@@ -41,12 +42,14 @@ func NewService(opts ...Option) grpc.Service {
options.Logger.Error().Err(err).Msg("could not get gateway client tls mode")
return grpc.Service{}
}
- gc, err := pool.GetGatewayServiceClient(tconf.RevaGateway,
+
+ gatewaySelector, err := pool.GatewaySelector(tconf.RevaGateway,
pool.WithTLSCACert(options.Config.GRPCClientTLS.CACert),
pool.WithTLSMode(tm),
+ pool.WithRegistry(registry.GetRegistry()),
)
if err != nil {
- options.Logger.Error().Err(err).Msg("could not get gateway client")
+ options.Logger.Error().Err(err).Msg("could not get gateway selector")
return grpc.Service{}
}
var thumbnail decorators.DecoratedService
@@ -61,8 +64,8 @@ func NewService(opts ...Option) grpc.Service {
options.Logger,
),
),
- svc.CS3Source(imgsource.NewCS3Source(tconf, gc)),
- svc.CS3Client(gc),
+ svc.CS3Source(imgsource.NewCS3Source(tconf, gatewaySelector)),
+ svc.GatewaySelector(gatewaySelector),
)
thumbnail = decorators.NewInstrument(thumbnail, options.Metrics)
thumbnail = decorators.NewLogging(thumbnail, options.Logger)
diff --git a/services/thumbnails/pkg/service/grpc/v0/option.go b/services/thumbnails/pkg/service/grpc/v0/option.go
index 19b341c58..00cf0eeab 100644
--- a/services/thumbnails/pkg/service/grpc/v0/option.go
+++ b/services/thumbnails/pkg/service/grpc/v0/option.go
@@ -4,7 +4,7 @@ import (
"net/http"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
-
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/services/thumbnails/pkg/config"
"github.com/owncloud/ocis/v2/services/thumbnails/pkg/thumbnail/imgsource"
@@ -22,7 +22,7 @@ type Options struct {
ThumbnailStorage storage.Storage
ImageSource imgsource.Source
CS3Source imgsource.Source
- CS3Client gateway.GatewayAPIClient
+ GatewaySelector pool.Selectable[gateway.GatewayAPIClient]
}
// newOptions initializes the available default options.
@@ -71,14 +71,16 @@ func ThumbnailSource(val imgsource.Source) Option {
}
}
+// CS3Source provides a function to set the CS3Source option
func CS3Source(val imgsource.Source) Option {
return func(o *Options) {
o.CS3Source = val
}
}
-func CS3Client(c gateway.GatewayAPIClient) Option {
+// GatewaySelector adds a grpc client selector for the gateway service
+func GatewaySelector(val pool.Selectable[gateway.GatewayAPIClient]) Option {
return func(o *Options) {
- o.CS3Client = c
+ o.GatewaySelector = val
}
}
diff --git a/services/thumbnails/pkg/service/grpc/v0/service.go b/services/thumbnails/pkg/service/grpc/v0/service.go
index 541e56bca..070613b0c 100644
--- a/services/thumbnails/pkg/service/grpc/v0/service.go
+++ b/services/thumbnails/pkg/service/grpc/v0/service.go
@@ -12,6 +12,7 @@ import (
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
revactx "github.com/cs3org/reva/v2/pkg/ctx"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/storagespace"
"github.com/cs3org/reva/v2/pkg/utils"
"github.com/golang-jwt/jwt/v4"
@@ -45,7 +46,7 @@ func NewService(opts ...Option) decorators.DecoratedService {
webdavSource: options.ImageSource,
cs3Source: options.CS3Source,
logger: logger,
- cs3Client: options.CS3Client,
+ selector: options.GatewaySelector,
preprocessorOpts: PreprocessorOpts{
TxtFontFileMap: options.Config.Thumbnail.FontMapFile,
},
@@ -65,10 +66,11 @@ type Thumbnail struct {
webdavSource imgsource.Source
cs3Source imgsource.Source
logger log.Logger
- cs3Client gateway.GatewayAPIClient
+ selector pool.Selectable[gateway.GatewayAPIClient]
preprocessorOpts PreprocessorOpts
}
+// PreprocessorOpts holds the options for the preprocessor
type PreprocessorOpts struct {
TxtFontFileMap string
}
@@ -161,21 +163,24 @@ func (g Thumbnail) handleWebdavSource(ctx context.Context, req *thumbnailssvc.Ge
}
var auth, statPath string
-
if src.IsPublicLink {
q := imgURL.Query()
var rsp *gateway.AuthenticateResponse
+ client, err := g.selector.Next()
+ if err != nil {
+ return "", merrors.InternalServerError(g.serviceID, "could not select next gateway client: %s", err.Error())
+ }
if q.Get("signature") != "" && q.Get("expiration") != "" {
// Handle pre-signed public links
sig := q.Get("signature")
exp := q.Get("expiration")
- rsp, err = g.cs3Client.Authenticate(ctx, &gateway.AuthenticateRequest{
+ rsp, err = client.Authenticate(ctx, &gateway.AuthenticateRequest{
Type: "publicshares",
ClientId: src.PublicLinkToken,
ClientSecret: strings.Join([]string{"signature", sig, exp}, "|"),
})
} else {
- rsp, err = g.cs3Client.Authenticate(ctx, &gateway.AuthenticateRequest{
+ rsp, err = client.Authenticate(ctx, &gateway.AuthenticateRequest{
Type: "publicshares",
ClientId: src.PublicLinkToken,
// We pass an empty password because we expect non pre-signed public links
@@ -248,8 +253,12 @@ func (g Thumbnail) stat(path, auth string) (*provider.StatResponse, error) {
}
}
+ client, err := g.selector.Next()
+ if err != nil {
+ return nil, merrors.InternalServerError(g.serviceID, "could not select next gateway client: %s", err.Error())
+ }
req := &provider.StatRequest{Ref: &ref}
- rsp, err := g.cs3Client.Stat(ctx, req)
+ rsp, err := client.Stat(ctx, req)
if err != nil {
g.logger.Error().Err(err).Str("path", path).Msg("could not stat file")
return nil, merrors.InternalServerError(g.serviceID, "could not stat file: %s", err.Error())
diff --git a/services/thumbnails/pkg/thumbnail/imgsource/cs3.go b/services/thumbnails/pkg/thumbnail/imgsource/cs3.go
index be17365c0..d17648e5f 100644
--- a/services/thumbnails/pkg/thumbnail/imgsource/cs3.go
+++ b/services/thumbnails/pkg/thumbnail/imgsource/cs3.go
@@ -11,6 +11,7 @@ import (
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
revactx "github.com/cs3org/reva/v2/pkg/ctx"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/rhttp"
"github.com/cs3org/reva/v2/pkg/storagespace"
"github.com/owncloud/ocis/v2/services/thumbnails/pkg/config"
@@ -24,15 +25,17 @@ const (
TokenTransportHeader = "X-Reva-Transfer"
)
+// CS3 implements a CS3 image source
type CS3 struct {
- client gateway.GatewayAPIClient
- insecure bool
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
+ insecure bool
}
-func NewCS3Source(cfg config.Thumbnail, c gateway.GatewayAPIClient) CS3 {
+// NewCS3Source configures a new CS3 image source
+func NewCS3Source(cfg config.Thumbnail, gatewaySelector pool.Selectable[gateway.GatewayAPIClient]) CS3 {
return CS3{
- client: c,
- insecure: cfg.CS3AllowInsecure,
+ gatewaySelector: gatewaySelector,
+ insecure: cfg.CS3AllowInsecure,
}
}
@@ -51,8 +54,13 @@ func (s CS3) Get(ctx context.Context, path string) (io.ReadCloser, error) {
Path: path,
}
}
+
ctx = metadata.AppendToOutgoingContext(context.Background(), revactx.TokenHeader, auth)
- rsp, err := s.client.InitiateFileDownload(ctx, &provider.InitiateFileDownloadRequest{Ref: &ref})
+ gwc, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ rsp, err := gwc.InitiateFileDownload(ctx, &provider.InitiateFileDownloadRequest{Ref: &ref})
if err != nil {
return nil, err
diff --git a/services/userlog/pkg/command/server.go b/services/userlog/pkg/command/server.go
index c814b322c..58a6f209d 100644
--- a/services/userlog/pkg/command/server.go
+++ b/services/userlog/pkg/command/server.go
@@ -11,6 +11,7 @@ import (
"github.com/oklog/run"
"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
+ "github.com/owncloud/ocis/v2/ocis-pkg/registry"
"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -90,13 +91,14 @@ func Server(cfg *config.Config) *cli.Command {
if err != nil {
return err
}
- gwclient, err := pool.GetGatewayServiceClient(
+ gatewaySelector, err := pool.GatewaySelector(
cfg.RevaGateway,
pool.WithTLSCACert(cfg.GRPCClientTLS.CACert),
pool.WithTLSMode(tm),
+ pool.WithRegistry(registry.GetRegistry()),
)
if err != nil {
- return fmt.Errorf("could not get reva client: %s", err)
+ return fmt.Errorf("could not get reva client selector: %s", err)
}
hClient := ehsvc.NewEventHistoryService("com.owncloud.api.eventhistory", ogrpc.DefaultClient())
@@ -109,7 +111,7 @@ func Server(cfg *config.Config) *cli.Command {
http.Metrics(mtrcs),
http.Store(st),
http.Consumer(consumer),
- http.Gateway(gwclient),
+ http.GatewaySelector(gatewaySelector),
http.History(hClient),
http.RegisteredEvents(_registeredEvents),
)
diff --git a/services/userlog/pkg/server/http/option.go b/services/userlog/pkg/server/http/option.go
index 11700b5c1..430c854db 100644
--- a/services/userlog/pkg/server/http/option.go
+++ b/services/userlog/pkg/server/http/option.go
@@ -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/log"
ehsvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/eventhistory/v0"
"github.com/owncloud/ocis/v2/services/userlog/pkg/config"
@@ -26,7 +27,7 @@ type Options struct {
Namespace string
Store store.Store
Consumer events.Consumer
- GatewayClient gateway.GatewayAPIClient
+ GatewaySelector pool.Selectable[gateway.GatewayAPIClient]
HistoryClient ehsvc.EventHistoryService
RegisteredEvents []events.Unmarshaller
}
@@ -98,10 +99,10 @@ func Consumer(consumer events.Consumer) Option {
}
}
-// Gateway provides a function to configure the gateway client
-func Gateway(gw gateway.GatewayAPIClient) Option {
+// GatewaySelector provides a function to configure the gateway client selector
+func GatewaySelector(gatewaySelector pool.Selectable[gateway.GatewayAPIClient]) Option {
return func(o *Options) {
- o.GatewayClient = gw
+ o.GatewaySelector = gatewaySelector
}
}
diff --git a/services/userlog/pkg/server/http/server.go b/services/userlog/pkg/server/http/server.go
index 280c5b775..724248439 100644
--- a/services/userlog/pkg/server/http/server.go
+++ b/services/userlog/pkg/server/http/server.go
@@ -75,7 +75,7 @@ func Server(opts ...Option) (http.Service, error) {
svc.Store(options.Store),
svc.Config(options.Config),
svc.HistoryClient(options.HistoryClient),
- svc.GatewayClient(options.GatewayClient),
+ svc.GatewaySelector(options.GatewaySelector),
svc.RegisteredEvents(options.RegisteredEvents),
)
if err != nil {
diff --git a/services/userlog/pkg/service/conversion.go b/services/userlog/pkg/service/conversion.go
index e1bce3525..93fa14d2b 100644
--- a/services/userlog/pkg/service/conversion.go
+++ b/services/userlog/pkg/service/conversion.go
@@ -16,6 +16,7 @@ import (
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/v2/pkg/events"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/storagespace"
"github.com/cs3org/reva/v2/pkg/utils"
"github.com/leonelquinteros/gotext"
@@ -52,7 +53,7 @@ type OC10Notification struct {
// Converter is responsible for converting eventhistory events to OC10Notifications
type Converter struct {
locale string
- gwClient gateway.GatewayAPIClient
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
machineAuthAPIKey string
serviceName string
registeredEvents map[string]events.Unmarshaller
@@ -66,10 +67,10 @@ type Converter struct {
}
// NewConverter returns a new Converter
-func NewConverter(loc string, gwc gateway.GatewayAPIClient, machineAuthAPIKey string, name string, translationPath string, registeredEvents map[string]events.Unmarshaller) *Converter {
+func NewConverter(loc string, gatewaySelector pool.Selectable[gateway.GatewayAPIClient], machineAuthAPIKey string, name string, translationPath string, registeredEvents map[string]events.Unmarshaller) *Converter {
return &Converter{
locale: loc,
- gwClient: gwc,
+ gatewaySelector: gatewaySelector,
machineAuthAPIKey: machineAuthAPIKey,
serviceName: name,
registeredEvents: registeredEvents,
@@ -306,7 +307,7 @@ func (c *Converter) authenticate(usr *user.User) (context.Context, error) {
if ctx, ok := c.contexts[usr.GetId().GetOpaqueId()]; ok {
return ctx, nil
}
- ctx, err := authenticate(usr, c.gwClient, c.machineAuthAPIKey)
+ ctx, err := authenticate(usr, c.gatewaySelector, c.machineAuthAPIKey)
if err == nil {
c.contexts[usr.GetId().GetOpaqueId()] = ctx
}
@@ -317,7 +318,7 @@ func (c *Converter) getSpace(ctx context.Context, spaceID string) (*storageprovi
if space, ok := c.spaces[spaceID]; ok {
return space, nil
}
- space, err := getSpace(ctx, spaceID, c.gwClient)
+ space, err := getSpace(ctx, spaceID, c.gatewaySelector)
if err == nil {
c.spaces[spaceID] = space
}
@@ -328,7 +329,7 @@ func (c *Converter) getResource(ctx context.Context, resourceID *storageprovider
if r, ok := c.resources[resourceID.GetOpaqueId()]; ok {
return r, nil
}
- resource, err := getResource(ctx, resourceID, c.gwClient)
+ resource, err := getResource(ctx, resourceID, c.gatewaySelector)
if err == nil {
c.resources[resourceID.GetOpaqueId()] = resource
}
@@ -339,7 +340,7 @@ func (c *Converter) getUser(ctx context.Context, userID *user.UserId) (*user.Use
if u, ok := c.users[userID.GetOpaqueId()]; ok {
return u, nil
}
- usr, err := getUser(ctx, userID, c.gwClient)
+ usr, err := getUser(ctx, userID, c.gatewaySelector)
if err == nil {
c.users[userID.GetOpaqueId()] = usr
}
diff --git a/services/userlog/pkg/service/http.go b/services/userlog/pkg/service/http.go
index 31d7c9b64..f49d383e6 100644
--- a/services/userlog/pkg/service/http.go
+++ b/services/userlog/pkg/service/http.go
@@ -31,7 +31,7 @@ func (ul *UserlogService) HandleGetEvents(w http.ResponseWriter, r *http.Request
return
}
- conv := NewConverter(r.Header.Get(HeaderAcceptLanguage), ul.gwClient, ul.cfg.MachineAuthAPIKey, ul.cfg.Service.Name, ul.cfg.TranslationPath, ul.registeredEvents)
+ conv := NewConverter(r.Header.Get(HeaderAcceptLanguage), ul.gatewaySelector, ul.cfg.MachineAuthAPIKey, ul.cfg.Service.Name, ul.cfg.TranslationPath, ul.registeredEvents)
resp := GetEventResponseOC10{}
for _, e := range evs {
diff --git a/services/userlog/pkg/service/options.go b/services/userlog/pkg/service/options.go
index b84c67725..acea1a4b7 100644
--- a/services/userlog/pkg/service/options.go
+++ b/services/userlog/pkg/service/options.go
@@ -3,6 +3,7 @@ package service
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/owncloud/ocis/v2/ocis-pkg/log"
ehsvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/eventhistory/v0"
@@ -21,7 +22,7 @@ type Options struct {
Store store.Store
Config *config.Config
HistoryClient ehsvc.EventHistoryService
- GatewayClient gateway.GatewayAPIClient
+ GatewaySelector pool.Selectable[gateway.GatewayAPIClient]
RegisteredEvents []events.Unmarshaller
}
@@ -67,10 +68,10 @@ func HistoryClient(hc ehsvc.EventHistoryService) Option {
}
}
-// GatewayClient adds a grpc client for the gateway service
-func GatewayClient(gwc gateway.GatewayAPIClient) Option {
+// GatewaySelector adds a grpc client selector for the gateway service
+func GatewaySelector(gatewaySelector pool.Selectable[gateway.GatewayAPIClient]) Option {
return func(o *Options) {
- o.GatewayClient = gwc
+ o.GatewaySelector = gatewaySelector
}
}
diff --git a/services/userlog/pkg/service/service.go b/services/userlog/pkg/service/service.go
index d9a663ffb..37e445dbf 100644
--- a/services/userlog/pkg/service/service.go
+++ b/services/userlog/pkg/service/service.go
@@ -14,6 +14,7 @@ import (
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
revactx "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/events"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/utils"
"github.com/go-chi/chi/v5"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
@@ -31,7 +32,7 @@ type UserlogService struct {
store store.Store
cfg *config.Config
historyClient ehsvc.EventHistoryService
- gwClient gateway.GatewayAPIClient
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
registeredEvents map[string]events.Unmarshaller
translationPath string
}
@@ -58,7 +59,7 @@ func NewUserlogService(opts ...Option) (*UserlogService, error) {
store: o.Store,
cfg: o.Config,
historyClient: o.HistoryClient,
- gwClient: o.GatewayClient,
+ gatewaySelector: o.GatewaySelector,
registeredEvents: make(map[string]events.Unmarshaller),
}
@@ -283,7 +284,7 @@ func (ul *UserlogService) findSpaceMembers(ctx context.Context, spaceID string,
return nil, errors.New("need authenticated context to find space members")
}
- space, err := getSpace(ctx, spaceID, ul.gwClient)
+ space, err := getSpace(ctx, spaceID, ul.gatewaySelector)
if err != nil {
return nil, err
}
@@ -361,7 +362,7 @@ func (ul *UserlogService) resolveID(ctx context.Context, userid *user.UserId, gr
// resolves the users of a group
func (ul *UserlogService) resolveGroup(ctx context.Context, groupID string) ([]string, error) {
- grp, err := getGroup(ctx, groupID, ul.gwClient)
+ grp, err := getGroup(ctx, groupID, ul.gatewaySelector)
if err != nil {
return nil, err
}
@@ -380,13 +381,13 @@ func (ul *UserlogService) impersonate(uid *user.UserId) context.Context {
return nil
}
- u, err := getUser(context.Background(), uid, ul.gwClient)
+ u, err := getUser(context.Background(), uid, ul.gatewaySelector)
if err != nil {
ul.log.Error().Err(err).Msg("cannot get user")
return nil
}
- ctx, err := authenticate(u, ul.gwClient, ul.cfg.MachineAuthAPIKey)
+ ctx, err := authenticate(u, ul.gatewaySelector, ul.cfg.MachineAuthAPIKey)
if err != nil {
ul.log.Error().Err(err).Str("userid", u.GetId().GetOpaqueId()).Msg("failed to impersonate user")
return nil
@@ -394,9 +395,14 @@ func (ul *UserlogService) impersonate(uid *user.UserId) context.Context {
return ctx
}
-func authenticate(usr *user.User, gwc gateway.GatewayAPIClient, machineAuthAPIKey string) (context.Context, error) {
+func authenticate(usr *user.User, gatewaySelector pool.Selectable[gateway.GatewayAPIClient], machineAuthAPIKey string) (context.Context, error) {
+ gatewayClient, err := gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
ctx := revactx.ContextSetUser(context.Background(), usr)
- authRes, err := gwc.Authenticate(ctx, &gateway.AuthenticateRequest{
+ authRes, err := gatewayClient.Authenticate(ctx, &gateway.AuthenticateRequest{
Type: "machine",
ClientId: "userid:" + usr.GetId().GetOpaqueId(),
ClientSecret: machineAuthAPIKey,
@@ -411,8 +417,13 @@ func authenticate(usr *user.User, gwc gateway.GatewayAPIClient, machineAuthAPIKe
return metadata.AppendToOutgoingContext(ctx, revactx.TokenHeader, authRes.Token), nil
}
-func getSpace(ctx context.Context, spaceID string, gwc gateway.GatewayAPIClient) (*storageprovider.StorageSpace, error) {
- res, err := gwc.ListStorageSpaces(ctx, listStorageSpaceRequest(spaceID))
+func getSpace(ctx context.Context, spaceID string, gatewaySelector pool.Selectable[gateway.GatewayAPIClient]) (*storageprovider.StorageSpace, error) {
+ gatewayClient, err := gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ res, err := gatewayClient.ListStorageSpaces(ctx, listStorageSpaceRequest(spaceID))
if err != nil {
return nil, err
}
@@ -428,8 +439,13 @@ func getSpace(ctx context.Context, spaceID string, gwc gateway.GatewayAPIClient)
return res.StorageSpaces[0], nil
}
-func getUser(ctx context.Context, userid *user.UserId, gwc gateway.GatewayAPIClient) (*user.User, error) {
- getUserResponse, err := gwc.GetUser(context.Background(), &user.GetUserRequest{
+func getUser(ctx context.Context, userid *user.UserId, gatewaySelector pool.Selectable[gateway.GatewayAPIClient]) (*user.User, error) {
+ gatewayClient, err := gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ getUserResponse, err := gatewayClient.GetUser(context.Background(), &user.GetUserRequest{
UserId: userid,
})
if err != nil {
@@ -443,8 +459,13 @@ func getUser(ctx context.Context, userid *user.UserId, gwc gateway.GatewayAPICli
return getUserResponse.GetUser(), nil
}
-func getGroup(ctx context.Context, groupid string, gwc gateway.GatewayAPIClient) (*group.Group, error) {
- r, err := gwc.GetGroup(ctx, &group.GetGroupRequest{GroupId: &group.GroupId{OpaqueId: groupid}})
+func getGroup(ctx context.Context, groupid string, gatewaySelector pool.Selectable[gateway.GatewayAPIClient]) (*group.Group, error) {
+ gatewayClient, err := gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ r, err := gatewayClient.GetGroup(ctx, &group.GetGroupRequest{GroupId: &group.GroupId{OpaqueId: groupid}})
if err != nil {
return nil, err
}
@@ -456,8 +477,13 @@ func getGroup(ctx context.Context, groupid string, gwc gateway.GatewayAPIClient)
return r.GetGroup(), nil
}
-func getResource(ctx context.Context, resourceid *storageprovider.ResourceId, gwc gateway.GatewayAPIClient) (*storageprovider.ResourceInfo, error) {
- res, err := gwc.Stat(ctx, &storageprovider.StatRequest{Ref: &storageprovider.Reference{ResourceId: resourceid}})
+func getResource(ctx context.Context, resourceid *storageprovider.ResourceId, gatewaySelector pool.Selectable[gateway.GatewayAPIClient]) (*storageprovider.ResourceInfo, error) {
+ gatewayClient, err := gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ res, err := gatewayClient.Stat(ctx, &storageprovider.StatRequest{Ref: &storageprovider.Reference{ResourceId: resourceid}})
if err != nil {
return nil, err
}
diff --git a/services/userlog/pkg/service/service_suit_test.go b/services/userlog/pkg/service/service_suit_test.go
index 77d1081a8..ab7fb7b19 100644
--- a/services/userlog/pkg/service/service_suit_test.go
+++ b/services/userlog/pkg/service/service_suit_test.go
@@ -3,10 +3,23 @@ package service_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 TestSearch(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Userlog service Suite")
diff --git a/services/userlog/pkg/service/service_test.go b/services/userlog/pkg/service/service_test.go
index acecb66a8..2a7e49830 100644
--- a/services/userlog/pkg/service/service_test.go
+++ b/services/userlog/pkg/service/service_test.go
@@ -11,6 +11,7 @@ import (
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/v2/pkg/events"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/store"
"github.com/cs3org/reva/v2/pkg/utils"
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
@@ -27,6 +28,7 @@ import (
"github.com/test-go/testify/mock"
microevents "go-micro.dev/v4/events"
microstore "go-micro.dev/v4/store"
+ "google.golang.org/grpc"
)
var _ = Describe("UserlogService", func() {
@@ -37,7 +39,9 @@ var _ = Describe("UserlogService", func() {
bus testBus
sto microstore.Store
- gwc cs3mocks.GatewayAPIClient
+ gatewayClient *cs3mocks.GatewayAPIClient
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
+
ehc mocks.EventHistoryService
)
@@ -45,15 +49,26 @@ var _ = Describe("UserlogService", func() {
var err error
sto = store.Create()
bus = testBus(make(chan events.Event))
+
+ 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
+ },
+ )
+
o := utils.AppendJSONToOpaque(nil, "grants", map[string]*provider.ResourcePermissions{"userid": {Stat: true}})
- gwc.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(&provider.ListStorageSpacesResponse{StorageSpaces: []*provider.StorageSpace{
+ gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(&provider.ListStorageSpacesResponse{StorageSpaces: []*provider.StorageSpace{
{
Opaque: o,
SpaceType: "project",
},
}, Status: &rpc.Status{Code: rpc.Code_CODE_OK}}, nil)
- gwc.On("GetUser", mock.Anything, mock.Anything).Return(&user.GetUserResponse{User: &user.User{Id: &user.UserId{OpaqueId: "userid"}}, Status: &rpc.Status{Code: rpc.Code_CODE_OK}}, nil)
- gwc.On("Authenticate", mock.Anything, mock.Anything).Return(&gateway.AuthenticateResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}}, nil)
+ gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(&user.GetUserResponse{User: &user.User{Id: &user.UserId{OpaqueId: "userid"}}, Status: &rpc.Status{Code: rpc.Code_CODE_OK}}, nil)
+ gatewayClient.On("Authenticate", mock.Anything, mock.Anything).Return(&gateway.AuthenticateResponse{Status: &rpc.Status{Code: rpc.Code_CODE_OK}}, nil)
ul, err = service.NewUserlogService(
service.Config(cfg),
@@ -61,7 +76,7 @@ var _ = Describe("UserlogService", func() {
service.Store(sto),
service.Logger(log.NewLogger()),
service.Mux(chi.NewMux()),
- service.GatewayClient(&gwc),
+ service.GatewaySelector(gatewaySelector),
service.HistoryClient(&ehc),
service.RegisteredEvents([]events.Unmarshaller{
events.SpaceDisabled{},
diff --git a/services/users/pkg/command/server.go b/services/users/pkg/command/server.go
index b0419b305..e661eee74 100644
--- a/services/users/pkg/command/server.go
+++ b/services/users/pkg/command/server.go
@@ -11,7 +11,7 @@ import (
"github.com/oklog/run"
"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
"github.com/owncloud/ocis/v2/ocis-pkg/ldap"
- "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/users/pkg/config"
@@ -43,10 +43,6 @@ 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.UsersConfigFromStruct(cfg)
-
// the reva runtime calls os.Exit in the case of a failure and there is no way for the oCIS
// runtime to catch it and restart a reva service. Therefore we need to ensure the service has
// everything it needs, before starting the service.
@@ -60,7 +56,15 @@ func Server(cfg *config.Config) *cli.Command {
}
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.UsersConfigFromStruct(cfg)
+ reg := registry.GetRegistry()
+
+ runtime.RunWithOptions(rCfg, pidFile,
+ runtime.WithLogger(&logger.Logger),
+ runtime.WithRegistry(reg),
+ )
+
return nil
}, func(err error) {
logger.Error().
@@ -90,15 +94,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")
}
return gr.Run()
diff --git a/services/web/pkg/config/defaults/defaultconfig.go b/services/web/pkg/config/defaults/defaultconfig.go
index b24440867..110a12d8d 100644
--- a/services/web/pkg/config/defaults/defaultconfig.go
+++ b/services/web/pkg/config/defaults/defaultconfig.go
@@ -82,7 +82,7 @@ func DefaultConfig() *config.Config {
Asset: config.Asset{
Path: filepath.Join(defaults.BaseDataPath(), "web/assets"),
},
- GatewayAddress: "127.0.0.1:9142",
+ GatewayAddress: "com.owncloud.api.gateway",
Web: config.Web{
Path: "",
ThemeServer: "https://localhost:9200",
diff --git a/services/web/pkg/server/http/server.go b/services/web/pkg/server/http/server.go
index 564afabbd..8312f54b2 100644
--- a/services/web/pkg/server/http/server.go
+++ b/services/web/pkg/server/http/server.go
@@ -7,6 +7,7 @@ import (
chimiddleware "github.com/go-chi/chi/v5/middleware"
"github.com/owncloud/ocis/v2/ocis-pkg/cors"
"github.com/owncloud/ocis/v2/ocis-pkg/middleware"
+ "github.com/owncloud/ocis/v2/ocis-pkg/registry"
"github.com/owncloud/ocis/v2/ocis-pkg/service/http"
"github.com/owncloud/ocis/v2/ocis-pkg/version"
webmid "github.com/owncloud/ocis/v2/services/web/pkg/middleware"
@@ -35,7 +36,7 @@ func Server(opts ...Option) (http.Service, error) {
return http.Service{}, fmt.Errorf("could not initialize http service: %w", err)
}
- client, err := pool.GetGatewayServiceClient(options.Config.GatewayAddress)
+ gatewaySelector, err := pool.GatewaySelector(options.Config.GatewayAddress, pool.WithRegistry(registry.GetRegistry()))
if err != nil {
return http.Service{}, err
}
@@ -43,7 +44,7 @@ func Server(opts ...Option) (http.Service, error) {
handle := svc.NewService(
svc.Logger(options.Logger),
svc.Config(options.Config),
- svc.GatewayClient(client),
+ svc.GatewaySelector(gatewaySelector),
svc.Middleware(
chimiddleware.RealIP,
chimiddleware.RequestID,
diff --git a/services/web/pkg/service/v0/branding.go b/services/web/pkg/service/v0/branding.go
index 7d7cec63a..4eae62732 100644
--- a/services/web/pkg/service/v0/branding.go
+++ b/services/web/pkg/service/v0/branding.go
@@ -26,8 +26,14 @@ var (
// UploadLogo implements the endpoint to upload a custom logo for the oCIS instance.
func (p Web) UploadLogo(w http.ResponseWriter, r *http.Request) {
+ gatewayClient, err := p.gatewaySelector.Next()
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+
user := revactx.ContextMustGetUser(r.Context())
- rsp, err := p.gatewayClient.CheckPermission(r.Context(), &permissionsapi.CheckPermissionRequest{
+ rsp, err := gatewayClient.CheckPermission(r.Context(), &permissionsapi.CheckPermissionRequest{
Permission: "Logo.Write",
SubjectRef: &permissionsapi.SubjectReference{
Spec: &permissionsapi.SubjectReference_UserId{
@@ -79,8 +85,14 @@ func (p Web) UploadLogo(w http.ResponseWriter, r *http.Request) {
// ResetLogo implements the endpoint to reset the instance logo.
// The config will be changed back to use the embedded logo asset.
func (p Web) ResetLogo(w http.ResponseWriter, r *http.Request) {
+ gatewayClient, err := p.gatewaySelector.Next()
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+
user := revactx.ContextMustGetUser(r.Context())
- rsp, err := p.gatewayClient.CheckPermission(r.Context(), &permissionsapi.CheckPermissionRequest{
+ rsp, err := gatewayClient.CheckPermission(r.Context(), &permissionsapi.CheckPermissionRequest{
Permission: "Logo.Write",
SubjectRef: &permissionsapi.SubjectReference{
Spec: &permissionsapi.SubjectReference_UserId{
diff --git a/services/web/pkg/service/v0/option.go b/services/web/pkg/service/v0/option.go
index 8a0ed024b..8f6f261a4 100644
--- a/services/web/pkg/service/v0/option.go
+++ b/services/web/pkg/service/v0/option.go
@@ -4,6 +4,7 @@ import (
"net/http"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/services/web/pkg/config"
)
@@ -13,10 +14,10 @@ type Option func(o *Options)
// Options defines the available options for this package.
type Options struct {
- Logger log.Logger
- Config *config.Config
- Middleware []func(http.Handler) http.Handler
- GatewayClient gateway.GatewayAPIClient
+ Logger log.Logger
+ Config *config.Config
+ Middleware []func(http.Handler) http.Handler
+ GatewaySelector pool.Selectable[gateway.GatewayAPIClient]
}
// newOptions initializes the available default options.
@@ -51,9 +52,9 @@ func Middleware(val ...func(http.Handler) http.Handler) Option {
}
}
-// GatewayClient provides a function to set the GatewayClient option.
-func GatewayClient(client gateway.GatewayAPIClient) Option {
+// GatewaySelector provides a function to set the gatewaySelector option.
+func GatewaySelector(gatewaySelector pool.Selectable[gateway.GatewayAPIClient]) Option {
return func(o *Options) {
- o.GatewayClient = client
+ o.GatewaySelector = gatewaySelector
}
}
diff --git a/services/web/pkg/service/v0/service.go b/services/web/pkg/service/v0/service.go
index 2699f975f..7e557b357 100644
--- a/services/web/pkg/service/v0/service.go
+++ b/services/web/pkg/service/v0/service.go
@@ -11,6 +11,7 @@ import (
"time"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/go-chi/chi/v5"
"github.com/owncloud/ocis/v2/ocis-pkg/account"
"github.com/owncloud/ocis/v2/ocis-pkg/assetsfs"
@@ -42,11 +43,11 @@ func NewService(opts ...Option) Service {
m.Use(options.Middleware...)
svc := Web{
- logger: options.Logger,
- config: options.Config,
- mux: m,
- fs: assetsfs.New(web.Assets, options.Config.Asset.Path, options.Logger),
- gatewayClient: options.GatewayClient,
+ logger: options.Logger,
+ config: options.Config,
+ mux: m,
+ fs: assetsfs.New(web.Assets, options.Config.Asset.Path, options.Logger),
+ gatewaySelector: options.GatewaySelector,
}
m.Route(options.Config.HTTP.Root, func(r chi.Router) {
@@ -72,11 +73,11 @@ func NewService(opts ...Option) Service {
// Web defines implements the business logic for Service.
type Web struct {
- logger log.Logger
- config *config.Config
- mux *chi.Mux
- fs *assetsfs.FileSystem
- gatewayClient gateway.GatewayAPIClient
+ logger log.Logger
+ config *config.Config
+ mux *chi.Mux
+ fs *assetsfs.FileSystem
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
}
// ServeHTTP implements the Service interface.
diff --git a/services/webdav/pkg/service/v0/service.go b/services/webdav/pkg/service/v0/service.go
index fe63df7cb..a411a2968 100644
--- a/services/webdav/pkg/service/v0/service.go
+++ b/services/webdav/pkg/service/v0/service.go
@@ -17,10 +17,8 @@ import (
"github.com/cs3org/reva/v2/pkg/storage/utils/templates"
"github.com/go-chi/chi/v5"
"github.com/go-chi/render"
- merrors "go-micro.dev/v4/errors"
- "google.golang.org/grpc/metadata"
-
"github.com/owncloud/ocis/v2/ocis-pkg/log"
+ "github.com/owncloud/ocis/v2/ocis-pkg/registry"
"github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
thumbnailsmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/thumbnails/v0"
searchsvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/search/v0"
@@ -28,6 +26,8 @@ import (
"github.com/owncloud/ocis/v2/services/webdav/pkg/config"
"github.com/owncloud/ocis/v2/services/webdav/pkg/constants"
"github.com/owncloud/ocis/v2/services/webdav/pkg/dav/requests"
+ merrors "go-micro.dev/v4/errors"
+ "google.golang.org/grpc/metadata"
)
const (
@@ -64,9 +64,10 @@ func NewService(opts ...Option) (Service, error) {
if err != nil {
return nil, err
}
- gwc, err := pool.GetGatewayServiceClient(conf.RevaGateway,
+ gatewaySelector, err := pool.GatewaySelector(conf.RevaGateway,
pool.WithTLSCACert(conf.GRPCClientTLS.CACert),
pool.WithTLSMode(tm),
+ pool.WithRegistry(registry.GetRegistry()),
)
if err != nil {
return nil, err
@@ -78,7 +79,7 @@ func NewService(opts ...Option) (Service, error) {
mux: m,
searchClient: searchsvc.NewSearchProviderService("com.owncloud.api.search", grpc.DefaultClient()),
thumbnailsClient: thumbnailssvc.NewThumbnailService("com.owncloud.api.thumbnails", grpc.DefaultClient()),
- revaClient: gwc,
+ gatewaySelector: gatewaySelector,
}
m.Route(options.Config.HTTP.Root, func(r chi.Router) {
@@ -149,7 +150,7 @@ type Webdav struct {
mux *chi.Mux
searchClient searchsvc.SearchProviderService
thumbnailsClient thumbnailssvc.ThumbnailService
- revaClient gatewayv1beta1.GatewayAPIClient
+ gatewaySelector pool.Selectable[gatewayv1beta1.GatewayAPIClient]
}
// ServeHTTP implements the Service interface.
@@ -278,11 +279,17 @@ func (g Webdav) Thumbnail(w http.ResponseWriter, r *http.Request) {
t := r.Header.Get(TokenHeader)
- var user *userv1beta1.User
+ gatewayClient, err := g.gatewaySelector.Next()
+ if err != nil {
+ logger.Error().Err(err).Msg("could not get reva gatewayClient")
+ renderError(w, r, errInternalError("could not get reva gatewayClient"))
+ return
+ }
+ var user *userv1beta1.User
if tr.Identifier == "" {
// look up user from token via WhoAmI
- userRes, err := g.revaClient.WhoAmI(r.Context(), &gatewayv1beta1.WhoAmIRequest{
+ userRes, err := gatewayClient.WhoAmI(r.Context(), &gatewayv1beta1.WhoAmIRequest{
Token: t,
})
if err != nil {
@@ -299,7 +306,7 @@ func (g Webdav) Thumbnail(w http.ResponseWriter, r *http.Request) {
} else {
// look up user from URL via GetUserByClaim
ctx := metadata.AppendToOutgoingContext(r.Context(), TokenHeader, t)
- userRes, err := g.revaClient.GetUserByClaim(ctx, &userv1beta1.GetUserByClaimRequest{
+ userRes, err := gatewayClient.GetUserByClaim(ctx, &userv1beta1.GetUserByClaimRequest{
Claim: "username",
Value: tr.Identifier,
})
diff --git a/vendor/github.com/cs3org/reva/v2/cmd/revad/runtime/option.go b/vendor/github.com/cs3org/reva/v2/cmd/revad/runtime/option.go
index 44be8f959..daa1654e5 100644
--- a/vendor/github.com/cs3org/reva/v2/cmd/revad/runtime/option.go
+++ b/vendor/github.com/cs3org/reva/v2/cmd/revad/runtime/option.go
@@ -19,8 +19,8 @@
package runtime
import (
- "github.com/cs3org/reva/v2/pkg/registry"
"github.com/rs/zerolog"
+ "go-micro.dev/v4/registry"
)
// Option defines a single option function.
diff --git a/vendor/github.com/cs3org/reva/v2/cmd/revad/runtime/runtime.go b/vendor/github.com/cs3org/reva/v2/cmd/revad/runtime/runtime.go
index d161a23b4..ef99449fb 100644
--- a/vendor/github.com/cs3org/reva/v2/cmd/revad/runtime/runtime.go
+++ b/vendor/github.com/cs3org/reva/v2/cmd/revad/runtime/runtime.go
@@ -30,12 +30,11 @@ import (
"github.com/cs3org/reva/v2/cmd/revad/internal/grace"
"github.com/cs3org/reva/v2/pkg/logger"
- "github.com/cs3org/reva/v2/pkg/registry/memory"
+ "github.com/cs3org/reva/v2/pkg/registry"
"github.com/cs3org/reva/v2/pkg/rgrpc"
"github.com/cs3org/reva/v2/pkg/rhttp"
"github.com/cs3org/reva/v2/pkg/sharedconf"
rtrace "github.com/cs3org/reva/v2/pkg/trace"
- "github.com/cs3org/reva/v2/pkg/utils"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
"github.com/rs/zerolog"
@@ -55,19 +54,8 @@ func RunWithOptions(mainConf map[string]interface{}, pidFile string, opts ...Opt
parseSharedConfOrDie(mainConf["shared"])
coreConf := parseCoreConfOrDie(mainConf["core"])
- // TODO: one can pass the options from the config file to registry.New() and initialize a registry based upon config files.
- if options.Registry != nil {
- utils.GlobalRegistry = options.Registry
- } else if _, ok := mainConf["registry"]; ok {
- for _, services := range mainConf["registry"].(map[string]interface{}) {
- for sName, nodes := range services.(map[string]interface{}) {
- for _, instance := range nodes.([]interface{}) {
- if err := utils.GlobalRegistry.Add(memory.NewService(sName, instance.(map[string]interface{})["nodes"].([]interface{}))); err != nil {
- panic(err)
- }
- }
- }
- }
+ if err := registry.Init(options.Registry); err != nil {
+ panic(err)
}
run(mainConf, coreConf, options.Logger, pidFile)
diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/authprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/authprovider.go
index 52875480e..59214afff 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/authprovider.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/authprovider.go
@@ -44,6 +44,7 @@ func (s *svc) Authenticate(ctx context.Context, req *gateway.AuthenticateRequest
// find auth provider
c, err := s.findAuthProvider(ctx, req.Type)
if err != nil {
+ log.Err(err).Str("type", req.Type).Msg("error getting auth provider client")
return &gateway.AuthenticateResponse{
Status: status.NewInternal(ctx, "error getting auth provider client"),
}, nil
diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicstorageprovider/publicstorageprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicstorageprovider/publicstorageprovider.go
index afff2e729..48fb77791 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicstorageprovider/publicstorageprovider.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicstorageprovider/publicstorageprovider.go
@@ -59,8 +59,8 @@ type config struct {
}
type service struct {
- conf *config
- gateway gateway.GatewayAPIClient
+ conf *config
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
}
func (s *service) Close() error {
@@ -91,14 +91,14 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) {
return nil, err
}
- gateway, err := pool.GetGatewayServiceClient(c.GatewayAddr)
+ gatewaySelector, err := pool.GatewaySelector(c.GatewayAddr)
if err != nil {
return nil, err
}
service := &service{
- conf: c,
- gateway: gateway,
+ conf: c,
+ gatewaySelector: gatewaySelector,
}
return service, nil
@@ -114,7 +114,11 @@ func (s *service) SetArbitraryMetadata(ctx context.Context, req *provider.SetArb
Status: st,
}, nil
}
- return s.gateway.SetArbitraryMetadata(ctx, &provider.SetArbitraryMetadataRequest{Opaque: req.Opaque, Ref: ref, ArbitraryMetadata: req.ArbitraryMetadata})
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ return gatewayClient.SetArbitraryMetadata(ctx, &provider.SetArbitraryMetadataRequest{Opaque: req.Opaque, Ref: ref, ArbitraryMetadata: req.ArbitraryMetadata})
}
func (s *service) UnsetArbitraryMetadata(ctx context.Context, req *provider.UnsetArbitraryMetadataRequest) (*provider.UnsetArbitraryMetadataResponse, error) {
@@ -132,7 +136,11 @@ func (s *service) SetLock(ctx context.Context, req *provider.SetLockRequest) (*p
Status: st,
}, nil
}
- return s.gateway.SetLock(ctx, &provider.SetLockRequest{Opaque: req.Opaque, Ref: ref, Lock: req.Lock})
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ return gatewayClient.SetLock(ctx, &provider.SetLockRequest{Opaque: req.Opaque, Ref: ref, Lock: req.Lock})
}
// GetLock returns an existing lock on the given reference
@@ -146,7 +154,11 @@ func (s *service) GetLock(ctx context.Context, req *provider.GetLockRequest) (*p
Status: st,
}, nil
}
- return s.gateway.GetLock(ctx, &provider.GetLockRequest{Opaque: req.Opaque, Ref: ref})
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ return gatewayClient.GetLock(ctx, &provider.GetLockRequest{Opaque: req.Opaque, Ref: ref})
}
// RefreshLock refreshes an existing lock on the given reference
@@ -160,7 +172,11 @@ func (s *service) RefreshLock(ctx context.Context, req *provider.RefreshLockRequ
Status: st,
}, nil
}
- return s.gateway.RefreshLock(ctx, &provider.RefreshLockRequest{Opaque: req.Opaque, Ref: ref, Lock: req.Lock})
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ return gatewayClient.RefreshLock(ctx, &provider.RefreshLockRequest{Opaque: req.Opaque, Ref: ref, Lock: req.Lock})
}
// Unlock removes an existing lock from the given reference
@@ -174,7 +190,11 @@ func (s *service) Unlock(ctx context.Context, req *provider.UnlockRequest) (*pro
Status: st,
}, nil
}
- return s.gateway.Unlock(ctx, &provider.UnlockRequest{Opaque: req.Opaque, Ref: ref, Lock: req.Lock})
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ return gatewayClient.Unlock(ctx, &provider.UnlockRequest{Opaque: req.Opaque, Ref: ref, Lock: req.Lock})
}
func (s *service) InitiateFileDownload(ctx context.Context, req *provider.InitiateFileDownloadRequest) (*provider.InitiateFileDownloadResponse, error) {
@@ -265,7 +285,11 @@ func (s *service) initiateFileDownload(ctx context.Context, req *provider.Initia
Ref: cs3Ref,
}
- dRes, err := s.gateway.InitiateFileDownload(ctx, dReq)
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ dRes, err := gatewayClient.InitiateFileDownload(ctx, dReq)
if err != nil {
return &provider.InitiateFileDownloadResponse{
Status: status.NewInternal(ctx, "initiateFileDownload: error calling InitiateFileDownload"),
@@ -319,7 +343,11 @@ func (s *service) InitiateFileUpload(ctx context.Context, req *provider.Initiate
Opaque: req.Opaque,
}
- uRes, err := s.gateway.InitiateFileUpload(ctx, uReq)
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ uRes, err := gatewayClient.InitiateFileUpload(ctx, uReq)
if err != nil {
return &provider.InitiateFileUploadResponse{
Status: status.NewInternal(ctx, "InitiateFileUpload: error calling InitiateFileUpload"),
@@ -543,7 +571,11 @@ func (s *service) CreateContainer(ctx context.Context, req *provider.CreateConta
var res *provider.CreateContainerResponse
// the call has to be made to the gateway instead of the storage.
- res, err = s.gateway.CreateContainer(ctx, &provider.CreateContainerRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ res, err = gatewayClient.CreateContainer(ctx, &provider.CreateContainerRequest{
Ref: cs3Ref,
})
if err != nil {
@@ -568,7 +600,11 @@ func (s *service) TouchFile(ctx context.Context, req *provider.TouchFileRequest)
Status: st,
}, nil
}
- return s.gateway.TouchFile(ctx, &provider.TouchFileRequest{Opaque: req.Opaque, Ref: ref})
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ return gatewayClient.TouchFile(ctx, &provider.TouchFileRequest{Opaque: req.Opaque, Ref: ref})
}
func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*provider.DeleteResponse, error) {
@@ -596,7 +632,11 @@ func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*pro
var res *provider.DeleteResponse
// the call has to be made to the gateway instead of the storage.
- res, err = s.gateway.Delete(ctx, &provider.DeleteRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ res, err = gatewayClient.Delete(ctx, &provider.DeleteRequest{
Ref: cs3Ref,
})
if err != nil {
@@ -658,7 +698,11 @@ func (s *service) Move(ctx context.Context, req *provider.MoveRequest) (*provide
var res *provider.MoveResponse
// the call has to be made to the gateway instead of the storage.
- res, err = s.gateway.Move(ctx, &provider.MoveRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ res, err = gatewayClient.Move(ctx, &provider.MoveRequest{
Source: cs3RefSource,
Destination: cs3RefDestination,
})
@@ -721,7 +765,11 @@ func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provide
Path: utils.MakeRelativePath(req.Ref.Path),
}
- statResponse, err := s.gateway.Stat(ctx, &provider.StatRequest{Ref: ref})
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ statResponse, err := gatewayClient.Stat(ctx, &provider.StatRequest{Ref: ref})
if err != nil {
return &provider.StatResponse{
Status: status.NewInternal(ctx, "Stat: error calling Stat for ref:"+req.Ref.String()),
@@ -796,7 +844,11 @@ func (s *service) ListContainer(ctx context.Context, req *provider.ListContainer
}, nil
}
- listContainerR, err := s.gateway.ListContainer(
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ listContainerR, err := gatewayClient.ListContainer(
ctx,
&provider.ListContainerRequest{
Ref: &provider.Reference{
@@ -926,7 +978,11 @@ func (s *service) resolveToken(ctx context.Context, token string) (*link.PublicS
return nil, nil, publicShareResponse.Status, nil
}
- sRes, err := s.gateway.Stat(ctx, &provider.StatRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ sRes, err := gatewayClient.Stat(ctx, &provider.StatRequest{
Ref: &provider.Reference{
ResourceId: publicShareResponse.GetShare().GetResourceId(),
},
diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go
index 709631a04..4b1a12f8b 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go
@@ -62,8 +62,8 @@ type config struct {
}
type service struct {
- gateway gateway.GatewayAPIClient
- sharesProviderClient collaboration.CollaborationAPIClient
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
+ sharingCollaborationSelector pool.Selectable[collaboration.CollaborationAPIClient]
}
func (s *service) Close() error {
@@ -86,24 +86,24 @@ func NewDefault(m map[string]interface{}, _ *grpc.Server) (rgrpc.Service, error)
return nil, err
}
- gateway, err := pool.GetGatewayServiceClient(sharedconf.GetGatewaySVC(c.GatewayAddr))
+ gatewaySelector, err := pool.GatewaySelector(sharedconf.GetGatewaySVC(c.GatewayAddr))
if err != nil {
return nil, err
}
- client, err := pool.GetUserShareProviderClient(sharedconf.GetGatewaySVC(c.UserShareProviderEndpoint))
+ sharingCollaborationSelector, err := pool.SharingCollaborationSelector(sharedconf.GetGatewaySVC(c.UserShareProviderEndpoint))
if err != nil {
return nil, errors.Wrap(err, "sharesstorageprovider: error getting UserShareProvider client")
}
- return New(gateway, client)
+ return New(gatewaySelector, sharingCollaborationSelector)
}
// New returns a new instance of the SharesStorageProvider service
-func New(gateway gateway.GatewayAPIClient, c collaboration.CollaborationAPIClient) (rgrpc.Service, error) {
+func New(gatewaySelector pool.Selectable[gateway.GatewayAPIClient], sharingCollaborationSelector pool.Selectable[collaboration.CollaborationAPIClient]) (rgrpc.Service, error) {
s := &service{
- gateway: gateway,
- sharesProviderClient: c,
+ gatewaySelector: gatewaySelector,
+ sharingCollaborationSelector: sharingCollaborationSelector,
}
return s, nil
}
@@ -123,7 +123,12 @@ func (s *service) SetArbitraryMetadata(ctx context.Context, req *provider.SetArb
}, nil
}
- return s.gateway.SetArbitraryMetadata(ctx, &provider.SetArbitraryMetadataRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ return gatewayClient.SetArbitraryMetadata(ctx, &provider.SetArbitraryMetadataRequest{
Opaque: req.Opaque,
Ref: buildReferenceInShare(req.Ref, receivedShare),
ArbitraryMetadata: req.ArbitraryMetadata,
@@ -145,7 +150,12 @@ func (s *service) UnsetArbitraryMetadata(ctx context.Context, req *provider.Unse
}, nil
}
- return s.gateway.UnsetArbitraryMetadata(ctx, &provider.UnsetArbitraryMetadataRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ return gatewayClient.UnsetArbitraryMetadata(ctx, &provider.UnsetArbitraryMetadataRequest{
Opaque: req.Opaque,
Ref: buildReferenceInShare(req.Ref, receivedShare),
ArbitraryMetadataKeys: req.ArbitraryMetadataKeys,
@@ -167,7 +177,12 @@ func (s *service) InitiateFileDownload(ctx context.Context, req *provider.Initia
}, nil
}
- gwres, err := s.gateway.InitiateFileDownload(ctx, &provider.InitiateFileDownloadRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ gwres, err := gatewayClient.InitiateFileDownload(ctx, &provider.InitiateFileDownloadRequest{
Opaque: req.Opaque,
Ref: buildReferenceInShare(req.Ref, receivedShare),
LockId: req.LockId,
@@ -229,7 +244,13 @@ func (s *service) InitiateFileUpload(ctx context.Context, req *provider.Initiate
Status: status.NewPermissionDenied(ctx, nil, "share does not grant InitiateFileDownload permission"),
}, nil
}
- gwres, err := s.gateway.InitiateFileUpload(ctx, &provider.InitiateFileUploadRequest{
+
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ gwres, err := gatewayClient.InitiateFileUpload(ctx, &provider.InitiateFileUploadRequest{
Opaque: req.Opaque,
Ref: buildReferenceInShare(req.Ref, receivedShare),
LockId: req.LockId,
@@ -513,7 +534,12 @@ func (s *service) CreateContainer(ctx context.Context, req *provider.CreateConta
}, nil
}
- return s.gateway.CreateContainer(ctx, &provider.CreateContainerRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ return gatewayClient.CreateContainer(ctx, &provider.CreateContainerRequest{
Opaque: req.Opaque,
Ref: buildReferenceInShare(req.Ref, receivedShare),
})
@@ -548,7 +574,12 @@ func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*pro
}, nil
}
- return s.gateway.Delete(ctx, &provider.DeleteRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ return gatewayClient.Delete(ctx, &provider.DeleteRequest{
Opaque: req.Opaque,
Ref: buildReferenceInShare(req.Ref, receivedShare),
})
@@ -584,7 +615,12 @@ func (s *service) Move(ctx context.Context, req *provider.MoveRequest) (*provide
Path: filepath.Base(req.Destination.Path),
}
- _, err = s.sharesProviderClient.UpdateReceivedShare(ctx, &collaboration.UpdateReceivedShareRequest{
+ sharingCollaborationClient, err := s.sharingCollaborationSelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = sharingCollaborationClient.UpdateReceivedShare(ctx, &collaboration.UpdateReceivedShareRequest{
Share: srcReceivedShare,
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"state", "mount_point"}},
})
@@ -613,7 +649,12 @@ func (s *service) Move(ctx context.Context, req *provider.MoveRequest) (*provide
}, nil
}
- return s.gateway.Move(ctx, &provider.MoveRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ return gatewayClient.Move(ctx, &provider.MoveRequest{
Opaque: req.Opaque,
Source: buildReferenceInShare(req.Source, srcReceivedShare),
Destination: buildReferenceInShare(req.Destination, dstReceivedShare),
@@ -712,8 +753,13 @@ func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provide
}, nil
}
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
// TODO return reference?
- return s.gateway.Stat(ctx, &provider.StatRequest{
+ return gatewayClient.Stat(ctx, &provider.StatRequest{
Opaque: req.Opaque,
Ref: buildReferenceInShare(req.Ref, receivedShare),
ArbitraryMetadataKeys: req.ArbitraryMetadataKeys,
@@ -742,13 +788,18 @@ func (s *service) ListContainer(ctx context.Context, req *provider.ListContainer
return nil, errors.Wrap(err, "sharesstorageprovider: error calling ListReceivedSharesRequest")
}
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
infos := []*provider.ResourceInfo{}
for _, share := range receivedShares {
if share.GetState() != collaboration.ShareState_SHARE_STATE_ACCEPTED {
continue
}
- statRes, err := s.gateway.Stat(ctx, &provider.StatRequest{
+ statRes, err := gatewayClient.Stat(ctx, &provider.StatRequest{
Opaque: req.Opaque,
Ref: &provider.Reference{
ResourceId: share.Share.ResourceId,
@@ -802,7 +853,12 @@ func (s *service) ListContainer(ctx context.Context, req *provider.ListContainer
}, nil
}
- return s.gateway.ListContainer(ctx, &provider.ListContainerRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ return gatewayClient.ListContainer(ctx, &provider.ListContainerRequest{
Opaque: req.Opaque,
Ref: buildReferenceInShare(req.Ref, receivedShare),
ArbitraryMetadataKeys: req.ArbitraryMetadataKeys,
@@ -824,7 +880,12 @@ func (s *service) ListFileVersions(ctx context.Context, req *provider.ListFileVe
}, nil
}
- return s.gateway.ListFileVersions(ctx, &provider.ListFileVersionsRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ return gatewayClient.ListFileVersions(ctx, &provider.ListFileVersionsRequest{
Opaque: req.Opaque,
Ref: buildReferenceInShare(req.Ref, receivedShare),
})
@@ -846,7 +907,12 @@ func (s *service) RestoreFileVersion(ctx context.Context, req *provider.RestoreF
}, nil
}
- return s.gateway.RestoreFileVersion(ctx, &provider.RestoreFileVersionRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ return gatewayClient.RestoreFileVersion(ctx, &provider.RestoreFileVersionRequest{
Opaque: req.Opaque,
Ref: buildReferenceInShare(req.Ref, receivedShare),
})
@@ -911,7 +977,12 @@ func (s *service) TouchFile(ctx context.Context, req *provider.TouchFileRequest)
}, nil
}
- return s.gateway.TouchFile(ctx, &provider.TouchFileRequest{
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ return gatewayClient.TouchFile(ctx, &provider.TouchFileRequest{
Opaque: req.Opaque,
Ref: buildReferenceInShare(req.Ref, receivedShare),
})
@@ -938,10 +1009,15 @@ func (s *service) resolveAcceptedShare(ctx context.Context, ref *provider.Refere
return nil, status.NewNotFound(ctx, "sharesstorageprovider: not found "+ref.String()), nil
}
+ sharingCollaborationClient, err := s.sharingCollaborationSelector.Next()
+ if err != nil {
+ return nil, nil, err
+ }
+
// we can get the share if the reference carries a share id
if ref.ResourceId.OpaqueId != utils.ShareStorageProviderID {
// look up share for this resourceid
- lsRes, err := s.sharesProviderClient.GetReceivedShare(ctx, &collaboration.GetReceivedShareRequest{
+ lsRes, err := sharingCollaborationClient.GetReceivedShare(ctx, &collaboration.GetReceivedShareRequest{
Ref: &collaboration.ShareReference{
Spec: &collaboration.ShareReference_Id{
Id: &collaboration.ShareId{
@@ -968,7 +1044,7 @@ func (s *service) resolveAcceptedShare(ctx context.Context, ref *provider.Refere
// we need to list accepted shares and match the path
// look up share for this resourceid
- lsRes, err := s.sharesProviderClient.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{
+ lsRes, err := sharingCollaborationClient.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{
Filters: []*collaboration.Filter{
// FIXME filter by accepted ... and by mountpoint?
},
@@ -997,7 +1073,12 @@ func (s *service) rejectReceivedShare(ctx context.Context, receivedShare *collab
receivedShare.State = collaboration.ShareState_SHARE_STATE_REJECTED
receivedShare.MountPoint = nil
- res, err := s.sharesProviderClient.UpdateReceivedShare(ctx, &collaboration.UpdateReceivedShareRequest{
+ sharingCollaborationClient, err := s.sharingCollaborationSelector.Next()
+ if err != nil {
+ return err
+ }
+
+ res, err := sharingCollaborationClient.UpdateReceivedShare(ctx, &collaboration.UpdateReceivedShareRequest{
Share: receivedShare,
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"state", "mount_point"}},
})
@@ -1009,7 +1090,12 @@ func (s *service) rejectReceivedShare(ctx context.Context, receivedShare *collab
}
func (s *service) fetchShares(ctx context.Context) ([]*collaboration.ReceivedShare, map[string]*provider.ResourceInfo, error) {
- lsRes, err := s.sharesProviderClient.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{
+ sharingCollaborationClient, err := s.sharingCollaborationSelector.Next()
+ if err != nil {
+ return nil, nil, err
+ }
+
+ lsRes, err := sharingCollaborationClient.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{
// FIXME filter by received shares for resource id - listing all shares is tooo expensive!
})
if err != nil {
@@ -1019,6 +1105,11 @@ func (s *service) fetchShares(ctx context.Context) ([]*collaboration.ReceivedSha
return nil, nil, fmt.Errorf("sharesstorageprovider: error calling ListReceivedSharesRequest")
}
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, nil, err
+ }
+
shareMetaData := make(map[string]*provider.ResourceInfo, len(lsRes.Shares))
for _, rs := range lsRes.Shares {
// only stat accepted shares
@@ -1029,7 +1120,7 @@ func (s *service) fetchShares(ctx context.Context) ([]*collaboration.ReceivedSha
// convert backwards compatible share id
rs.Share.ResourceId.StorageId, rs.Share.ResourceId.SpaceId = storagespace.SplitStorageID(rs.Share.ResourceId.StorageId)
}
- sRes, err := s.gateway.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{ResourceId: rs.Share.ResourceId}})
+ sRes, err := gatewayClient.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{ResourceId: rs.Share.ResourceId}})
if err != nil {
appctx.GetLogger(ctx).Error().
Err(err).
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/archiver/handler.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/archiver/handler.go
index 831fb5718..d668ad625 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/archiver/handler.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/archiver/handler.go
@@ -47,11 +47,11 @@ import (
)
type svc struct {
- config *Config
- gtwClient gateway.GatewayAPIClient
- log *zerolog.Logger
- walker walker.Walker
- downloader downloader.Downloader
+ config *Config
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
+ log *zerolog.Logger
+ walker walker.Walker
+ downloader downloader.Downloader
allowedFolders []*regexp.Regexp
}
@@ -82,7 +82,7 @@ func New(conf map[string]interface{}, log *zerolog.Logger) (global.Service, erro
c.init()
- gtw, err := pool.GetGatewayServiceClient(c.GatewaySvc)
+ gatewaySelector, err := pool.GatewaySelector(c.GatewaySvc)
if err != nil {
return nil, err
}
@@ -98,12 +98,12 @@ func New(conf map[string]interface{}, log *zerolog.Logger) (global.Service, erro
}
return &svc{
- config: c,
- gtwClient: gtw,
- downloader: downloader.NewDownloader(gtw, rhttp.Insecure(c.Insecure), rhttp.Timeout(time.Duration(c.Timeout*int64(time.Second)))),
- walker: walker.NewWalker(gtw),
- log: log,
- allowedFolders: allowedFolderRegex,
+ config: c,
+ gatewaySelector: gatewaySelector,
+ downloader: downloader.NewDownloader(gatewaySelector, rhttp.Insecure(c.Insecure), rhttp.Timeout(time.Duration(c.Timeout*int64(time.Second)))),
+ walker: walker.NewWalker(gatewaySelector),
+ log: log,
+ allowedFolders: allowedFolderRegex,
}, nil
}
@@ -138,10 +138,14 @@ func (s *svc) getResources(ctx context.Context, paths, ids []string) ([]*provide
}
+ gatewayClient, err := s.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
for _, p := range paths {
// id is base64 encoded and after decoding has the form :
- resp, err := s.gtwClient.Stat(ctx, &provider.StatRequest{
+ resp, err := gatewayClient.Stat(ctx, &provider.StatRequest{
Ref: &provider.Reference{
Path: p,
},
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/copy.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/copy.go
index 1aa89ac6e..7b4bce24e 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/copy.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/copy.go
@@ -36,6 +36,7 @@ import (
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/spacelookup"
"github.com/cs3org/reva/v2/pkg/appctx"
"github.com/cs3org/reva/v2/pkg/errtypes"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/rhttp"
"github.com/cs3org/reva/v2/pkg/rhttp/router"
"github.com/cs3org/reva/v2/pkg/storagespace"
@@ -105,7 +106,7 @@ func (s *svc) handlePathCopy(w http.ResponseWriter, r *http.Request, ns string)
sublog := appctx.GetLogger(ctx).With().Str("src", src).Str("dst", dst).Logger()
- srcSpace, status, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gwClient, src)
+ srcSpace, status, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gatewaySelector, src)
if err != nil {
sublog.Error().Err(err).Str("path", src).Msg("failed to look up storage space")
w.WriteHeader(http.StatusInternalServerError)
@@ -115,7 +116,7 @@ func (s *svc) handlePathCopy(w http.ResponseWriter, r *http.Request, ns string)
errors.HandleErrorStatus(&sublog, w, status)
return
}
- dstSpace, status, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gwClient, dst)
+ dstSpace, status, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gatewaySelector, dst)
if err != nil {
sublog.Error().Err(err).Str("path", dst).Msg("failed to look up storage space")
w.WriteHeader(http.StatusInternalServerError)
@@ -131,17 +132,22 @@ func (s *svc) handlePathCopy(w http.ResponseWriter, r *http.Request, ns string)
return
}
- if err := s.executePathCopy(ctx, s.gwClient, w, r, cp); err != nil {
+ if err := s.executePathCopy(ctx, s.gatewaySelector, w, r, cp); err != nil {
sublog.Error().Err(err).Str("depth", cp.depth.String()).Msg("error executing path copy")
w.WriteHeader(http.StatusInternalServerError)
}
w.WriteHeader(cp.successCode)
}
-func (s *svc) executePathCopy(ctx context.Context, client gateway.GatewayAPIClient, w http.ResponseWriter, r *http.Request, cp *copy) error {
+func (s *svc) executePathCopy(ctx context.Context, selector pool.Selectable[gateway.GatewayAPIClient], w http.ResponseWriter, r *http.Request, cp *copy) error {
log := appctx.GetLogger(ctx)
log.Debug().Str("src", cp.sourceInfo.Path).Str("dst", cp.destination.Path).Msg("descending")
+ client, err := selector.Next()
+ if err != nil {
+ return err
+ }
+
var fileid string
if cp.sourceInfo.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
// create dir
@@ -192,7 +198,7 @@ func (s *svc) executePathCopy(ctx context.Context, client gateway.GatewayAPIClie
ResourceId: cp.destination.ResourceId,
Path: utils.MakeRelativePath(filepath.Join(cp.destination.Path, child)),
}
- err := s.executePathCopy(ctx, client, w, r, ©{source: src, sourceInfo: res.Infos[i], destination: childDst, depth: cp.depth, successCode: cp.successCode})
+ err := s.executePathCopy(ctx, selector, w, r, ©{source: src, sourceInfo: res.Infos[i], destination: childDst, depth: cp.depth, successCode: cp.successCode})
if err != nil {
return err
}
@@ -354,7 +360,7 @@ func (s *svc) handleSpacesCopy(w http.ResponseWriter, r *http.Request, spaceID s
return
}
- err = s.executeSpacesCopy(ctx, w, s.gwClient, cp)
+ err = s.executeSpacesCopy(ctx, w, s.gatewaySelector, cp)
if err != nil {
sublog.Error().Err(err).Str("depth", cp.depth.String()).Msg("error descending directory")
w.WriteHeader(http.StatusInternalServerError)
@@ -362,10 +368,15 @@ func (s *svc) handleSpacesCopy(w http.ResponseWriter, r *http.Request, spaceID s
w.WriteHeader(cp.successCode)
}
-func (s *svc) executeSpacesCopy(ctx context.Context, w http.ResponseWriter, client gateway.GatewayAPIClient, cp *copy) error {
+func (s *svc) executeSpacesCopy(ctx context.Context, w http.ResponseWriter, selector pool.Selectable[gateway.GatewayAPIClient], cp *copy) error {
log := appctx.GetLogger(ctx)
log.Debug().Interface("src", cp.sourceInfo).Interface("dst", cp.destination).Msg("descending")
+ client, err := selector.Next()
+ if err != nil {
+ return err
+ }
+
var fileid string
if cp.sourceInfo.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
// create dir
@@ -410,7 +421,7 @@ func (s *svc) executeSpacesCopy(ctx context.Context, w http.ResponseWriter, clie
ResourceId: cp.destination.ResourceId,
Path: utils.MakeRelativePath(path.Join(cp.destination.Path, res.Infos[i].Path)),
}
- err := s.executeSpacesCopy(ctx, w, client, ©{sourceInfo: res.Infos[i], destination: childRef, depth: cp.depth, successCode: cp.successCode})
+ err := s.executeSpacesCopy(ctx, w, selector, ©{sourceInfo: res.Infos[i], destination: childRef, depth: cp.depth, successCode: cp.successCode})
if err != nil {
return err
}
@@ -528,7 +539,7 @@ func (s *svc) executeSpacesCopy(ctx context.Context, w http.ResponseWriter, clie
}
func (s *svc) prepareCopy(ctx context.Context, w http.ResponseWriter, r *http.Request, srcRef, dstRef *provider.Reference, log *zerolog.Logger) *copy {
- isChild, err := s.referenceIsChildOf(ctx, s.gwClient, dstRef, srcRef)
+ isChild, err := s.referenceIsChildOf(ctx, s.gatewaySelector, dstRef, srcRef)
if err != nil {
switch err.(type) {
case errtypes.IsNotSupported:
@@ -573,8 +584,15 @@ func (s *svc) prepareCopy(ctx context.Context, w http.ResponseWriter, r *http.Re
log.Debug().Bool("overwrite", overwrite).Str("depth", depth.String()).Msg("copy")
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ log.Error().Err(err).Msg("error selecting next client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return nil
+ }
+
srcStatReq := &provider.StatRequest{Ref: srcRef}
- srcStatRes, err := s.gwClient.Stat(ctx, srcStatReq)
+ srcStatRes, err := client.Stat(ctx, srcStatReq)
switch {
case err != nil:
log.Error().Err(err).Msg("error sending grpc stat request")
@@ -592,7 +610,7 @@ func (s *svc) prepareCopy(ctx context.Context, w http.ResponseWriter, r *http.Re
}
dstStatReq := &provider.StatRequest{Ref: dstRef}
- dstStatRes, err := s.gwClient.Stat(ctx, dstStatReq)
+ dstStatRes, err := client.Stat(ctx, dstStatReq)
switch {
case err != nil:
log.Error().Err(err).Msg("error sending grpc stat request")
@@ -621,7 +639,7 @@ func (s *svc) prepareCopy(ctx context.Context, w http.ResponseWriter, r *http.Re
(dstStatRes.Info.Type == provider.ResourceType_RESOURCE_TYPE_FILE &&
srcStatRes.Info.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER) {
delReq := &provider.DeleteRequest{Ref: dstRef}
- delRes, err := s.gwClient.Delete(ctx, delReq)
+ delRes, err := client.Delete(ctx, delReq)
if err != nil {
log.Error().Err(err).Msg("error sending grpc delete request")
w.WriteHeader(http.StatusInternalServerError)
@@ -640,7 +658,7 @@ func (s *svc) prepareCopy(ctx context.Context, w http.ResponseWriter, r *http.Re
Path: utils.MakeRelativePath(p),
}
intStatReq := &provider.StatRequest{Ref: pRef}
- intStatRes, err := s.gwClient.Stat(ctx, intStatReq)
+ intStatRes, err := client.Stat(ctx, intStatReq)
if err != nil {
log.Error().Err(err).Msg("error sending grpc stat request")
w.WriteHeader(http.StatusInternalServerError)
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/dav.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/dav.go
index 279534652..b3a133b24 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/dav.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/dav.go
@@ -32,6 +32,7 @@ import (
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/net"
"github.com/cs3org/reva/v2/pkg/appctx"
ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/rhttp/router"
"github.com/cs3org/reva/v2/pkg/utils"
"google.golang.org/grpc/metadata"
@@ -188,7 +189,7 @@ func (h *DavHandler) Handler(s *svc) http.Handler {
var pass string
var err error
if _, pass, hasValidBasicAuthHeader = r.BasicAuth(); hasValidBasicAuthHeader {
- res, err = handleBasicAuth(r.Context(), s.gwClient, token, pass)
+ res, err = handleBasicAuth(r.Context(), s.gatewaySelector, token, pass)
} else {
q := r.URL.Query()
sig := q.Get("signature")
@@ -198,7 +199,7 @@ func (h *DavHandler) Handler(s *svc) http.Handler {
w.WriteHeader(http.StatusUnauthorized)
return
}
- res, err = handleSignatureAuth(r.Context(), s.gwClient, token, sig, expiration)
+ res, err = handleSignatureAuth(r.Context(), s.gatewaySelector, token, sig, expiration)
}
switch {
@@ -232,7 +233,7 @@ func (h *DavHandler) Handler(s *svc) http.Handler {
r = r.WithContext(ctx)
// the public share manager knew the token, but does the referenced target still exist?
- sRes, err := getTokenStatInfo(ctx, s.gwClient, token)
+ sRes, err := getTokenStatInfo(ctx, s.gatewaySelector, token)
switch {
case err != nil:
log.Error().Err(err).Msg("error sending grpc stat request")
@@ -271,7 +272,12 @@ func (h *DavHandler) Handler(s *svc) http.Handler {
})
}
-func getTokenStatInfo(ctx context.Context, client gatewayv1beta1.GatewayAPIClient, token string) (*provider.StatResponse, error) {
+func getTokenStatInfo(ctx context.Context, selector pool.Selectable[gatewayv1beta1.GatewayAPIClient], token string) (*provider.StatResponse, error) {
+ client, err := selector.Next()
+ if err != nil {
+ return nil, err
+ }
+
return client.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{
ResourceId: &provider.ResourceId{
StorageId: utils.PublicStorageProviderID,
@@ -281,7 +287,11 @@ func getTokenStatInfo(ctx context.Context, client gatewayv1beta1.GatewayAPIClien
}})
}
-func handleBasicAuth(ctx context.Context, c gatewayv1beta1.GatewayAPIClient, token, pw string) (*gatewayv1beta1.AuthenticateResponse, error) {
+func handleBasicAuth(ctx context.Context, selector pool.Selectable[gatewayv1beta1.GatewayAPIClient], token, pw string) (*gatewayv1beta1.AuthenticateResponse, error) {
+ c, err := selector.Next()
+ if err != nil {
+ return nil, err
+ }
authenticateRequest := gatewayv1beta1.AuthenticateRequest{
Type: "publicshares",
ClientId: token,
@@ -291,7 +301,11 @@ func handleBasicAuth(ctx context.Context, c gatewayv1beta1.GatewayAPIClient, tok
return c.Authenticate(ctx, &authenticateRequest)
}
-func handleSignatureAuth(ctx context.Context, c gatewayv1beta1.GatewayAPIClient, token, sig, expiration string) (*gatewayv1beta1.AuthenticateResponse, error) {
+func handleSignatureAuth(ctx context.Context, selector pool.Selectable[gatewayv1beta1.GatewayAPIClient], token, sig, expiration string) (*gatewayv1beta1.AuthenticateResponse, error) {
+ c, err := selector.Next()
+ if err != nil {
+ return nil, err
+ }
authenticateRequest := gatewayv1beta1.AuthenticateRequest{
Type: "publicshares",
ClientId: token,
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/delete.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/delete.go
index c09100037..24ed1a7ad 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/delete.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/delete.go
@@ -45,7 +45,7 @@ func (s *svc) handlePathDelete(w http.ResponseWriter, r *http.Request, ns string
fn := path.Join(ns, r.URL.Path)
- space, rpcStatus, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gwClient, fn)
+ space, rpcStatus, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gatewaySelector, fn)
switch {
case err != nil:
span.RecordError(err)
@@ -73,7 +73,12 @@ func (s *svc) handleDelete(ctx context.Context, w http.ResponseWriter, r *http.R
return http.StatusBadRequest, errtypes.BadRequest("invalid if header")
}
- res, err := s.gwClient.Delete(ctx, req)
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ return http.StatusInternalServerError, errtypes.InternalError(err.Error())
+ }
+
+ res, err := client.Delete(ctx, req)
switch {
case err != nil:
span.RecordError(err)
@@ -92,7 +97,7 @@ func (s *svc) handleDelete(ctx context.Context, w http.ResponseWriter, r *http.R
status = http.StatusLocked
}
// check if user has access to resource
- sRes, err := s.gwClient.Stat(ctx, &provider.StatRequest{Ref: ref})
+ sRes, err := client.Stat(ctx, &provider.StatRequest{Ref: ref})
if err != nil {
span.RecordError(err)
return http.StatusInternalServerError, err
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/get.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/get.go
index 21b10ff7a..191d9cc04 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/get.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/get.go
@@ -45,7 +45,7 @@ func (s *svc) handlePathGet(w http.ResponseWriter, r *http.Request, ns string) {
sublog := appctx.GetLogger(ctx).With().Str("path", fn).Str("svc", "ocdav").Str("handler", "get").Logger()
- space, status, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gwClient, fn)
+ space, status, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gatewaySelector, fn)
if err != nil {
sublog.Error().Err(err).Str("path", fn).Msg("failed to look up storage space")
w.WriteHeader(http.StatusInternalServerError)
@@ -60,10 +60,16 @@ func (s *svc) handlePathGet(w http.ResponseWriter, r *http.Request, ns string) {
}
func (s *svc) handleGet(ctx context.Context, w http.ResponseWriter, r *http.Request, ref *provider.Reference, dlProtocol string, log zerolog.Logger) {
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ log.Error().Err(err).Msg("error selecting next client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
sReq := &provider.StatRequest{
Ref: ref,
}
- sRes, err := s.gwClient.Stat(ctx, sReq)
+ sRes, err := client.Stat(ctx, sReq)
if err != nil {
log.Error().Err(err).Msg("error stat resource")
w.WriteHeader(http.StatusInternalServerError)
@@ -85,7 +91,7 @@ func (s *svc) handleGet(ctx context.Context, w http.ResponseWriter, r *http.Requ
}
dReq := &provider.InitiateFileDownloadRequest{Ref: ref}
- dRes, err := s.gwClient.InitiateFileDownload(ctx, dReq)
+ dRes, err := client.InitiateFileDownload(ctx, dReq)
switch {
case err != nil:
log.Error().Err(err).Msg("error initiating file download")
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/head.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/head.go
index 702193b39..f055d18f4 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/head.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/head.go
@@ -48,7 +48,7 @@ func (s *svc) handlePathHead(w http.ResponseWriter, r *http.Request, ns string)
sublog := appctx.GetLogger(ctx).With().Str("path", fn).Logger()
- space, status, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gwClient, fn)
+ space, status, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gatewaySelector, fn)
if err != nil {
sublog.Error().Err(err).Str("path", fn).Msg("failed to look up storage space")
w.WriteHeader(http.StatusInternalServerError)
@@ -63,9 +63,14 @@ func (s *svc) handlePathHead(w http.ResponseWriter, r *http.Request, ns string)
}
func (s *svc) handleHead(ctx context.Context, w http.ResponseWriter, r *http.Request, ref *provider.Reference, log zerolog.Logger) {
-
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ log.Error().Err(err).Msg("error selecting next client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
req := &provider.StatRequest{Ref: ref}
- res, err := s.gwClient.Stat(ctx, req)
+ res, err := client.Stat(ctx, req)
if err != nil {
log.Error().Err(err).Msg("error sending grpc stat request")
w.WriteHeader(http.StatusInternalServerError)
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/locks.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/locks.go
index d822b1055..54d69a1e2 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/locks.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/locks.go
@@ -41,6 +41,7 @@ import (
"github.com/cs3org/reva/v2/pkg/appctx"
ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/errtypes"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/google/uuid"
"go.opentelemetry.io/otel/attribute"
)
@@ -159,14 +160,14 @@ type LockSystem interface {
}
// NewCS3LS returns a new CS3 based LockSystem.
-func NewCS3LS(c gateway.GatewayAPIClient) LockSystem {
+func NewCS3LS(s pool.Selectable[gateway.GatewayAPIClient]) LockSystem {
return &cs3LS{
- client: c,
+ selector: s,
}
}
type cs3LS struct {
- client gateway.GatewayAPIClient
+ selector pool.Selectable[gateway.GatewayAPIClient]
}
func (cls *cs3LS) Confirm(ctx context.Context, now time.Time, name0, name1 string, conditions ...Condition) (func(), error) {
@@ -205,7 +206,13 @@ func (cls *cs3LS) Create(ctx context.Context, now time.Time, details LockDetails
Nanos: uint32(expiration.Nanosecond()),
}
}
- res, err := cls.client.SetLock(ctx, r)
+
+ client, err := cls.selector.Next()
+ if err != nil {
+ return "", err
+ }
+
+ res, err := client.SetLock(ctx, r)
if err != nil {
return "", err
}
@@ -233,10 +240,17 @@ func (cls *cs3LS) Unlock(ctx context.Context, now time.Time, ref *provider.Refer
User: u.Id,
},
}
- res, err := cls.client.Unlock(ctx, r)
+
+ client, err := cls.selector.Next()
if err != nil {
return err
}
+
+ res, err := client.Unlock(ctx, r)
+ if err != nil {
+ return err
+ }
+
switch res.Status.Code {
case rpc.Code_CODE_OK:
return nil
@@ -388,7 +402,7 @@ func (s *svc) handleLock(w http.ResponseWriter, r *http.Request, ns string) (ret
fn := path.Join(ns, r.URL.Path) // TODO do we still need to jail if we query the registry about the spaces?
// TODO instead of using a string namespace ns pass in the space with the request?
- ref, cs3Status, err := spacelookup.LookupReferenceForPath(ctx, s.gwClient, fn)
+ ref, cs3Status, err := spacelookup.LookupReferenceForPath(ctx, s.gatewaySelector, fn)
if err != nil {
return http.StatusInternalServerError, err
}
@@ -566,7 +580,7 @@ func (s *svc) handleUnlock(w http.ResponseWriter, r *http.Request, ns string) (s
fn := path.Join(ns, r.URL.Path) // TODO do we still need to jail if we query the registry about the spaces?
// TODO instead of using a string namespace ns pass in the space with the request?
- ref, cs3Status, err := spacelookup.LookupReferenceForPath(ctx, s.gwClient, fn)
+ ref, cs3Status, err := spacelookup.LookupReferenceForPath(ctx, s.gatewaySelector, fn)
if err != nil {
return http.StatusInternalServerError, err
}
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/meta.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/meta.go
index 69d7da344..169f9fd3f 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/meta.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/meta.go
@@ -119,9 +119,14 @@ func (h *MetaHandler) handlePathForUser(w http.ResponseWriter, r *http.Request,
w.WriteHeader(http.StatusBadRequest)
return
}
-
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ sublog.Error().Err(err).Msg("error selecting next client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
pathReq := &provider.GetPathRequest{ResourceId: rid}
- pathRes, err := s.gwClient.GetPath(ctx, pathReq)
+ pathRes, err := client.GetPath(ctx, pathReq)
if err != nil {
sublog.Error().Err(err).Msg("could not send GetPath grpc request: transport error")
w.WriteHeader(http.StatusInternalServerError)
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/mkcol.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/mkcol.go
index 0636052b0..9b445a143 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/mkcol.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/mkcol.go
@@ -45,9 +45,14 @@ func (s *svc) handlePathMkcol(w http.ResponseWriter, r *http.Request, ns string)
}
sublog := appctx.GetLogger(ctx).With().Str("path", fn).Logger()
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ return http.StatusInternalServerError, errtypes.InternalError(err.Error())
+ }
+
// stat requested path to make sure it isn't existing yet
// NOTE: It could be on another storage provider than the 'parent' of it
- sr, err := s.gwClient.Stat(ctx, &provider.StatRequest{
+ sr, err := client.Stat(ctx, &provider.StatRequest{
Ref: &provider.Reference{
Path: fn,
},
@@ -67,7 +72,7 @@ func (s *svc) handlePathMkcol(w http.ResponseWriter, r *http.Request, ns string)
parentPath := path.Dir(fn)
- space, rpcStatus, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gwClient, parentPath)
+ space, rpcStatus, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gatewaySelector, parentPath)
switch {
case err != nil:
return http.StatusInternalServerError, err
@@ -108,8 +113,12 @@ func (s *svc) handleMkcol(ctx context.Context, w http.ResponseWriter, r *http.Re
return http.StatusUnsupportedMediaType, fmt.Errorf("extended-mkcol not supported")
}
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ return http.StatusInternalServerError, errtypes.InternalError(err.Error())
+ }
req := &provider.CreateContainerRequest{Ref: childRef}
- res, err := s.gwClient.CreateContainer(ctx, req)
+ res, err := client.CreateContainer(ctx, req)
switch {
case err != nil:
return http.StatusInternalServerError, err
@@ -123,7 +132,7 @@ func (s *svc) handleMkcol(ctx context.Context, w http.ResponseWriter, r *http.Re
return http.StatusNotFound, errors.New("Resource not found")
case res.Status.Code == rpc.Code_CODE_PERMISSION_DENIED:
// check if user has access to parent
- sRes, err := s.gwClient.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{
+ sRes, err := client.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{
ResourceId: childRef.GetResourceId(),
Path: utils.MakeRelativePath(path.Dir(childRef.Path)),
}})
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/move.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/move.go
index 793eaa9d8..10ccb32ac 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/move.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/move.go
@@ -78,7 +78,7 @@ func (s *svc) handlePathMove(w http.ResponseWriter, r *http.Request, ns string)
sublog := appctx.GetLogger(ctx).With().Str("src", srcPath).Str("dst", dstPath).Logger()
- srcSpace, status, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gwClient, srcPath)
+ srcSpace, status, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gatewaySelector, srcPath)
if err != nil {
sublog.Error().Err(err).Str("path", srcPath).Msg("failed to look up source storage space")
w.WriteHeader(http.StatusInternalServerError)
@@ -88,7 +88,7 @@ func (s *svc) handlePathMove(w http.ResponseWriter, r *http.Request, ns string)
errors.HandleErrorStatus(&sublog, w, status)
return
}
- dstSpace, status, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gwClient, dstPath)
+ dstSpace, status, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gatewaySelector, dstPath)
if err != nil {
sublog.Error().Err(err).Str("path", dstPath).Msg("failed to look up destination storage space")
w.WriteHeader(http.StatusInternalServerError)
@@ -141,7 +141,7 @@ func (s *svc) handleSpacesMove(w http.ResponseWriter, r *http.Request, srcSpaceI
}
func (s *svc) handleMove(ctx context.Context, w http.ResponseWriter, r *http.Request, src, dst *provider.Reference, log zerolog.Logger) {
- isChild, err := s.referenceIsChildOf(ctx, s.gwClient, dst, src)
+ isChild, err := s.referenceIsChildOf(ctx, s.gatewaySelector, dst, src)
if err != nil {
switch err.(type) {
case errtypes.IsNotSupported:
@@ -169,9 +169,16 @@ func (s *svc) handleMove(ctx context.Context, w http.ResponseWriter, r *http.Req
return
}
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ log.Error().Err(err).Msg("error selecting next client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+
// check src exists
srcStatReq := &provider.StatRequest{Ref: src}
- srcStatRes, err := s.gwClient.Stat(ctx, srcStatReq)
+ srcStatRes, err := client.Stat(ctx, srcStatReq)
if err != nil {
log.Error().Err(err).Msg("error sending grpc stat request")
w.WriteHeader(http.StatusInternalServerError)
@@ -190,7 +197,7 @@ func (s *svc) handleMove(ctx context.Context, w http.ResponseWriter, r *http.Req
// check dst exists
dstStatReq := &provider.StatRequest{Ref: dst}
- dstStatRes, err := s.gwClient.Stat(ctx, dstStatReq)
+ dstStatRes, err := client.Stat(ctx, dstStatReq)
if err != nil {
log.Error().Err(err).Msg("error sending grpc stat request")
w.WriteHeader(http.StatusInternalServerError)
@@ -213,7 +220,7 @@ func (s *svc) handleMove(ctx context.Context, w http.ResponseWriter, r *http.Req
// delete existing tree
delReq := &provider.DeleteRequest{Ref: dst}
- delRes, err := s.gwClient.Delete(ctx, delReq)
+ delRes, err := client.Delete(ctx, delReq)
if err != nil {
log.Error().Err(err).Msg("error sending grpc delete request")
w.WriteHeader(http.StatusInternalServerError)
@@ -230,7 +237,7 @@ func (s *svc) handleMove(ctx context.Context, w http.ResponseWriter, r *http.Req
ResourceId: dst.ResourceId,
Path: utils.MakeRelativePath(path.Dir(dst.Path)),
}}
- intStatRes, err := s.gwClient.Stat(ctx, intStatReq)
+ intStatRes, err := client.Stat(ctx, intStatReq)
if err != nil {
log.Error().Err(err).Msg("error sending grpc stat request")
w.WriteHeader(http.StatusInternalServerError)
@@ -250,7 +257,7 @@ func (s *svc) handleMove(ctx context.Context, w http.ResponseWriter, r *http.Req
}
mReq := &provider.MoveRequest{Source: src, Destination: dst}
- mRes, err := s.gwClient.Move(ctx, mReq)
+ mRes, err := client.Move(ctx, mReq)
if err != nil {
log.Error().Err(err).Msg("error sending move grpc request")
w.WriteHeader(http.StatusInternalServerError)
@@ -279,7 +286,7 @@ func (s *svc) handleMove(ctx context.Context, w http.ResponseWriter, r *http.Req
return
}
- dstStatRes, err = s.gwClient.Stat(ctx, dstStatReq)
+ dstStatRes, err = client.Stat(ctx, dstStatReq)
if err != nil {
log.Error().Err(err).Msg("error sending grpc stat request")
w.WriteHeader(http.StatusInternalServerError)
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go
index db25c5d7a..e0291a319 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go
@@ -144,7 +144,7 @@ type svc struct {
davHandler *DavHandler
favoritesManager favorite.Manager
client *http.Client
- gwClient gateway.GatewayAPIClient
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
// LockSystem is the lock management system.
LockSystem LockSystem
userIdentifierCache *ttlcache.Cache
@@ -163,11 +163,11 @@ func getFavoritesManager(c *Config) (favorite.Manager, error) {
}
func getLockSystem(c *Config) (LockSystem, error) {
// TODO in memory implementation
- client, err := pool.GetGatewayServiceClient(c.GatewaySvc)
+ selector, err := pool.GatewaySelector(c.GatewaySvc)
if err != nil {
return nil, err
}
- return NewCS3LS(client), nil
+ return NewCS3LS(selector), nil
}
// New returns a new ocdav service
@@ -192,7 +192,7 @@ func New(m map[string]interface{}, log *zerolog.Logger) (global.Service, error)
}
// NewWith returns a new ocdav service
-func NewWith(conf *Config, fm favorite.Manager, ls LockSystem, _ *zerolog.Logger, gwc gateway.GatewayAPIClient) (global.Service, error) {
+func NewWith(conf *Config, fm favorite.Manager, ls LockSystem, _ *zerolog.Logger, selector pool.Selectable[gateway.GatewayAPIClient]) (global.Service, error) {
// be safe - init the conf again
conf.init()
@@ -204,7 +204,7 @@ func NewWith(conf *Config, fm favorite.Manager, ls LockSystem, _ *zerolog.Logger
rhttp.Timeout(time.Duration(conf.Timeout*int64(time.Second))),
rhttp.Insecure(conf.Insecure),
),
- gwClient: gwc,
+ gatewaySelector: selector,
favoritesManager: fm,
LockSystem: ls,
userIdentifierCache: ttlcache.NewCache(),
@@ -219,9 +219,9 @@ func NewWith(conf *Config, fm favorite.Manager, ls LockSystem, _ *zerolog.Logger
if err := s.davHandler.init(conf); err != nil {
return nil, err
}
- if gwc == nil {
+ if selector == nil {
var err error
- s.gwClient, err = pool.GetGatewayServiceClient(s.c.GatewaySvc)
+ s.gatewaySelector, err = pool.GatewaySelector(s.c.GatewaySvc)
if err != nil {
return nil, err
}
@@ -326,7 +326,12 @@ func (s *svc) ApplyLayout(ctx context.Context, ns string, useLoggedInUserNS bool
requestUsernameOrID, requestPath = router.ShiftPath(requestPath)
// Check if this is a Userid
- userRes, err := s.gwClient.GetUser(ctx, &userpb.GetUserRequest{
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ return "", "", err
+ }
+
+ userRes, err := client.GetUser(ctx, &userpb.GetUserRequest{
UserId: &userpb.UserId{OpaqueId: requestUsernameOrID},
})
if err != nil {
@@ -335,7 +340,7 @@ func (s *svc) ApplyLayout(ctx context.Context, ns string, useLoggedInUserNS bool
// If it's not a userid try if it is a user name
if userRes.Status.Code != rpc.Code_CODE_OK {
- res, err := s.gwClient.GetUserByClaim(ctx, &userpb.GetUserByClaimRequest{
+ res, err := client.GetUserByClaim(ctx, &userpb.GetUserByClaimRequest{
Claim: "username",
Value: requestUsernameOrID,
})
@@ -406,7 +411,11 @@ func authContextForUser(client gateway.GatewayAPIClient, userID *userpb.UserId,
return granteeCtx, nil
}
-func (s *svc) sspReferenceIsChildOf(ctx context.Context, client gateway.GatewayAPIClient, child, parent *provider.Reference) (bool, error) {
+func (s *svc) sspReferenceIsChildOf(ctx context.Context, selector pool.Selectable[gateway.GatewayAPIClient], child, parent *provider.Reference) (bool, error) {
+ client, err := selector.Next()
+ if err != nil {
+ return false, err
+ }
parentStatRes, err := client.Stat(ctx, &provider.StatRequest{Ref: parent})
if err != nil {
return false, err
@@ -448,7 +457,7 @@ func (s *svc) sspReferenceIsChildOf(ctx context.Context, client gateway.GatewayA
return strings.HasPrefix(cp, pp), nil
}
-func (s *svc) referenceIsChildOf(ctx context.Context, client gateway.GatewayAPIClient, child, parent *provider.Reference) (bool, error) {
+func (s *svc) referenceIsChildOf(ctx context.Context, selector pool.Selectable[gateway.GatewayAPIClient], child, parent *provider.Reference) (bool, error) {
if child.ResourceId.SpaceId != parent.ResourceId.SpaceId {
return false, nil // Not on the same storage -> not a child
}
@@ -459,7 +468,12 @@ func (s *svc) referenceIsChildOf(ctx context.Context, client gateway.GatewayAPIC
if child.ResourceId.SpaceId == utils.ShareStorageSpaceID || parent.ResourceId.SpaceId == utils.ShareStorageSpaceID {
// the sharesstorageprovider needs some special handling
- return s.sspReferenceIsChildOf(ctx, client, child, parent)
+ return s.sspReferenceIsChildOf(ctx, selector, child, parent)
+ }
+
+ client, err := selector.Next()
+ if err != nil {
+ return false, err
}
// the references are on the same storage but relative to different resources
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/propfind/propfind.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/propfind/propfind.go
index ad4c671a2..6e0de1022 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/propfind/propfind.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/propfind/propfind.go
@@ -47,6 +47,7 @@ import (
ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/publicshare"
rstatus "github.com/cs3org/reva/v2/pkg/rgrpc/status"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/rhttp/router"
"github.com/cs3org/reva/v2/pkg/storagespace"
"github.com/cs3org/reva/v2/pkg/utils"
@@ -163,20 +164,17 @@ func NewMultiStatusResponseXML() *MultiStatusResponseXML {
}
}
-// GetGatewayServiceClientFunc is a callback used to pass in a StorageProviderClient during testing
-type GetGatewayServiceClientFunc func() (gateway.GatewayAPIClient, error)
-
// Handler handles propfind requests
type Handler struct {
PublicURL string
- getClient GetGatewayServiceClientFunc
+ selector pool.Selectable[gateway.GatewayAPIClient]
}
// NewHandler returns a new PropfindHandler instance
-func NewHandler(publicURL string, getClientFunc GetGatewayServiceClientFunc) *Handler {
+func NewHandler(publicURL string, selector pool.Selectable[gateway.GatewayAPIClient]) *Handler {
return &Handler{
PublicURL: publicURL,
- getClient: getClientFunc,
+ selector: selector,
}
}
@@ -197,7 +195,7 @@ func (p *Handler) HandlePathPropfind(w http.ResponseWriter, r *http.Request, ns
}
// retrieve a specific storage space
- client, err := p.getClient()
+ client, err := p.selector.Next()
if err != nil {
sublog.Error().Err(err).Msg("error retrieving a gateway service client")
w.WriteHeader(http.StatusInternalServerError)
@@ -263,7 +261,7 @@ func (p *Handler) HandleSpacesPropfind(w http.ResponseWriter, r *http.Request, s
return
}
- client, err := p.getClient()
+ client, err := p.selector.Next()
if err != nil {
sublog.Error().Err(err).Msg("error getting grpc client")
w.WriteHeader(http.StatusInternalServerError)
@@ -386,7 +384,7 @@ func (p *Handler) propfindResponse(ctx context.Context, w http.ResponseWriter, r
// same as user / group shares for share indicators
filters = append(filters, publicshare.ResourceIDFilter(resourceInfos[i].Id))
}
- client, err := p.getClient()
+ client, err := p.selector.Next()
if err != nil {
log.Error().Err(err).Msg("error getting grpc client")
w.WriteHeader(http.StatusInternalServerError)
@@ -465,7 +463,7 @@ func (p *Handler) getResourceInfos(ctx context.Context, w http.ResponseWriter, r
}
span.SetAttributes(attribute.KeyValue{Key: "depth", Value: attribute.StringValue(depth.String())})
- client, err := p.getClient()
+ client, err := p.selector.Next()
if err != nil {
log.Error().Err(err).Msg("error getting grpc client")
w.WriteHeader(http.StatusInternalServerError)
@@ -675,7 +673,7 @@ func (p *Handler) getSpaceResourceInfos(ctx context.Context, w http.ResponseWrit
span.SetAttributes(attribute.KeyValue{Key: "depth", Value: attribute.StringValue(depth.String())})
defer span.End()
- client, err := p.getClient()
+ client, err := p.selector.Next()
if err != nil {
log.Error().Err(err).Msg("error getting grpc client")
w.WriteHeader(http.StatusInternalServerError)
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/proppatch.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/proppatch.go
index 9358e6b8c..492348d40 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/proppatch.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/proppatch.go
@@ -55,7 +55,7 @@ func (s *svc) handlePathProppatch(w http.ResponseWriter, r *http.Request, ns str
return status, err
}
- space, rpcStatus, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gwClient, fn)
+ space, rpcStatus, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gatewaySelector, fn)
switch {
case err != nil:
return http.StatusInternalServerError, err
@@ -64,9 +64,14 @@ func (s *svc) handlePathProppatch(w http.ResponseWriter, r *http.Request, ns str
case rpcStatus.Code != rpc.Code_CODE_OK:
return rstatus.HTTPStatusFromCode(rpcStatus.Code), errtypes.NewErrtypeFromStatus(rpcStatus)
}
+
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ return http.StatusInternalServerError, errtypes.InternalError(err.Error())
+ }
// check if resource exists
statReq := &provider.StatRequest{Ref: spacelookup.MakeRelativeReference(space, fn, false)}
- statRes, err := s.gwClient.Stat(ctx, statReq)
+ statRes, err := client.Stat(ctx, statReq)
switch {
case err != nil:
return http.StatusInternalServerError, err
@@ -137,6 +142,12 @@ func (s *svc) handleProppatch(ctx context.Context, w http.ResponseWriter, r *htt
acceptedProps := []xml.Name{}
removedProps := []xml.Name{}
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ log.Error().Err(err).Msg("error selecting next gateway client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return nil, nil, false
+ }
for i := range patches {
if len(patches[i].Props) < 1 {
continue
@@ -161,7 +172,7 @@ func (s *svc) handleProppatch(ctx context.Context, w http.ResponseWriter, r *htt
// FIXME: batch this somehow
if remove {
rreq.ArbitraryMetadataKeys[0] = key
- res, err := s.gwClient.UnsetArbitraryMetadata(ctx, rreq)
+ res, err := client.UnsetArbitraryMetadata(ctx, rreq)
if err != nil {
log.Error().Err(err).Msg("error sending a grpc UnsetArbitraryMetadata request")
w.WriteHeader(http.StatusInternalServerError)
@@ -178,7 +189,7 @@ func (s *svc) handleProppatch(ctx context.Context, w http.ResponseWriter, r *htt
m := res.Status.Message
if res.Status.Code == rpc.Code_CODE_PERMISSION_DENIED {
// check if user has access to resource
- sRes, err := s.gwClient.Stat(ctx, &provider.StatRequest{Ref: ref})
+ sRes, err := client.Stat(ctx, &provider.StatRequest{Ref: ref})
if err != nil {
log.Error().Err(err).Msg("error performing stat grpc request")
w.WriteHeader(http.StatusInternalServerError)
@@ -200,7 +211,7 @@ func (s *svc) handleProppatch(ctx context.Context, w http.ResponseWriter, r *htt
return nil, nil, false
}
if key == "http://owncloud.org/ns/favorite" {
- statRes, err := s.gwClient.Stat(ctx, &provider.StatRequest{Ref: ref})
+ statRes, err := client.Stat(ctx, &provider.StatRequest{Ref: ref})
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return nil, nil, false
@@ -215,7 +226,7 @@ func (s *svc) handleProppatch(ctx context.Context, w http.ResponseWriter, r *htt
removedProps = append(removedProps, propNameXML)
} else {
sreq.ArbitraryMetadata.Metadata[key] = value
- res, err := s.gwClient.SetArbitraryMetadata(ctx, sreq)
+ res, err := client.SetArbitraryMetadata(ctx, sreq)
if err != nil {
log.Error().Err(err).Str("key", key).Str("value", value).Msg("error sending a grpc SetArbitraryMetadata request")
w.WriteHeader(http.StatusInternalServerError)
@@ -232,7 +243,7 @@ func (s *svc) handleProppatch(ctx context.Context, w http.ResponseWriter, r *htt
m := res.Status.Message
if res.Status.Code == rpc.Code_CODE_PERMISSION_DENIED {
// check if user has access to resource
- sRes, err := s.gwClient.Stat(ctx, &provider.StatRequest{Ref: ref})
+ sRes, err := client.Stat(ctx, &provider.StatRequest{Ref: ref})
if err != nil {
log.Error().Err(err).Msg("error performing stat grpc request")
w.WriteHeader(http.StatusInternalServerError)
@@ -258,7 +269,7 @@ func (s *svc) handleProppatch(ctx context.Context, w http.ResponseWriter, r *htt
delete(sreq.ArbitraryMetadata.Metadata, key)
if key == "http://owncloud.org/ns/favorite" {
- statRes, err := s.gwClient.Stat(ctx, &provider.StatRequest{Ref: ref})
+ statRes, err := client.Stat(ctx, &provider.StatRequest{Ref: ref})
if err != nil || statRes.Info == nil {
w.WriteHeader(http.StatusInternalServerError)
return nil, nil, false
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/put.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/put.go
index f90b0d7b3..c76aafeb6 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/put.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/put.go
@@ -114,7 +114,7 @@ func (s *svc) handlePathPut(w http.ResponseWriter, r *http.Request, ns string) {
fn := path.Join(ns, r.URL.Path)
sublog := appctx.GetLogger(ctx).With().Str("path", fn).Logger()
- space, status, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gwClient, fn)
+ space, status, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gatewaySelector, fn)
if err != nil {
sublog.Error().Err(err).Str("path", fn).Msg("failed to look up storage space")
w.WriteHeader(http.StatusInternalServerError)
@@ -148,8 +148,14 @@ func (s *svc) handlePut(ctx context.Context, w http.ResponseWriter, r *http.Requ
return
}
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ log.Error().Err(err).Msg("error selecting next gateway client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
if length == 0 {
- tfRes, err := s.gwClient.TouchFile(ctx, &provider.TouchFileRequest{
+ tfRes, err := client.TouchFile(ctx, &provider.TouchFileRequest{
Ref: ref,
})
if err != nil {
@@ -162,7 +168,7 @@ func (s *svc) handlePut(ctx context.Context, w http.ResponseWriter, r *http.Requ
w.WriteHeader(http.StatusInternalServerError)
return
}
- sRes, err := s.gwClient.Stat(ctx, &provider.StatRequest{
+ sRes, err := client.Stat(ctx, &provider.StatRequest{
Ref: ref,
})
if err != nil {
@@ -241,7 +247,7 @@ func (s *svc) handlePut(ctx context.Context, w http.ResponseWriter, r *http.Requ
}
// where to upload the file?
- uRes, err := s.gwClient.InitiateFileUpload(ctx, uReq)
+ uRes, err := client.InitiateFileUpload(ctx, uReq)
if err != nil {
log.Error().Err(err).Msg("error initiating file upload")
w.WriteHeader(http.StatusInternalServerError)
@@ -258,7 +264,7 @@ func (s *svc) handlePut(ctx context.Context, w http.ResponseWriter, r *http.Requ
status := http.StatusForbidden
m := uRes.Status.Message
// check if user has access to parent
- sRes, err := s.gwClient.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{
+ sRes, err := client.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{
ResourceId: ref.ResourceId,
Path: utils.MakeRelativePath(path.Dir(ref.Path)),
}})
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/report.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/report.go
index 3cea9b1f7..02f688676 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/report.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/report.go
@@ -81,9 +81,15 @@ func (s *svc) doFilterFiles(w http.ResponseWriter, r *http.Request, ff *reportFi
return
}
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ log.Error().Err(err).Msg("error selecting next gateway client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
infos := make([]*provider.ResourceInfo, 0, len(favorites))
for i := range favorites {
- statRes, err := s.gwClient.Stat(ctx, &providerv1beta1.StatRequest{Ref: &providerv1beta1.Reference{ResourceId: favorites[i]}})
+ statRes, err := client.Stat(ctx, &providerv1beta1.StatRequest{Ref: &providerv1beta1.Reference{ResourceId: favorites[i]}})
if err != nil {
log.Error().Err(err).Msg("error getting resource info")
continue
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/spacelookup/spacelookup.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/spacelookup/spacelookup.go
index b9f68ed22..db6b0cc2a 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/spacelookup/spacelookup.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/spacelookup/spacelookup.go
@@ -29,6 +29,7 @@ import (
storageProvider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
typesv1beta1 "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/storagespace"
"github.com/cs3org/reva/v2/pkg/utils"
"google.golang.org/protobuf/types/known/fieldmaskpb"
@@ -37,8 +38,8 @@ import (
// LookupReferenceForPath returns:
// a reference with root and relative path
// the status and error for the lookup
-func LookupReferenceForPath(ctx context.Context, client gateway.GatewayAPIClient, path string) (*storageProvider.Reference, *rpc.Status, error) {
- space, cs3Status, err := LookUpStorageSpaceForPath(ctx, client, path)
+func LookupReferenceForPath(ctx context.Context, selector pool.Selectable[gateway.GatewayAPIClient], path string) (*storageProvider.Reference, *rpc.Status, error) {
+ space, cs3Status, err := LookUpStorageSpaceForPath(ctx, selector, path)
if err != nil || cs3Status.Code != rpc.Code_CODE_OK {
return nil, cs3Status, err
}
@@ -52,7 +53,7 @@ func LookupReferenceForPath(ctx context.Context, client gateway.GatewayAPIClient
// LookUpStorageSpaceForPath returns:
// the storage spaces responsible for a path
// the status and error for the lookup
-func LookUpStorageSpaceForPath(ctx context.Context, client gateway.GatewayAPIClient, path string) (*storageProvider.StorageSpace, *rpc.Status, error) {
+func LookUpStorageSpaceForPath(ctx context.Context, selector pool.Selectable[gateway.GatewayAPIClient], path string) (*storageProvider.StorageSpace, *rpc.Status, error) {
// TODO add filter to only fetch spaces changed in the last 30 sec?
// TODO cache space information, invalidate after ... 5min? so we do not need to fetch all spaces?
// TODO use ListContainerStream to listen for changes
@@ -72,6 +73,11 @@ func LookUpStorageSpaceForPath(ctx context.Context, client gateway.GatewayAPICli
},
}
+ client, err := selector.Next()
+ if err != nil {
+ return nil, status.NewInternal(ctx, "could not select next client"), err
+ }
+
lSSRes, err := client.ListStorageSpaces(ctx, lSSReq)
if err != nil || lSSRes.Status.Code != rpc.Code_CODE_OK {
status := status.NewStatusFromErrType(ctx, "failed to lookup storage spaces", err)
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/spaces.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/spaces.go
index 40c227287..b915ce63b 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/spaces.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/spaces.go
@@ -22,7 +22,6 @@ import (
"net/http"
"path"
- gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/errors"
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/net"
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/propfind"
@@ -79,9 +78,7 @@ func (h *SpacesHandler) Handler(s *svc, trashbinHandler *TrashbinHandler) http.H
var err error
switch r.Method {
case MethodPropfind:
- p := propfind.NewHandler(config.PublicURL, func() (gateway.GatewayAPIClient, error) {
- return s.gwClient, nil
- })
+ p := propfind.NewHandler(config.PublicURL, s.gatewaySelector)
p.HandleSpacesPropfind(w, r, spaceID)
case MethodProppatch:
status, err = s.handleSpacesProppatch(w, r, spaceID)
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/tpc.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/tpc.go
index 1b138c1a8..0c18979f8 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/tpc.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/tpc.go
@@ -37,6 +37,7 @@ import (
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/net"
"github.com/cs3org/reva/v2/pkg/appctx"
"github.com/cs3org/reva/v2/pkg/errtypes"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/rhttp"
)
@@ -134,10 +135,16 @@ func (s *svc) handleTPCPull(ctx context.Context, w http.ResponseWriter, r *http.
}
sublog.Debug().Bool("overwrite", overwrite).Msg("TPC Pull")
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ sublog.Error().Err(err).Msg("error selecting next gateway client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
// check if destination exists
ref := &provider.Reference{Path: dst}
dstStatReq := &provider.StatRequest{Ref: ref}
- dstStatRes, err := s.gwClient.Stat(ctx, dstStatReq)
+ dstStatRes, err := client.Stat(ctx, dstStatReq)
if err != nil {
sublog.Error().Err(err).Msg("error sending grpc stat request")
w.WriteHeader(http.StatusInternalServerError)
@@ -153,7 +160,7 @@ func (s *svc) handleTPCPull(ctx context.Context, w http.ResponseWriter, r *http.
return
}
- err = s.performHTTPPull(ctx, s.gwClient, r, w, ns)
+ err = s.performHTTPPull(ctx, s.gatewaySelector, r, w, ns)
if err != nil {
sublog.Error().Err(err).Msg("error performing TPC Pull")
return
@@ -161,7 +168,7 @@ func (s *svc) handleTPCPull(ctx context.Context, w http.ResponseWriter, r *http.
fmt.Fprintf(w, "success: Created")
}
-func (s *svc) performHTTPPull(ctx context.Context, client gateway.GatewayAPIClient, r *http.Request, w http.ResponseWriter, ns string) error {
+func (s *svc) performHTTPPull(ctx context.Context, selector pool.Selectable[gateway.GatewayAPIClient], r *http.Request, w http.ResponseWriter, ns string) error {
src := r.Header.Get("Source")
dst := path.Join(ns, r.URL.Path)
sublog := appctx.GetLogger(ctx)
@@ -197,6 +204,12 @@ func (s *svc) performHTTPPull(ctx context.Context, client gateway.GatewayAPIClie
return errtypes.InternalError(fmt.Sprintf("Remote GET returned status code %d", httpDownloadRes.StatusCode))
}
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ sublog.Error().Err(err).Msg("error selecting next gateway client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return errtypes.InternalError(err.Error())
+ }
// get upload url
uReq := &provider.InitiateFileUploadRequest{
Ref: &provider.Reference{Path: dst},
@@ -287,9 +300,15 @@ func (s *svc) handleTPCPush(ctx context.Context, w http.ResponseWriter, r *http.
sublog.Debug().Bool("overwrite", overwrite).Msg("TPC Push")
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ sublog.Error().Err(err).Msg("error selecting next gateway client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
ref := &provider.Reference{Path: src}
srcStatReq := &provider.StatRequest{Ref: ref}
- srcStatRes, err := s.gwClient.Stat(ctx, srcStatReq)
+ srcStatRes, err := client.Stat(ctx, srcStatReq)
if err != nil {
sublog.Error().Err(err).Msg("error sending grpc stat request")
w.WriteHeader(http.StatusInternalServerError)
@@ -305,7 +324,7 @@ func (s *svc) handleTPCPush(ctx context.Context, w http.ResponseWriter, r *http.
return
}
- err = s.performHTTPPush(ctx, s.gwClient, r, w, srcStatRes.Info, ns)
+ err = s.performHTTPPush(ctx, r, w, srcStatRes.Info, ns)
if err != nil {
sublog.Error().Err(err).Msg("error performing TPC Push")
return
@@ -313,7 +332,7 @@ func (s *svc) handleTPCPush(ctx context.Context, w http.ResponseWriter, r *http.
fmt.Fprintf(w, "success: Created")
}
-func (s *svc) performHTTPPush(ctx context.Context, client gateway.GatewayAPIClient, r *http.Request, w http.ResponseWriter, srcInfo *provider.ResourceInfo, ns string) error {
+func (s *svc) performHTTPPush(ctx context.Context, r *http.Request, w http.ResponseWriter, srcInfo *provider.ResourceInfo, ns string) error {
src := path.Join(ns, r.URL.Path)
dst := r.Header.Get("Destination")
@@ -325,6 +344,12 @@ func (s *svc) performHTTPPush(ctx context.Context, client gateway.GatewayAPIClie
Ref: &provider.Reference{Path: src},
}
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ sublog.Error().Err(err).Msg("error selecting next gateway client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return err
+ }
dRes, err := client.InitiateFileDownload(ctx, dReq)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/trashbin.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/trashbin.go
index 3944546a0..78de68e4a 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/trashbin.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/trashbin.go
@@ -111,7 +111,7 @@ func (h *TrashbinHandler) Handler(s *svc) http.Handler {
r.URL.Path = newPath
basePath := path.Join(ns, newPath)
- space, rpcstatus, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gwClient, basePath)
+ space, rpcstatus, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gatewaySelector, basePath)
switch {
case err != nil:
log.Error().Err(err).Str("path", basePath).Msg("failed to look up storage space")
@@ -151,7 +151,7 @@ func (h *TrashbinHandler) Handler(s *svc) http.Handler {
p := path.Join(ns, dst)
// The destination can be in another space. E.g. the 'Shares Jail'.
- space, rpcstatus, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gwClient, p)
+ space, rpcstatus, err := spacelookup.LookUpStorageSpaceForPath(ctx, s.gatewaySelector, p)
if err != nil {
log.Error().Err(err).Str("path", p).Msg("failed to look up destination storage space")
w.WriteHeader(http.StatusInternalServerError)
@@ -216,8 +216,14 @@ func (h *TrashbinHandler) listTrashbin(w http.ResponseWriter, r *http.Request, s
return
}
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ sublog.Error().Err(err).Msg("error selecting next gateway client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
// ask gateway for recycle items
- getRecycleRes, err := s.gwClient.ListRecycle(ctx, &provider.ListRecycleRequest{Ref: ref, Key: path.Join(key, itemPath)})
+ getRecycleRes, err := client.ListRecycle(ctx, &provider.ListRecycleRequest{Ref: ref, Key: path.Join(key, itemPath)})
if err != nil {
sublog.Error().Err(err).Msg("error calling ListRecycle")
w.WriteHeader(http.StatusInternalServerError)
@@ -247,7 +253,7 @@ func (h *TrashbinHandler) listTrashbin(w http.ResponseWriter, r *http.Request, s
for len(stack) > 0 {
key := stack[len(stack)-1]
- getRecycleRes, err := s.gwClient.ListRecycle(ctx, &provider.ListRecycleRequest{Ref: ref, Key: key})
+ getRecycleRes, err := client.ListRecycle(ctx, &provider.ListRecycleRequest{Ref: ref, Key: key})
if err != nil {
sublog.Error().Err(err).Msg("error calling ListRecycle")
w.WriteHeader(http.StatusInternalServerError)
@@ -465,8 +471,14 @@ func (h *TrashbinHandler) restore(w http.ResponseWriter, r *http.Request, s *svc
return
}
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ sublog.Error().Err(err).Msg("error selecting next gateway client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
dstStatReq := &provider.StatRequest{Ref: dst}
- dstStatRes, err := s.gwClient.Stat(ctx, dstStatReq)
+ dstStatRes, err := client.Stat(ctx, dstStatReq)
if err != nil {
sublog.Error().Err(err).Msg("error sending grpc stat request")
w.WriteHeader(http.StatusInternalServerError)
@@ -484,7 +496,7 @@ func (h *TrashbinHandler) restore(w http.ResponseWriter, r *http.Request, s *svc
parentRef := &provider.Reference{ResourceId: dst.ResourceId, Path: utils.MakeRelativePath(path.Dir(dst.Path))}
parentStatReq := &provider.StatRequest{Ref: parentRef}
- parentStatResponse, err := s.gwClient.Stat(ctx, parentStatReq)
+ parentStatResponse, err := client.Stat(ctx, parentStatReq)
if err != nil {
sublog.Error().Err(err).Msg("error sending grpc stat request")
w.WriteHeader(http.StatusInternalServerError)
@@ -515,7 +527,7 @@ func (h *TrashbinHandler) restore(w http.ResponseWriter, r *http.Request, s *svc
}
// delete existing tree
delReq := &provider.DeleteRequest{Ref: dst}
- delRes, err := s.gwClient.Delete(ctx, delReq)
+ delRes, err := client.Delete(ctx, delReq)
if err != nil {
sublog.Error().Err(err).Msg("error sending grpc delete request")
w.WriteHeader(http.StatusInternalServerError)
@@ -534,7 +546,7 @@ func (h *TrashbinHandler) restore(w http.ResponseWriter, r *http.Request, s *svc
RestoreRef: dst,
}
- res, err := s.gwClient.RestoreRecycleItem(ctx, req)
+ res, err := client.RestoreRecycleItem(ctx, req)
if err != nil {
sublog.Error().Err(err).Msg("error sending a grpc restore recycle item request")
w.WriteHeader(http.StatusInternalServerError)
@@ -551,7 +563,7 @@ func (h *TrashbinHandler) restore(w http.ResponseWriter, r *http.Request, s *svc
return
}
- dstStatRes, err = s.gwClient.Stat(ctx, dstStatReq)
+ dstStatRes, err = client.Stat(ctx, dstStatReq)
if err != nil {
sublog.Error().Err(err).Msg("error sending grpc stat request")
w.WriteHeader(http.StatusInternalServerError)
@@ -584,7 +596,13 @@ func (h *TrashbinHandler) delete(w http.ResponseWriter, r *http.Request, s *svc,
Key: trashPath,
}
- res, err := s.gwClient.PurgeRecycle(ctx, req)
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ sublog.Error().Err(err).Msg("error selecting next gateway client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ res, err := client.PurgeRecycle(ctx, req)
if err != nil {
sublog.Error().Err(err).Msg("error sending a grpc restore recycle item request")
w.WriteHeader(http.StatusInternalServerError)
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/tus.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/tus.go
index 7e9148d06..8a6e6a66c 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/tus.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/tus.go
@@ -114,10 +114,15 @@ func (s *svc) handleTusPost(ctx context.Context, w http.ResponseWriter, r *http.
// TODO check Expect: 100-continue
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
sReq := &provider.StatRequest{
Ref: ref,
}
- sRes, err := s.gwClient.Stat(ctx, sReq)
+ sRes, err := client.Stat(ctx, sReq)
if err != nil {
log.Error().Err(err).Msg("error sending grpc stat request")
w.WriteHeader(http.StatusInternalServerError)
@@ -155,7 +160,7 @@ func (s *svc) handleTusPost(ctx context.Context, w http.ResponseWriter, r *http.
return
}
if uploadLength == 0 {
- tfRes, err := s.gwClient.TouchFile(ctx, &provider.TouchFileRequest{
+ tfRes, err := client.TouchFile(ctx, &provider.TouchFileRequest{
Ref: ref,
})
if err != nil {
@@ -193,7 +198,7 @@ func (s *svc) handleTusPost(ctx context.Context, w http.ResponseWriter, r *http.
},
}
- uRes, err := s.gwClient.InitiateFileUpload(ctx, uReq)
+ uRes, err := client.InitiateFileUpload(ctx, uReq)
if err != nil {
log.Error().Err(err).Msg("error initiating file upload")
w.WriteHeader(http.StatusInternalServerError)
@@ -284,7 +289,7 @@ func (s *svc) handleTusPost(ctx context.Context, w http.ResponseWriter, r *http.
}
}
- sRes, err := s.gwClient.Stat(ctx, sReq)
+ sRes, err := client.Stat(ctx, sReq)
if err != nil {
log.Error().Err(err).Msg("error sending grpc stat request")
w.WriteHeader(http.StatusInternalServerError)
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/versions.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/versions.go
index 36831f0cf..ae249c1a6 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/versions.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/versions.go
@@ -122,8 +122,14 @@ func (h *VersionsHandler) doListVersions(w http.ResponseWriter, r *http.Request,
return
}
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ sublog.Error().Err(err).Msg("error selecting next gateway client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
ref := &provider.Reference{ResourceId: rid}
- res, err := s.gwClient.Stat(ctx, &provider.StatRequest{Ref: ref})
+ res, err := client.Stat(ctx, &provider.StatRequest{Ref: ref})
if err != nil {
sublog.Error().Err(err).Msg("error sending a grpc stat request")
w.WriteHeader(http.StatusInternalServerError)
@@ -142,7 +148,7 @@ func (h *VersionsHandler) doListVersions(w http.ResponseWriter, r *http.Request,
info := res.Info
- lvRes, err := s.gwClient.ListFileVersions(ctx, &provider.ListFileVersionsRequest{Ref: ref})
+ lvRes, err := client.ListFileVersions(ctx, &provider.ListFileVersionsRequest{Ref: ref})
if err != nil {
sublog.Error().Err(err).Msg("error sending list container grpc request")
w.WriteHeader(http.StatusInternalServerError)
@@ -225,7 +231,13 @@ func (h *VersionsHandler) doRestore(w http.ResponseWriter, r *http.Request, s *s
Key: key,
}
- res, err := s.gwClient.RestoreFileVersion(ctx, req)
+ client, err := s.gatewaySelector.Next()
+ if err != nil {
+ sublog.Error().Err(err).Msg("error selecting next gateway client")
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ res, err := client.RestoreFileVersion(ctx, req)
if err != nil {
sublog.Error().Err(err).Msg("error sending a grpc restore version request")
w.WriteHeader(http.StatusInternalServerError)
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/webdav.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/webdav.go
index 6a169edb6..e471bfdf4 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/webdav.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/webdav.go
@@ -23,7 +23,6 @@ import (
"net/http"
"path"
- gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/errors"
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/propfind"
"github.com/cs3org/reva/v2/pkg/appctx"
@@ -73,9 +72,7 @@ func (h *WebDavHandler) Handler(s *svc) http.Handler {
var status int // status 0 means the handler already sent the response
switch r.Method {
case MethodPropfind:
- p := propfind.NewHandler(config.PublicURL, func() (gateway.GatewayAPIClient, error) {
- return s.gwClient, nil
- })
+ p := propfind.NewHandler(config.PublicURL, s.gatewaySelector)
p.HandlePathPropfind(w, r, ns)
case MethodLock:
status, err = s.handleLock(w, r, ns)
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/conversions/main.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/conversions/main.go
index 307ed0f39..c475b2be1 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/conversions/main.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/conversions/main.go
@@ -345,7 +345,7 @@ func ParseTimestamp(timestampString string) (*types.Timestamp, error) {
parsedTime, err = time.Parse("2006-01-02", timestampString)
if err == nil {
// the link needs to be valid for the whole day
- parsedTime.Add(23*time.Hour + 59*time.Minute + 59*time.Second)
+ parsedTime = parsedTime.Add(23*time.Hour + 59*time.Minute + 59*time.Second)
}
}
if err != nil {
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/eosclient/eosgrpc/eoshttp.go b/vendor/github.com/cs3org/reva/v2/pkg/eosclient/eosgrpc/eoshttp.go
index 591f4ae00..bf7872a14 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/eosclient/eosgrpc/eoshttp.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/eosclient/eosgrpc/eoshttp.go
@@ -379,6 +379,9 @@ func (c *EOSHTTPClient) PUTFile(ctx context.Context, remoteuser string, auth eos
// Execute the request. I don't like that there is no explicit timeout or buffer control on the input stream
log.Debug().Str("func", "PUTFile").Msg("sending req")
resp, err := c.cl.Do(req)
+ if resp != nil {
+ resp.Body.Close()
+ }
// Let's support redirections... and if we retry we retry at the same FST
if resp != nil && resp.StatusCode == 307 {
@@ -471,6 +474,9 @@ func (c *EOSHTTPClient) Head(ctx context.Context, remoteuser string, auth eoscli
}
// Execute the request. I don't like that there is no explicit timeout or buffer control on the input stream
resp, err := c.cl.Do(req)
+ if resp != nil {
+ resp.Body.Close()
+ }
// And get an error code (if error) that is worth propagating
e := c.getRespError(resp, err)
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/micro/ocdav/option.go b/vendor/github.com/cs3org/reva/v2/pkg/micro/ocdav/option.go
index 762cbb8e9..5ff8644ac 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/micro/ocdav/option.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/micro/ocdav/option.go
@@ -24,6 +24,7 @@ import (
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/storage/favorite"
"github.com/rs/zerolog"
"go-micro.dev/v4/broker"
@@ -45,7 +46,7 @@ type Options struct {
JWTSecret string
FavoriteManager favorite.Manager
- GatewayClient gateway.GatewayAPIClient
+ GatewaySelector pool.Selectable[gateway.GatewayAPIClient]
TracingEnabled bool
TracingInsecure bool
@@ -196,10 +197,10 @@ func FavoriteManager(val favorite.Manager) Option {
}
}
-// GatewayClient provides a function to set the GatewayClient option.
-func GatewayClient(val gateway.GatewayAPIClient) Option {
+// GatewaySelector provides a function to set the GatewaySelector option.
+func GatewaySelector(val pool.Selectable[gateway.GatewayAPIClient]) Option {
return func(o *Options) {
- o.GatewayClient = val
+ o.GatewaySelector = val
}
}
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/micro/ocdav/service.go b/vendor/github.com/cs3org/reva/v2/pkg/micro/ocdav/service.go
index 5e384e3a6..a54f5280a 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/micro/ocdav/service.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/micro/ocdav/service.go
@@ -35,6 +35,7 @@ import (
"github.com/go-chi/chi/v5/middleware"
httpServer "github.com/go-micro/plugins/v4/server/http"
"github.com/owncloud/ocis/v2/ocis-pkg/registry"
+ "github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"go-micro.dev/v4"
@@ -68,7 +69,7 @@ func Service(opts ...Option) (micro.Service, error) {
server.Version(sopts.config.VersionString),
)
- revaService, err := ocdav.NewWith(&sopts.config, sopts.FavoriteManager, sopts.lockSystem, &sopts.Logger, sopts.GatewayClient)
+ revaService, err := ocdav.NewWith(&sopts.config, sopts.FavoriteManager, sopts.lockSystem, &sopts.Logger, sopts.GatewaySelector)
if err != nil {
return nil, err
}
@@ -137,11 +138,11 @@ func setDefaults(sopts *Options) error {
sopts.Name = ServerName
}
if sopts.lockSystem == nil {
- client, err := pool.GetGatewayServiceClient(sopts.config.GatewaySvc)
+ selector, err := pool.GatewaySelector(sopts.config.GatewaySvc)
if err != nil {
- return err
+ return errors.Wrap(err, "error getting gateway selector")
}
- sopts.lockSystem = ocdav.NewCS3LS(client)
+ sopts.lockSystem = ocdav.NewCS3LS(selector)
}
if sopts.FavoriteManager == nil {
sopts.FavoriteManager, _ = memory.New(map[string]interface{}{})
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/ocm/share/manager/nextcloud/nextcloud.go b/vendor/github.com/cs3org/reva/v2/pkg/ocm/share/manager/nextcloud/nextcloud.go
index d186b2e02..449387c0e 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/ocm/share/manager/nextcloud/nextcloud.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/ocm/share/manager/nextcloud/nextcloud.go
@@ -58,7 +58,6 @@ func randSeq(n int) string {
}
func init() {
- rand.Seed(time.Now().UnixNano())
registry.Register("nextcloud", New)
}
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/registry/config.go b/vendor/github.com/cs3org/reva/v2/pkg/registry/config.go
deleted file mode 100644
index f798b65b9..000000000
--- a/vendor/github.com/cs3org/reva/v2/pkg/registry/config.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2018-2021 CERN
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// In applying this license, CERN does not waive the privileges and immunities
-// granted to it by virtue of its status as an Intergovernmental Organization
-// or submit itself to any jurisdiction.
-
-package registry
-
-import (
- "github.com/mitchellh/mapstructure"
-)
-
-// Config configures a registry
-type Config struct {
- Services map[string]map[string]*service `mapstructure:"services"`
-}
-
-// service implements the Service interface. Attributes are exported so that mapstructure can unmarshal values onto them.
-type service struct {
- Name string `mapstructure:"name"`
- Nodes []node `mapstructure:"nodes"`
-}
-
-type node struct {
- Address string `mapstructure:"address"`
- Metadata map[string]string `mapstructure:"metadata"`
-}
-
-// ParseConfig translates Config file values into a Config struct for consumers.
-func ParseConfig(m map[string]interface{}) (*Config, error) {
- c := &Config{}
- if err := mapstructure.Decode(m, c); err != nil {
- return nil, err
- }
-
- if len(c.Services) == 0 {
- c.Services = make(map[string]map[string]*service)
- }
-
- return c, nil
-}
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/registry/memory/memory.go b/vendor/github.com/cs3org/reva/v2/pkg/registry/memory/memory.go
deleted file mode 100644
index aee78c9ad..000000000
--- a/vendor/github.com/cs3org/reva/v2/pkg/registry/memory/memory.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2018-2021 CERN
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// In applying this license, CERN does not waive the privileges and immunities
-// granted to it by virtue of its status as an Intergovernmental Organization
-// or submit itself to any jurisdiction.
-
-package memory
-
-import (
- "fmt"
- "sync"
-
- "github.com/cs3org/reva/v2/pkg/registry"
-)
-
-// Registry implements the Registry interface.
-type Registry struct {
- // m protects async access to the services map.
- sync.Mutex
- // services map a service name with a set of nodes.
- services map[string]registry.Service
-}
-
-// Add implements the Registry interface. If the service is already known in this registry it will only update the nodes.
-func (r *Registry) Add(svc registry.Service) error {
- r.Lock()
- defer r.Unlock()
-
- // append the nodes if the service is already registered.
- if _, ok := r.services[svc.Name()]; ok {
- s := service{
- name: svc.Name(),
- nodes: make([]node, 0),
- }
-
- s.mergeNodes(svc.Nodes(), r.services[svc.Name()].Nodes())
-
- r.services[svc.Name()] = s
- return nil
- }
-
- r.services[svc.Name()] = svc
- return nil
-}
-
-// GetService implements the Registry interface. There is currently no load balance being done, but it should not be
-// hard to add.
-func (r *Registry) GetService(name string) (registry.Service, error) {
- r.Lock()
- defer r.Unlock()
-
- if service, ok := r.services[name]; ok {
- return service, nil
- }
-
- return nil, fmt.Errorf("service %v not found", name)
-}
-
-// New returns an implementation of the Registry interface.
-func New(m map[string]interface{}) registry.Registry {
- // c, err := registry.ParseConfig(m)
- // if err != nil {
- // return nil
- // }
-
- return &Registry{
- services: map[string]registry.Service{},
- }
-}
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/registry/memory/node.go b/vendor/github.com/cs3org/reva/v2/pkg/registry/memory/node.go
deleted file mode 100644
index 22042306d..000000000
--- a/vendor/github.com/cs3org/reva/v2/pkg/registry/memory/node.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2018-2021 CERN
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// In applying this license, CERN does not waive the privileges and immunities
-// granted to it by virtue of its status as an Intergovernmental Organization
-// or submit itself to any jurisdiction.
-
-package memory
-
-import "fmt"
-
-// node implements the registry.Node interface.
-type node struct {
- id string
- address string
- metadata map[string]string
-}
-
-func (n node) Address() string {
- return n.address
-}
-
-func (n node) Metadata() map[string]string {
- return n.metadata
-}
-
-func (n node) String() string {
- return fmt.Sprintf("%v-%v", n.id, n.address)
-}
-
-func (n node) ID() string {
- return n.id
-}
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/registry/memory/service.go b/vendor/github.com/cs3org/reva/v2/pkg/registry/memory/service.go
deleted file mode 100644
index d34e92cc3..000000000
--- a/vendor/github.com/cs3org/reva/v2/pkg/registry/memory/service.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2018-2021 CERN
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// In applying this license, CERN does not waive the privileges and immunities
-// granted to it by virtue of its status as an Intergovernmental Organization
-// or submit itself to any jurisdiction.
-
-package memory
-
-import "github.com/cs3org/reva/v2/pkg/registry"
-
-// NewService creates a new memory registry.Service.
-func NewService(name string, nodes []interface{}) registry.Service {
- n := make([]node, 0)
- for i := 0; i < len(nodes); i++ {
- n = append(n, node{
- // explicit type conversions because types are not exported to prevent from circular dependencies until released.
- id: nodes[i].(map[string]interface{})["id"].(string),
- address: nodes[i].(map[string]interface{})["address"].(string),
- //metadata: nodes[i].(map[string]interface{})["metadata"].(map[string]string),
- })
- }
-
- return service{
- name: name,
- nodes: n,
- }
-}
-
-// service implements the Service interface
-type service struct {
- name string
- nodes []node
-}
-
-// Name implements the service interface.
-func (s service) Name() string {
- return s.name
-}
-
-// Nodes implements the service interface.
-func (s service) Nodes() []registry.Node {
- ret := make([]registry.Node, 0)
- for i := range s.nodes {
- ret = append(ret, s.nodes[i])
- }
- return ret
-}
-
-func (s *service) mergeNodes(n1, n2 []registry.Node) {
- n1 = append(n1, n2...)
- for _, n := range n1 {
- s.nodes = append(s.nodes, node{
- id: n.ID(),
- address: n.Address(),
- metadata: n.Metadata(),
- })
- }
-}
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/registry/registry.go b/vendor/github.com/cs3org/reva/v2/pkg/registry/registry.go
index 8b705a093..1595726f0 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/registry/registry.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/registry/registry.go
@@ -1,4 +1,4 @@
-// Copyright 2018-2021 CERN
+// Copyright 2018-2023 CERN
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -18,32 +18,38 @@
package registry
-// Registry provides with means for dynamically registering services.
-type Registry interface {
- // Add registers a Service on the memoryRegistry. Repeated names is allowed, services are distinguished by their metadata.
- Add(Service) error
+import (
+ mRegistry "go-micro.dev/v4/registry"
+ "go-micro.dev/v4/selector"
+)
- // GetService retrieves a Service and all of its nodes by Service name. It returns []*Service because we can have
- // multiple versions of the same Service running alongside each others.
- GetService(string) (Service, error)
+var (
+ // fixme: get rid of global registry
+ gRegistry mRegistry.Registry
+)
+
+// Init prepares the service registry
+func Init(nRegistry mRegistry.Registry) error {
+ // first come first serves, the first service defines the registry type.
+ if gRegistry == nil && nRegistry != nil {
+ gRegistry = nRegistry
+ }
+
+ return nil
}
-// Service defines a service.
-type Service interface {
- Name() string
- Nodes() []Node
+// GetRegistry exposes the registry
+func GetRegistry() mRegistry.Registry {
+ return gRegistry
}
-// Node defines nodes on a service.
-type Node interface {
- // Address where the given node is running.
- Address() string
+// GetNodeAddress returns a random address from the service nodes
+func GetNodeAddress(services []*mRegistry.Service) (string, error) {
+ next := selector.Random(services)
+ node, err := next()
+ if err != nil {
+ return "", err
+ }
- // metadata is used in order to differentiate services implementations. For instance an AuthProvider Service could
- // have multiple implementations, basic, bearer ..., metadata would be used to select the Service type depending on
- // its implementation.
- Metadata() map[string]string
-
- // ID returns the node ID.
- ID() string
+ return node.Address, nil
}
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/client.go b/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/client.go
new file mode 100644
index 000000000..dc22dd417
--- /dev/null
+++ b/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/client.go
@@ -0,0 +1,155 @@
+// Copyright 2018-2021 CERN
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// In applying this license, CERN does not waive the privileges and immunities
+// granted to it by virtue of its status as an Intergovernmental Organization
+// or submit itself to any jurisdiction.
+
+package pool
+
+import (
+ appprovider "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1"
+ appregistry "github.com/cs3org/go-cs3apis/cs3/app/registry/v1beta1"
+ applicationauth "github.com/cs3org/go-cs3apis/cs3/auth/applications/v1beta1"
+ authprovider "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
+ authregistry "github.com/cs3org/go-cs3apis/cs3/auth/registry/v1beta1"
+ gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
+ group "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
+ user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
+ ocmcore "github.com/cs3org/go-cs3apis/cs3/ocm/core/v1beta1"
+ invitepb "github.com/cs3org/go-cs3apis/cs3/ocm/invite/v1beta1"
+ ocmprovider "github.com/cs3org/go-cs3apis/cs3/ocm/provider/v1beta1"
+ permissions "github.com/cs3org/go-cs3apis/cs3/permissions/v1beta1"
+ preferences "github.com/cs3org/go-cs3apis/cs3/preferences/v1beta1"
+ collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
+ link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
+ ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
+ storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
+ storageregistry "github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1"
+ datatx "github.com/cs3org/go-cs3apis/cs3/tx/v1beta1"
+)
+
+// GetGatewayServiceClient returns a GatewayServiceClient.
+func GetGatewayServiceClient(id string, opts ...Option) (gateway.GatewayAPIClient, error) {
+ selector, _ := GatewaySelector(id, opts...)
+ return selector.Next()
+}
+
+// GetUserProviderServiceClient returns a UserProviderServiceClient.
+func GetUserProviderServiceClient(id string, opts ...Option) (user.UserAPIClient, error) {
+ selector, _ := IdentityUserSelector(id, opts...)
+ return selector.Next()
+}
+
+// GetGroupProviderServiceClient returns a GroupProviderServiceClient.
+func GetGroupProviderServiceClient(id string, opts ...Option) (group.GroupAPIClient, error) {
+ selector, _ := IdentityGroupSelector(id, opts...)
+ return selector.Next()
+}
+
+// GetStorageProviderServiceClient returns a StorageProviderServiceClient.
+func GetStorageProviderServiceClient(id string, opts ...Option) (storageprovider.ProviderAPIClient, error) {
+ selector, _ := StorageProviderSelector(id, opts...)
+ return selector.Next()
+}
+
+// GetAuthRegistryServiceClient returns a new AuthRegistryServiceClient.
+func GetAuthRegistryServiceClient(id string, opts ...Option) (authregistry.RegistryAPIClient, error) {
+ selector, _ := AuthRegistrySelector(id, opts...)
+ return selector.Next()
+}
+
+// GetAuthProviderServiceClient returns a new AuthProviderServiceClient.
+func GetAuthProviderServiceClient(id string, opts ...Option) (authprovider.ProviderAPIClient, error) {
+ selector, _ := AuthProviderSelector(id, opts...)
+ return selector.Next()
+}
+
+// GetAppAuthProviderServiceClient returns a new AppAuthProviderServiceClient.
+func GetAppAuthProviderServiceClient(id string, opts ...Option) (applicationauth.ApplicationsAPIClient, error) {
+ selector, _ := AuthApplicationSelector(id, opts...)
+ return selector.Next()
+}
+
+// GetUserShareProviderClient returns a new UserShareProviderClient.
+func GetUserShareProviderClient(id string, opts ...Option) (collaboration.CollaborationAPIClient, error) {
+ selector, _ := SharingCollaborationSelector(id, opts...)
+ return selector.Next()
+}
+
+// GetOCMShareProviderClient returns a new OCMShareProviderClient.
+func GetOCMShareProviderClient(id string, opts ...Option) (ocm.OcmAPIClient, error) {
+ selector, _ := SharingOCMSelector(id, opts...)
+ return selector.Next()
+}
+
+// GetOCMInviteManagerClient returns a new OCMInviteManagerClient.
+func GetOCMInviteManagerClient(id string, opts ...Option) (invitepb.InviteAPIClient, error) {
+ selector, _ := OCMInviteSelector(id, opts...)
+ return selector.Next()
+}
+
+// GetPublicShareProviderClient returns a new PublicShareProviderClient.
+func GetPublicShareProviderClient(id string, opts ...Option) (link.LinkAPIClient, error) {
+ selector, _ := SharingLinkSelector(id, opts...)
+ return selector.Next()
+}
+
+// GetPreferencesClient returns a new PreferencesClient.
+func GetPreferencesClient(id string, opts ...Option) (preferences.PreferencesAPIClient, error) {
+ selector, _ := PreferencesSelector(id, opts...)
+ return selector.Next()
+}
+
+// GetPermissionsClient returns a new PermissionsClient.
+func GetPermissionsClient(id string, opts ...Option) (permissions.PermissionsAPIClient, error) {
+ selector, _ := PermissionsSelector(id, opts...)
+ return selector.Next()
+}
+
+// GetAppRegistryClient returns a new AppRegistryClient.
+func GetAppRegistryClient(id string, opts ...Option) (appregistry.RegistryAPIClient, error) {
+ selector, _ := AppRegistrySelector(id, opts...)
+ return selector.Next()
+}
+
+// GetAppProviderClient returns a new AppRegistryClient.
+func GetAppProviderClient(id string, opts ...Option) (appprovider.ProviderAPIClient, error) {
+ selector, _ := AppProviderSelector(id, opts...)
+ return selector.Next()
+}
+
+// GetStorageRegistryClient returns a new StorageRegistryClient.
+func GetStorageRegistryClient(id string, opts ...Option) (storageregistry.RegistryAPIClient, error) {
+ selector, _ := StorageRegistrySelector(id, opts...)
+ return selector.Next()
+}
+
+// GetOCMProviderAuthorizerClient returns a new OCMProviderAuthorizerClient.
+func GetOCMProviderAuthorizerClient(id string, opts ...Option) (ocmprovider.ProviderAPIClient, error) {
+ selector, _ := OCMProviderSelector(id, opts...)
+ return selector.Next()
+}
+
+// GetOCMCoreClient returns a new OCMCoreClient.
+func GetOCMCoreClient(id string, opts ...Option) (ocmcore.OcmCoreAPIClient, error) {
+ selector, _ := OCMCoreSelector(id, opts...)
+ return selector.Next()
+}
+
+// GetDataTxClient returns a new DataTxClient.
+func GetDataTxClient(id string, opts ...Option) (datatx.TxAPIClient, error) {
+ selector, _ := TXSelector(id, opts...)
+ return selector.Next()
+}
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/connection.go b/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/connection.go
new file mode 100644
index 000000000..253ee7f8f
--- /dev/null
+++ b/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/connection.go
@@ -0,0 +1,102 @@
+// Copyright 2018-2021 CERN
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// In applying this license, CERN does not waive the privileges and immunities
+// granted to it by virtue of its status as an Intergovernmental Organization
+// or submit itself to any jurisdiction.
+
+package pool
+
+import (
+ "crypto/tls"
+
+ rtrace "github.com/cs3org/reva/v2/pkg/trace"
+ "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/credentials"
+ "google.golang.org/grpc/credentials/insecure"
+)
+
+var (
+ maxCallRecvMsgSize = 10240000
+)
+
+// NewConn creates a new connection to a grpc server
+// with open census tracing support.
+// TODO(labkode): make grpc tls configurable.
+// TODO make maxCallRecvMsgSize configurable, raised from the default 4MB to be able to list 10k files
+func NewConn(address string, opts ...Option) (*grpc.ClientConn, error) {
+
+ options := ClientOptions{}
+ if err := options.init(); err != nil {
+ return nil, err
+ }
+
+ // then overwrite with supplied options
+ for _, opt := range opts {
+ opt(&options)
+ }
+
+ var cred credentials.TransportCredentials
+ switch options.tlsMode {
+ case TLSOff:
+ cred = insecure.NewCredentials()
+ case TLSInsecure:
+ tlsConfig := tls.Config{
+ InsecureSkipVerify: true, //nolint:gosec
+ }
+ cred = credentials.NewTLS(&tlsConfig)
+ case TLSOn:
+ if options.caCert != "" {
+ var err error
+ if cred, err = credentials.NewClientTLSFromFile(options.caCert, ""); err != nil {
+ return nil, err
+ }
+ } else {
+ // Use system's cert pool
+ cred = credentials.NewTLS(&tls.Config{})
+ }
+ }
+
+ conn, err := grpc.Dial(
+ address,
+ grpc.WithTransportCredentials(cred),
+ grpc.WithDefaultCallOptions(
+ grpc.MaxCallRecvMsgSize(maxCallRecvMsgSize),
+ ),
+ grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor(
+ otelgrpc.WithTracerProvider(
+ options.tracerProvider,
+ ),
+ otelgrpc.WithPropagators(
+ rtrace.Propagator,
+ ),
+ )),
+ grpc.WithUnaryInterceptor(
+ otelgrpc.UnaryClientInterceptor(
+ otelgrpc.WithTracerProvider(
+ options.tracerProvider,
+ ),
+ otelgrpc.WithPropagators(
+ rtrace.Propagator,
+ ),
+ ),
+ ),
+ )
+ if err != nil {
+ return nil, err
+ }
+
+ return conn, nil
+}
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/option.go b/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/option.go
new file mode 100644
index 000000000..2dc598b7e
--- /dev/null
+++ b/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/option.go
@@ -0,0 +1,78 @@
+// Copyright 2018-2021 CERN
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// In applying this license, CERN does not waive the privileges and immunities
+// granted to it by virtue of its status as an Intergovernmental Organization
+// or submit itself to any jurisdiction.
+
+package pool
+
+import (
+ "github.com/cs3org/reva/v2/pkg/sharedconf"
+ rtrace "github.com/cs3org/reva/v2/pkg/trace"
+ "go-micro.dev/v4/registry"
+ "go.opentelemetry.io/otel/trace"
+)
+
+// Option is used to pass client options
+type Option func(opts *ClientOptions)
+
+// ClientOptions represent additional options (e.g. tls settings) for the grpc clients
+type ClientOptions struct {
+ tlsMode TLSMode
+ caCert string
+ tracerProvider trace.TracerProvider
+ registry registry.Registry
+}
+
+func (o *ClientOptions) init() error {
+ // default to shared settings
+ sharedOpt := sharedconf.GRPCClientOptions()
+ var err error
+
+ if o.tlsMode, err = StringToTLSMode(sharedOpt.TLSMode); err != nil {
+ return err
+ }
+ o.caCert = sharedOpt.CACertFile
+ o.tracerProvider = rtrace.DefaultProvider()
+ return nil
+}
+
+// WithTLSMode allows to set the TLSMode option for grpc clients
+func WithTLSMode(v TLSMode) Option {
+ return func(o *ClientOptions) {
+ o.tlsMode = v
+ }
+}
+
+// WithTLSCACert allows to set the CA Certificate for grpc clients
+func WithTLSCACert(v string) Option {
+ return func(o *ClientOptions) {
+ o.caCert = v
+ }
+}
+
+// WithTracerProvider allows to set the opentelemetry tracer provider for grpc clients
+func WithTracerProvider(v trace.TracerProvider) Option {
+ return func(o *ClientOptions) {
+ o.tracerProvider = v
+ }
+}
+
+// WithRegistry allows to set the registry for service lookup
+func WithRegistry(v registry.Registry) Option {
+ return func(o *ClientOptions) {
+ o.registry = v
+ }
+}
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/pool.go b/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/pool.go
index cd506bf9d..087ae5c63 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/pool.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/pool.go
@@ -19,50 +19,9 @@
package pool
import (
- "crypto/tls"
"fmt"
- "sync"
-
- appprovider "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1"
- appregistry "github.com/cs3org/go-cs3apis/cs3/app/registry/v1beta1"
- applicationauth "github.com/cs3org/go-cs3apis/cs3/auth/applications/v1beta1"
- authprovider "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
- authregistry "github.com/cs3org/go-cs3apis/cs3/auth/registry/v1beta1"
- gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
- group "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
- user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
- ocmcore "github.com/cs3org/go-cs3apis/cs3/ocm/core/v1beta1"
- invitepb "github.com/cs3org/go-cs3apis/cs3/ocm/invite/v1beta1"
- ocmprovider "github.com/cs3org/go-cs3apis/cs3/ocm/provider/v1beta1"
- permissions "github.com/cs3org/go-cs3apis/cs3/permissions/v1beta1"
- preferences "github.com/cs3org/go-cs3apis/cs3/preferences/v1beta1"
- collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
- link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
- ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
- storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
- storageregistry "github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1"
- datatx "github.com/cs3org/go-cs3apis/cs3/tx/v1beta1"
- "github.com/cs3org/reva/v2/pkg/sharedconf"
- rtrace "github.com/cs3org/reva/v2/pkg/trace"
- "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
- "go.opentelemetry.io/otel/trace"
- "google.golang.org/grpc"
- "google.golang.org/grpc/credentials"
- "google.golang.org/grpc/credentials/insecure"
)
-type provider struct {
- m sync.Mutex
- conn map[string]interface{}
-}
-
-func newProvider() provider {
- return provider{
- sync.Mutex{},
- make(map[string]interface{}),
- }
-}
-
// TLSMode represents TLS mode for the clients
type TLSMode int
@@ -76,41 +35,6 @@ const (
TLSInsecure
)
-// ClientOptions represent additional options (e.g. tls settings) for the grpc clients
-type ClientOptions struct {
- tlsMode TLSMode
- caCert string
- tracerProvider trace.TracerProvider
-}
-
-// Option is used to pass client options
-type Option func(opts *ClientOptions)
-
-// TODO(labkode): is concurrent access to the maps safe?
-// var storageProviders = map[string]storageprovider.ProviderAPIClient{}
-var (
- storageProviders = newProvider()
- authProviders = newProvider()
- appAuthProviders = newProvider()
- authRegistries = newProvider()
- userShareProviders = newProvider()
- ocmShareProviders = newProvider()
- ocmInviteManagers = newProvider()
- ocmProviderAuthorizers = newProvider()
- ocmCores = newProvider()
- publicShareProviders = newProvider()
- preferencesProviders = newProvider()
- permissionsProviders = newProvider()
- appRegistries = newProvider()
- appProviders = newProvider()
- storageRegistries = newProvider()
- gatewayProviders = newProvider()
- userProviders = newProvider()
- groupProviders = newProvider()
- dataTxs = newProvider()
- maxCallRecvMsgSize = 10240000
-)
-
// StringToTLSMode converts the supply string into the equivalent TLSMode constant
func StringToTLSMode(m string) (TLSMode, error) {
switch m {
@@ -124,487 +48,3 @@ func StringToTLSMode(m string) (TLSMode, error) {
return TLSOff, fmt.Errorf("unknown TLS mode: '%s'. Valid values are 'on', 'off' and 'insecure'", m)
}
}
-
-func (o *ClientOptions) init() error {
- // default to shared settings
- sharedOpt := sharedconf.GRPCClientOptions()
- var err error
-
- if o.tlsMode, err = StringToTLSMode(sharedOpt.TLSMode); err != nil {
- return err
- }
- o.caCert = sharedOpt.CACertFile
- o.tracerProvider = rtrace.DefaultProvider()
- return nil
-}
-
-// WithTLSMode allows to set the TLSMode option for grpc clients
-func WithTLSMode(v TLSMode) Option {
- return func(o *ClientOptions) {
- o.tlsMode = v
- }
-}
-
-// WithTLSCACert allows to set the CA Certificate for grpc clients
-func WithTLSCACert(v string) Option {
- return func(o *ClientOptions) {
- o.caCert = v
- }
-}
-
-// WithTracerProvider allows to set the opentelemetry tracer provider for grpc clients
-func WithTracerProvider(v trace.TracerProvider) Option {
- return func(o *ClientOptions) {
- o.tracerProvider = v
- }
-}
-
-// NewConn creates a new connection to a grpc server
-// with open census tracing support.
-// TODO(labkode): make grpc tls configurable.
-// TODO make maxCallRecvMsgSize configurable, raised from the default 4MB to be able to list 10k files
-func NewConn(endpoint string, opts ...Option) (*grpc.ClientConn, error) {
-
- options := ClientOptions{}
- if err := options.init(); err != nil {
- return nil, err
- }
-
- // then overwrite with supplied options
- for _, opt := range opts {
- opt(&options)
- }
-
- var cred credentials.TransportCredentials
- switch options.tlsMode {
- case TLSOff:
- cred = insecure.NewCredentials()
- case TLSInsecure:
- tlsConfig := tls.Config{
- InsecureSkipVerify: true, //nolint:gosec
- }
- cred = credentials.NewTLS(&tlsConfig)
- case TLSOn:
- if options.caCert != "" {
- var err error
- if cred, err = credentials.NewClientTLSFromFile(options.caCert, ""); err != nil {
- return nil, err
- }
- } else {
- // Use system's cert pool
- cred = credentials.NewTLS(&tls.Config{})
- }
- }
-
- conn, err := grpc.Dial(
- endpoint,
- grpc.WithTransportCredentials(cred),
- grpc.WithDefaultCallOptions(
- grpc.MaxCallRecvMsgSize(maxCallRecvMsgSize),
- ),
- grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor(
- otelgrpc.WithTracerProvider(
- options.tracerProvider,
- ),
- otelgrpc.WithPropagators(
- rtrace.Propagator,
- ),
- )),
- grpc.WithUnaryInterceptor(
- otelgrpc.UnaryClientInterceptor(
- otelgrpc.WithTracerProvider(
- options.tracerProvider,
- ),
- otelgrpc.WithPropagators(
- rtrace.Propagator,
- ),
- ),
- ),
- )
- if err != nil {
- return nil, err
- }
-
- return conn, nil
-}
-
-// GetGatewayServiceClient returns a GatewayServiceClient.
-func GetGatewayServiceClient(endpoint string, opts ...Option) (gateway.GatewayAPIClient, error) {
- gatewayProviders.m.Lock()
- defer gatewayProviders.m.Unlock()
-
- if val, ok := gatewayProviders.conn[endpoint]; ok {
- return val.(gateway.GatewayAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := gateway.NewGatewayAPIClient(conn)
- gatewayProviders.conn[endpoint] = v
-
- return v, nil
-}
-
-// GetUserProviderServiceClient returns a UserProviderServiceClient.
-func GetUserProviderServiceClient(endpoint string, opts ...Option) (user.UserAPIClient, error) {
- userProviders.m.Lock()
- defer userProviders.m.Unlock()
-
- if val, ok := userProviders.conn[endpoint]; ok {
- return val.(user.UserAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := user.NewUserAPIClient(conn)
- userProviders.conn[endpoint] = v
- return v, nil
-}
-
-// GetGroupProviderServiceClient returns a GroupProviderServiceClient.
-func GetGroupProviderServiceClient(endpoint string, opts ...Option) (group.GroupAPIClient, error) {
- groupProviders.m.Lock()
- defer groupProviders.m.Unlock()
-
- if val, ok := groupProviders.conn[endpoint]; ok {
- return val.(group.GroupAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := group.NewGroupAPIClient(conn)
- groupProviders.conn[endpoint] = v
- return v, nil
-}
-
-// GetStorageProviderServiceClient returns a StorageProviderServiceClient.
-func GetStorageProviderServiceClient(endpoint string, opts ...Option) (storageprovider.ProviderAPIClient, error) {
- storageProviders.m.Lock()
- defer storageProviders.m.Unlock()
-
- if c, ok := storageProviders.conn[endpoint]; ok {
- return c.(storageprovider.ProviderAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := storageprovider.NewProviderAPIClient(conn)
- storageProviders.conn[endpoint] = v
- return v, nil
-}
-
-// GetAuthRegistryServiceClient returns a new AuthRegistryServiceClient.
-func GetAuthRegistryServiceClient(endpoint string, opts ...Option) (authregistry.RegistryAPIClient, error) {
- authRegistries.m.Lock()
- defer authRegistries.m.Unlock()
-
- // if there is already a connection to this node, use it.
- if c, ok := authRegistries.conn[endpoint]; ok {
- return c.(authregistry.RegistryAPIClient), nil
- }
-
- // if not, create a new connection
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- // and memoize it
- v := authregistry.NewRegistryAPIClient(conn)
- authRegistries.conn[endpoint] = v
- return v, nil
-}
-
-// GetAuthProviderServiceClient returns a new AuthProviderServiceClient.
-func GetAuthProviderServiceClient(endpoint string, opts ...Option) (authprovider.ProviderAPIClient, error) {
- authProviders.m.Lock()
- defer authProviders.m.Unlock()
-
- if c, ok := authProviders.conn[endpoint]; ok {
- return c.(authprovider.ProviderAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := authprovider.NewProviderAPIClient(conn)
- authProviders.conn[endpoint] = v
- return v, nil
-}
-
-// GetAppAuthProviderServiceClient returns a new AppAuthProviderServiceClient.
-func GetAppAuthProviderServiceClient(endpoint string, opts ...Option) (applicationauth.ApplicationsAPIClient, error) {
- appAuthProviders.m.Lock()
- defer appAuthProviders.m.Unlock()
-
- if c, ok := appAuthProviders.conn[endpoint]; ok {
- return c.(applicationauth.ApplicationsAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := applicationauth.NewApplicationsAPIClient(conn)
- appAuthProviders.conn[endpoint] = v
- return v, nil
-}
-
-// GetUserShareProviderClient returns a new UserShareProviderClient.
-func GetUserShareProviderClient(endpoint string, opts ...Option) (collaboration.CollaborationAPIClient, error) {
- userShareProviders.m.Lock()
- defer userShareProviders.m.Unlock()
-
- if c, ok := userShareProviders.conn[endpoint]; ok {
- return c.(collaboration.CollaborationAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := collaboration.NewCollaborationAPIClient(conn)
- userShareProviders.conn[endpoint] = v
- return v, nil
-}
-
-// GetOCMShareProviderClient returns a new OCMShareProviderClient.
-func GetOCMShareProviderClient(endpoint string, opts ...Option) (ocm.OcmAPIClient, error) {
- ocmShareProviders.m.Lock()
- defer ocmShareProviders.m.Unlock()
-
- if c, ok := ocmShareProviders.conn[endpoint]; ok {
- return c.(ocm.OcmAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := ocm.NewOcmAPIClient(conn)
- ocmShareProviders.conn[endpoint] = v
- return v, nil
-}
-
-// GetOCMInviteManagerClient returns a new OCMInviteManagerClient.
-func GetOCMInviteManagerClient(endpoint string, opts ...Option) (invitepb.InviteAPIClient, error) {
- ocmInviteManagers.m.Lock()
- defer ocmInviteManagers.m.Unlock()
-
- if c, ok := ocmInviteManagers.conn[endpoint]; ok {
- return c.(invitepb.InviteAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := invitepb.NewInviteAPIClient(conn)
- ocmInviteManagers.conn[endpoint] = v
- return v, nil
-}
-
-// GetPublicShareProviderClient returns a new PublicShareProviderClient.
-func GetPublicShareProviderClient(endpoint string, opts ...Option) (link.LinkAPIClient, error) {
- publicShareProviders.m.Lock()
- defer publicShareProviders.m.Unlock()
-
- if c, ok := publicShareProviders.conn[endpoint]; ok {
- return c.(link.LinkAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := link.NewLinkAPIClient(conn)
- publicShareProviders.conn[endpoint] = v
- return v, nil
-}
-
-// GetPreferencesClient returns a new PreferencesClient.
-func GetPreferencesClient(endpoint string, opts ...Option) (preferences.PreferencesAPIClient, error) {
- preferencesProviders.m.Lock()
- defer preferencesProviders.m.Unlock()
-
- if c, ok := preferencesProviders.conn[endpoint]; ok {
- return c.(preferences.PreferencesAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := preferences.NewPreferencesAPIClient(conn)
- preferencesProviders.conn[endpoint] = v
- return v, nil
-}
-
-// GetPermissionsClient returns a new PermissionsClient.
-func GetPermissionsClient(endpoint string, opts ...Option) (permissions.PermissionsAPIClient, error) {
- permissionsProviders.m.Lock()
- defer permissionsProviders.m.Unlock()
-
- if c, ok := permissionsProviders.conn[endpoint]; ok {
- return c.(permissions.PermissionsAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := permissions.NewPermissionsAPIClient(conn)
- permissionsProviders.conn[endpoint] = v
- return v, nil
-}
-
-// GetAppRegistryClient returns a new AppRegistryClient.
-func GetAppRegistryClient(endpoint string, opts ...Option) (appregistry.RegistryAPIClient, error) {
- appRegistries.m.Lock()
- defer appRegistries.m.Unlock()
-
- if c, ok := appRegistries.conn[endpoint]; ok {
- return c.(appregistry.RegistryAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := appregistry.NewRegistryAPIClient(conn)
- appRegistries.conn[endpoint] = v
- return v, nil
-}
-
-// GetAppProviderClient returns a new AppRegistryClient.
-func GetAppProviderClient(endpoint string, opts ...Option) (appprovider.ProviderAPIClient, error) {
- appProviders.m.Lock()
- defer appProviders.m.Unlock()
-
- if c, ok := appProviders.conn[endpoint]; ok {
- return c.(appprovider.ProviderAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := appprovider.NewProviderAPIClient(conn)
- appProviders.conn[endpoint] = v
- return v, nil
-}
-
-// GetStorageRegistryClient returns a new StorageRegistryClient.
-func GetStorageRegistryClient(endpoint string, opts ...Option) (storageregistry.RegistryAPIClient, error) {
- storageRegistries.m.Lock()
- defer storageRegistries.m.Unlock()
-
- if c, ok := storageRegistries.conn[endpoint]; ok {
- return c.(storageregistry.RegistryAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := storageregistry.NewRegistryAPIClient(conn)
- storageRegistries.conn[endpoint] = v
- return v, nil
-}
-
-// GetOCMProviderAuthorizerClient returns a new OCMProviderAuthorizerClient.
-func GetOCMProviderAuthorizerClient(endpoint string, opts ...Option) (ocmprovider.ProviderAPIClient, error) {
- ocmProviderAuthorizers.m.Lock()
- defer ocmProviderAuthorizers.m.Unlock()
-
- if c, ok := ocmProviderAuthorizers.conn[endpoint]; ok {
- return c.(ocmprovider.ProviderAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := ocmprovider.NewProviderAPIClient(conn)
- ocmProviderAuthorizers.conn[endpoint] = v
- return v, nil
-}
-
-// GetOCMCoreClient returns a new OCMCoreClient.
-func GetOCMCoreClient(endpoint string, opts ...Option) (ocmcore.OcmCoreAPIClient, error) {
- ocmCores.m.Lock()
- defer ocmCores.m.Unlock()
-
- if c, ok := ocmCores.conn[endpoint]; ok {
- return c.(ocmcore.OcmCoreAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := ocmcore.NewOcmCoreAPIClient(conn)
- ocmCores.conn[endpoint] = v
- return v, nil
-}
-
-// GetDataTxClient returns a new DataTxClient.
-func GetDataTxClient(endpoint string, opts ...Option) (datatx.TxAPIClient, error) {
- dataTxs.m.Lock()
- defer dataTxs.m.Unlock()
-
- if c, ok := dataTxs.conn[endpoint]; ok {
- return c.(datatx.TxAPIClient), nil
- }
-
- conn, err := NewConn(endpoint, opts...)
- if err != nil {
- return nil, err
- }
-
- v := datatx.NewTxAPIClient(conn)
- dataTxs.conn[endpoint] = v
- return v, nil
-}
-
-// getEndpointByName resolve service names to ip addresses present on the registry.
-// func getEndpointByName(name string) (string, error) {
-// if services, err := utils.GlobalRegistry.GetService(name); err == nil {
-// if len(services) > 0 {
-// for i := range services {
-// for j := range services[i].Nodes() {
-// // return the first one. This MUST be improved upon with selectors.
-// return services[i].Nodes()[j].Address(), nil
-// }
-// }
-// }
-// }
-//
-// return "", fmt.Errorf("could not get service by name: %v", name)
-// }
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/selector.go b/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/selector.go
new file mode 100644
index 000000000..57f9c114e
--- /dev/null
+++ b/vendor/github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool/selector.go
@@ -0,0 +1,315 @@
+// Copyright 2018-2021 CERN
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// In applying this license, CERN does not waive the privileges and immunities
+// granted to it by virtue of its status as an Intergovernmental Organization
+// or submit itself to any jurisdiction.
+
+package pool
+
+import (
+ "fmt"
+ "sync"
+
+ appProvider "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1"
+ appRegistry "github.com/cs3org/go-cs3apis/cs3/app/registry/v1beta1"
+ authApplication "github.com/cs3org/go-cs3apis/cs3/auth/applications/v1beta1"
+ authProvider "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
+ authRegistry "github.com/cs3org/go-cs3apis/cs3/auth/registry/v1beta1"
+ gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
+ identityGroup "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
+ identityUser "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
+ ocmCore "github.com/cs3org/go-cs3apis/cs3/ocm/core/v1beta1"
+ ocmInvite "github.com/cs3org/go-cs3apis/cs3/ocm/invite/v1beta1"
+ ocmProvider "github.com/cs3org/go-cs3apis/cs3/ocm/provider/v1beta1"
+ permissions "github.com/cs3org/go-cs3apis/cs3/permissions/v1beta1"
+ preferences "github.com/cs3org/go-cs3apis/cs3/preferences/v1beta1"
+ sharingCollaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
+ sharingLink "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
+ sharingOCM "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
+ storageProvider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
+ storageRegistry "github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1"
+ tx "github.com/cs3org/go-cs3apis/cs3/tx/v1beta1"
+ "github.com/cs3org/reva/v2/pkg/registry"
+ "github.com/pkg/errors"
+ "google.golang.org/grpc"
+)
+
+type Selectable[T any] interface {
+ Next(opts ...Option) (T, error)
+}
+
+var selectors sync.Map
+
+// RemoveSelector removes given id from the selectors map.
+func RemoveSelector(id string) {
+ selectors.Delete(id)
+}
+
+func GetSelector[T any](k string, id string, f func(cc *grpc.ClientConn) T, options ...Option) *Selector[T] {
+ existingSelector, ok := selectors.Load(k + id)
+ if ok {
+ return existingSelector.(*Selector[T])
+ }
+
+ newSelector := &Selector[T]{
+ id: id,
+ clientFactory: f,
+ options: options,
+ }
+
+ selectors.Store(k+id, newSelector)
+
+ return newSelector
+}
+
+type Selector[T any] struct {
+ id string
+ clientFactory func(cc *grpc.ClientConn) T
+ clientMap sync.Map
+ options []Option
+}
+
+func (s *Selector[T]) Next(opts ...Option) (T, error) {
+ options := ClientOptions{
+ registry: registry.GetRegistry(),
+ }
+
+ allOpts := append([]Option{}, s.options...)
+ allOpts = append(allOpts, opts...)
+
+ for _, opt := range allOpts {
+ opt(&options)
+ }
+
+ address := s.id
+ if options.registry != nil {
+ services, err := options.registry.GetService(s.id)
+ if err != nil {
+ return *new(T), fmt.Errorf("%s: %w", s.id, err)
+ }
+
+ nodeAddress, err := registry.GetNodeAddress(services)
+ if err != nil {
+ return *new(T), fmt.Errorf("%s: %w", s.id, err)
+ }
+
+ address = nodeAddress
+ }
+
+ existingClient, ok := s.clientMap.Load(address)
+ if ok {
+ return existingClient.(T), nil
+ }
+
+ conn, err := NewConn(address, allOpts...)
+ if err != nil {
+ return *new(T), errors.Wrap(err, fmt.Sprintf("could not create connection for %s to %s", s.id, address))
+ }
+
+ newClient := s.clientFactory(conn)
+ s.clientMap.Store(address, newClient)
+
+ return newClient, nil
+}
+
+// GatewaySelector returns a Selector[gateway.GatewayAPIClient].
+func GatewaySelector(id string, options ...Option) (*Selector[gateway.GatewayAPIClient], error) {
+ return GetSelector[gateway.GatewayAPIClient](
+ "GatewaySelector",
+ id,
+ gateway.NewGatewayAPIClient,
+ options...,
+ ), nil
+}
+
+// IdentityUserSelector returns a Selector[identityUser.UserAPIClient].
+func IdentityUserSelector(id string, options ...Option) (*Selector[identityUser.UserAPIClient], error) {
+ return GetSelector[identityUser.UserAPIClient](
+ "IdentityUserSelector",
+ id,
+ identityUser.NewUserAPIClient,
+ options...,
+ ), nil
+}
+
+// IdentityGroupSelector returns a Selector[identityGroup.GroupAPIClient].
+func IdentityGroupSelector(id string, options ...Option) (*Selector[identityGroup.GroupAPIClient], error) {
+ return GetSelector[identityGroup.GroupAPIClient](
+ "IdentityGroupSelector",
+ id,
+ identityGroup.NewGroupAPIClient,
+ options...,
+ ), nil
+}
+
+// StorageProviderSelector returns a Selector[storageProvider.ProviderAPIClient].
+func StorageProviderSelector(id string, options ...Option) (*Selector[storageProvider.ProviderAPIClient], error) {
+ return GetSelector[storageProvider.ProviderAPIClient](
+ "StorageProviderSelector",
+ id,
+ storageProvider.NewProviderAPIClient,
+ options...,
+ ), nil
+}
+
+// AuthRegistrySelector returns a Selector[authRegistry.RegistryAPIClient].
+func AuthRegistrySelector(id string, options ...Option) (*Selector[authRegistry.RegistryAPIClient], error) {
+ return GetSelector[authRegistry.RegistryAPIClient](
+ "AuthRegistrySelector",
+ id,
+ authRegistry.NewRegistryAPIClient,
+ options...,
+ ), nil
+}
+
+// AuthProviderSelector returns a Selector[authProvider.RegistryAPIClient].
+func AuthProviderSelector(id string, options ...Option) (*Selector[authProvider.ProviderAPIClient], error) {
+ return GetSelector[authProvider.ProviderAPIClient](
+ "AuthProviderSelector",
+ id,
+ authProvider.NewProviderAPIClient,
+ options...,
+ ), nil
+}
+
+// AuthApplicationSelector returns a Selector[authApplication.ApplicationsAPIClient].
+func AuthApplicationSelector(id string, options ...Option) (*Selector[authApplication.ApplicationsAPIClient], error) {
+ return GetSelector[authApplication.ApplicationsAPIClient](
+ "AuthApplicationSelector",
+ id,
+ authApplication.NewApplicationsAPIClient,
+ options...,
+ ), nil
+}
+
+// SharingCollaborationSelector returns a Selector[sharingCollaboration.ApplicationsAPIClient].
+func SharingCollaborationSelector(id string, options ...Option) (*Selector[sharingCollaboration.CollaborationAPIClient], error) {
+ return GetSelector[sharingCollaboration.CollaborationAPIClient](
+ "SharingCollaborationSelector",
+ id,
+ sharingCollaboration.NewCollaborationAPIClient,
+ options...,
+ ), nil
+}
+
+// SharingOCMSelector returns a Selector[sharingOCM.OcmAPIClient].
+func SharingOCMSelector(id string, options ...Option) (*Selector[sharingOCM.OcmAPIClient], error) {
+ return GetSelector[sharingOCM.OcmAPIClient](
+ "SharingOCMSelector",
+ id,
+ sharingOCM.NewOcmAPIClient,
+ options...,
+ ), nil
+}
+
+// SharingLinkSelector returns a Selector[sharingLink.LinkAPIClient].
+func SharingLinkSelector(id string, options ...Option) (*Selector[sharingLink.LinkAPIClient], error) {
+ return GetSelector[sharingLink.LinkAPIClient](
+ "SharingLinkSelector",
+ id,
+ sharingLink.NewLinkAPIClient,
+ options...,
+ ), nil
+}
+
+// PreferencesSelector returns a Selector[preferences.PreferencesAPIClient].
+func PreferencesSelector(id string, options ...Option) (*Selector[preferences.PreferencesAPIClient], error) {
+ return GetSelector[preferences.PreferencesAPIClient](
+ "PreferencesSelector",
+ id,
+ preferences.NewPreferencesAPIClient,
+ options...,
+ ), nil
+}
+
+// PermissionsSelector returns a Selector[permissions.PermissionsAPIClient].
+func PermissionsSelector(id string, options ...Option) (*Selector[permissions.PermissionsAPIClient], error) {
+ return GetSelector[permissions.PermissionsAPIClient](
+ "PermissionsSelector",
+ id,
+ permissions.NewPermissionsAPIClient,
+ options...,
+ ), nil
+}
+
+// AppRegistrySelector returns a Selector[appRegistry.RegistryAPIClient].
+func AppRegistrySelector(id string, options ...Option) (*Selector[appRegistry.RegistryAPIClient], error) {
+ return GetSelector[appRegistry.RegistryAPIClient](
+ "AppRegistrySelector",
+ id,
+ appRegistry.NewRegistryAPIClient,
+ options...,
+ ), nil
+}
+
+// AppProviderSelector returns a Selector[appProvider.ProviderAPIClient].
+func AppProviderSelector(id string, options ...Option) (*Selector[appProvider.ProviderAPIClient], error) {
+ return GetSelector[appProvider.ProviderAPIClient](
+ "AppProviderSelector",
+ id,
+ appProvider.NewProviderAPIClient,
+ options...,
+ ), nil
+}
+
+// StorageRegistrySelector returns a Selector[storageRegistry.RegistryAPIClient].
+func StorageRegistrySelector(id string, options ...Option) (*Selector[storageRegistry.RegistryAPIClient], error) {
+ return GetSelector[storageRegistry.RegistryAPIClient](
+ "StorageRegistrySelector",
+ id,
+ storageRegistry.NewRegistryAPIClient,
+ options...,
+ ), nil
+}
+
+// OCMProviderSelector returns a Selector[storageRegistry.RegistryAPIClient].
+func OCMProviderSelector(id string, options ...Option) (*Selector[ocmProvider.ProviderAPIClient], error) {
+ return GetSelector[ocmProvider.ProviderAPIClient](
+ "OCMProviderSelector",
+ id,
+ ocmProvider.NewProviderAPIClient,
+ options...,
+ ), nil
+}
+
+// OCMCoreSelector returns a Selector[ocmCore.OcmCoreAPIClient].
+func OCMCoreSelector(id string, options ...Option) (*Selector[ocmCore.OcmCoreAPIClient], error) {
+ return GetSelector[ocmCore.OcmCoreAPIClient](
+ "OCMCoreSelector",
+ id,
+ ocmCore.NewOcmCoreAPIClient,
+ options...,
+ ), nil
+}
+
+// OCMInviteSelector returns a Selector[ocmInvite.InviteAPIClient].
+func OCMInviteSelector(id string, options ...Option) (*Selector[ocmInvite.InviteAPIClient], error) {
+ return GetSelector[ocmInvite.InviteAPIClient](
+ "OCMInviteSelector",
+ id,
+ ocmInvite.NewInviteAPIClient,
+ options...,
+ ), nil
+}
+
+// TXSelector returns a Selector[tx.TxAPIClient].
+func TXSelector(id string, options ...Option) (*Selector[tx.TxAPIClient], error) {
+ return GetSelector[tx.TxAPIClient](
+ "TXSelector",
+ id,
+ tx.NewTxAPIClient,
+ options...,
+ ), nil
+}
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go b/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go
index 2d301ba83..6943605f0 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go
@@ -33,6 +33,7 @@ import (
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
+ "golang.org/x/sync/errgroup"
"google.golang.org/genproto/protobuf/field_mask"
gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
@@ -109,12 +110,16 @@ import (
- if the mtime changed we download the file to update the local cache
*/
+// name is the Tracer name used to identify this instrumentation library.
+const tracerName = "jsoncs3"
+
func init() {
registry.Register("jsoncs3", NewDefault)
}
type config struct {
GatewayAddr string `mapstructure:"gateway_addr"`
+ MaxConcurrency int `mapstructure:"max_concurrency"`
ProviderAddr string `mapstructure:"provider_addr"`
ServiceUserID string `mapstructure:"service_user_id"`
ServiceUserIdp string `mapstructure:"service_user_idp"`
@@ -145,6 +150,8 @@ type Manager struct {
initialized bool
+ MaxConcurrency int
+
gateway gatewayv1beta1.GatewayAPIClient
eventStream events.Stream
}
@@ -205,11 +212,11 @@ func NewDefault(m map[string]interface{}) (share.Manager, error) {
}
}
- return New(s, gc, c.CacheTTL, es)
+ return New(s, gc, c.CacheTTL, es, c.MaxConcurrency)
}
// New returns a new manager instance.
-func New(s metadata.Storage, gc gatewayv1beta1.GatewayAPIClient, ttlSeconds int, es events.Stream) (*Manager, error) {
+func New(s metadata.Storage, gc gatewayv1beta1.GatewayAPIClient, ttlSeconds int, es events.Stream, maxconcurrency int) (*Manager, error) {
ttl := time.Duration(ttlSeconds) * time.Second
return &Manager{
Cache: providercache.New(s, ttl),
@@ -219,6 +226,7 @@ func New(s metadata.Storage, gc gatewayv1beta1.GatewayAPIClient, ttlSeconds int,
storage: s,
gateway: gc,
eventStream: es,
+ MaxConcurrency: maxconcurrency,
}, nil
}
@@ -259,6 +267,8 @@ func (m *Manager) initialize() error {
// Share creates a new share
func (m *Manager) Share(ctx context.Context, md *provider.ResourceInfo, g *collaboration.ShareGrant) (*collaboration.Share, error) {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Share")
+ defer span.End()
if err := m.initialize(); err != nil {
return nil, err
}
@@ -413,6 +423,8 @@ func (m *Manager) get(ctx context.Context, ref *collaboration.ShareReference) (s
// GetShare gets the information for a share by the given ref.
func (m *Manager) GetShare(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.Share, error) {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "GetShare")
+ defer span.End()
if err := m.initialize(); err != nil {
return nil, err
}
@@ -463,6 +475,9 @@ func (m *Manager) GetShare(ctx context.Context, ref *collaboration.ShareReferenc
// Unshare deletes a share
func (m *Manager) Unshare(ctx context.Context, ref *collaboration.ShareReference) error {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Unshare")
+ defer span.End()
+
if err := m.initialize(); err != nil {
return err
}
@@ -486,6 +501,9 @@ func (m *Manager) Unshare(ctx context.Context, ref *collaboration.ShareReference
// UpdateShare updates the mode of the given share.
func (m *Manager) UpdateShare(ctx context.Context, ref *collaboration.ShareReference, p *collaboration.SharePermissions, updated *collaboration.Share, fieldMask *field_mask.FieldMask) (*collaboration.Share, error) {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "UpdateShare")
+ defer span.End()
+
if err := m.initialize(); err != nil {
return nil, err
}
@@ -565,6 +583,9 @@ func (m *Manager) UpdateShare(ctx context.Context, ref *collaboration.ShareRefer
// ListShares returns the shares created by the user
func (m *Manager) ListShares(ctx context.Context, filters []*collaboration.Filter) ([]*collaboration.Share, error) {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "ListShares")
+ defer span.End()
+
if err := m.initialize(); err != nil {
return nil, err
}
@@ -582,6 +603,9 @@ func (m *Manager) ListShares(ctx context.Context, filters []*collaboration.Filte
}
func (m *Manager) listSharesByIDs(ctx context.Context, user *userv1beta1.User, filters []*collaboration.Filter) ([]*collaboration.Share, error) {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "listSharesByIDs")
+ defer span.End()
+
providerSpaces := make(map[string]map[string]struct{})
for _, f := range share.FilterFiltersByType(filters, collaboration.Filter_TYPE_RESOURCE_ID) {
storageID := f.GetResourceId().GetStorageId()
@@ -649,6 +673,9 @@ func (m *Manager) listSharesByIDs(ctx context.Context, user *userv1beta1.User, f
}
func (m *Manager) listCreatedShares(ctx context.Context, user *userv1beta1.User, filters []*collaboration.Filter) ([]*collaboration.Share, error) {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "listCreatedShares")
+ defer span.End()
+
var ss []*collaboration.Share
if err := m.CreatedCache.Sync(ctx, user.Id.OpaqueId); err != nil {
@@ -696,6 +723,9 @@ func (m *Manager) listCreatedShares(ctx context.Context, user *userv1beta1.User,
// ListReceivedShares returns the list of shares the user has access to.
func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter) ([]*collaboration.ReceivedShare, error) {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "ListReceivedShares")
+ defer span.End()
+
if err := m.initialize(); err != nil {
return nil, err
}
@@ -703,7 +733,6 @@ func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaborati
m.Lock()
defer m.Unlock()
- var rss []*collaboration.ReceivedShare
user := ctxpkg.ContextMustGetUser(ctx)
ssids := map[string]*receivedsharecache.Space{}
@@ -750,46 +779,98 @@ func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaborati
}
}
- for ssid, rspace := range ssids {
- storageID, spaceID, _ := shareid.Decode(ssid)
- err := m.Cache.Sync(ctx, storageID, spaceID)
- if err != nil {
- continue
- }
- for shareID, state := range rspace.States {
- s := m.Cache.Get(storageID, spaceID, shareID)
- if s == nil {
- continue
- }
- if share.IsExpired(s) {
- if err := m.removeShare(ctx, s); err != nil {
- log.Error().Err(err).
- Msg("failed to unshare expired share")
- }
- if err := events.Publish(m.eventStream, events.ShareExpired{
- ShareOwner: s.GetOwner(),
- ItemID: s.GetResourceId(),
- ExpiredAt: time.Unix(int64(s.GetExpiration().GetSeconds()), int64(s.GetExpiration().GetNanos())),
- GranteeUserID: s.GetGrantee().GetUserId(),
- GranteeGroupID: s.GetGrantee().GetGroupId(),
- }); err != nil {
- log.Error().Err(err).
- Msg("failed to publish share expired event")
- }
- continue
- }
+ numWorkers := m.MaxConcurrency
+ if numWorkers == 0 || len(ssids) < numWorkers {
+ numWorkers = len(ssids)
+ }
- if share.IsGrantedToUser(s, user) {
- if share.MatchesFiltersWithState(s, state.State, filters) {
- rs := &collaboration.ReceivedShare{
- Share: s,
- State: state.State,
- MountPoint: state.MountPoint,
- }
- rss = append(rss, rs)
- }
+ type w struct {
+ ssid string
+ rspace *receivedsharecache.Space
+ }
+ work := make(chan w)
+ results := make(chan *collaboration.ReceivedShare)
+
+ g, ctx := errgroup.WithContext(ctx)
+
+ // Distribute work
+ g.Go(func() error {
+ defer close(work)
+ for ssid, rspace := range ssids {
+ select {
+ case work <- w{ssid, rspace}:
+ case <-ctx.Done():
+ return ctx.Err()
}
}
+ return nil
+ })
+
+ // Spawn workers that'll concurrently work the queue
+ for i := 0; i < numWorkers; i++ {
+ g.Go(func() error {
+ for w := range work {
+ storageID, spaceID, _ := shareid.Decode(w.ssid)
+ err := m.Cache.Sync(ctx, storageID, spaceID)
+ if err != nil {
+ continue
+ }
+ for shareID, state := range w.rspace.States {
+ s := m.Cache.Get(storageID, spaceID, shareID)
+ if s == nil {
+ continue
+ }
+ if share.IsExpired(s) {
+ if err := m.removeShare(ctx, s); err != nil {
+ log.Error().Err(err).
+ Msg("failed to unshare expired share")
+ }
+ if err := events.Publish(m.eventStream, events.ShareExpired{
+ ShareOwner: s.GetOwner(),
+ ItemID: s.GetResourceId(),
+ ExpiredAt: time.Unix(int64(s.GetExpiration().GetSeconds()), int64(s.GetExpiration().GetNanos())),
+ GranteeUserID: s.GetGrantee().GetUserId(),
+ GranteeGroupID: s.GetGrantee().GetGroupId(),
+ }); err != nil {
+ log.Error().Err(err).
+ Msg("failed to publish share expired event")
+ }
+ continue
+ }
+
+ if share.IsGrantedToUser(s, user) {
+ if share.MatchesFiltersWithState(s, state.State, filters) {
+ rs := &collaboration.ReceivedShare{
+ Share: s,
+ State: state.State,
+ MountPoint: state.MountPoint,
+ }
+ select {
+ case results <- rs:
+ case <-ctx.Done():
+ return ctx.Err()
+ }
+ }
+ }
+ }
+ }
+ return nil
+ })
+ }
+
+ // Wait for things to settle down, then close results chan
+ go func() {
+ _ = g.Wait() // error is checked later
+ close(results)
+ }()
+
+ rss := []*collaboration.ReceivedShare{}
+ for n := range results {
+ rss = append(rss, n)
+ }
+
+ if err := g.Wait(); err != nil {
+ return nil, err
}
return rss, nil
@@ -797,6 +878,9 @@ func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaborati
// convert must be called in a lock-controlled block.
func (m *Manager) convert(ctx context.Context, userID string, s *collaboration.Share) *collaboration.ReceivedShare {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "convert")
+ defer span.End()
+
rs := &collaboration.ReceivedShare{
Share: s,
State: collaboration.ShareState_SHARE_STATE_PENDING,
@@ -823,6 +907,9 @@ func (m *Manager) GetReceivedShare(ctx context.Context, ref *collaboration.Share
}
func (m *Manager) getReceived(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.ReceivedShare, error) {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "getReceived")
+ defer span.End()
+
m.Lock()
defer m.Unlock()
s, err := m.get(ctx, ref)
@@ -854,6 +941,9 @@ func (m *Manager) getReceived(ctx context.Context, ref *collaboration.ShareRefer
// UpdateReceivedShare updates the received share with share state.
func (m *Manager) UpdateReceivedShare(ctx context.Context, receivedShare *collaboration.ReceivedShare, fieldMask *field_mask.FieldMask) (*collaboration.ReceivedShare, error) {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "UpdateReceivedShare")
+ defer span.End()
+
if err := m.initialize(); err != nil {
return nil, err
}
@@ -964,6 +1054,9 @@ func (m *Manager) Load(ctx context.Context, shareChan <-chan *collaboration.Shar
}
func (m *Manager) removeShare(ctx context.Context, s *collaboration.Share) error {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "removeShare")
+ defer span.End()
+
storageID, spaceID, _ := shareid.Decode(s.Id.OpaqueId)
err := m.Cache.Remove(ctx, storageID, spaceID, s.Id.OpaqueId)
if _, ok := err.(errtypes.IsPreconditionFailed); ok {
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/providercache/providercache.go b/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/providercache/providercache.go
index 528922ac4..2fc4ed182 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/providercache/providercache.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/providercache/providercache.go
@@ -33,8 +33,13 @@ import (
"github.com/cs3org/reva/v2/pkg/errtypes"
"github.com/cs3org/reva/v2/pkg/storage/utils/metadata"
"github.com/cs3org/reva/v2/pkg/utils"
+ "go.opentelemetry.io/otel/attribute"
+ "go.opentelemetry.io/otel/codes"
)
+// name is the Tracer name used to identify this instrumentation library.
+const tracerName = "providercache"
+
// Cache holds share information structured by provider and space
type Cache struct {
Providers map[string]*Spaces
@@ -106,6 +111,10 @@ func New(s metadata.Storage, ttl time.Duration) Cache {
// Add adds a share to the cache
func (c *Cache) Add(ctx context.Context, storageID, spaceID, shareID string, share *collaboration.Share) error {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Add")
+ defer span.End()
+ span.SetAttributes(attribute.String("cs3.storageid", storageID), attribute.String("cs3.spaceid", spaceID), attribute.String("cs3.shareid", shareID))
+
switch {
case storageID == "":
return fmt.Errorf("missing storage id")
@@ -122,6 +131,10 @@ func (c *Cache) Add(ctx context.Context, storageID, spaceID, shareID string, sha
// Remove removes a share from the cache
func (c *Cache) Remove(ctx context.Context, storageID, spaceID, shareID string) error {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Remove")
+ defer span.End()
+ span.SetAttributes(attribute.String("cs3.storageid", storageID), attribute.String("cs3.spaceid", spaceID), attribute.String("cs3.shareid", shareID))
+
if c.Providers[storageID] == nil ||
c.Providers[storageID].Spaces[spaceID] == nil {
return nil
@@ -150,6 +163,10 @@ func (c *Cache) ListSpace(storageID, spaceID string) *Shares {
// PersistWithTime persists the data of one space if it has not been modified since the given mtime
func (c *Cache) PersistWithTime(ctx context.Context, storageID, spaceID string, mtime time.Time) error {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "PersistWithTime")
+ defer span.End()
+ span.SetAttributes(attribute.String("cs3.storageid", storageID), attribute.String("cs3.spaceid", spaceID))
+
if c.Providers[storageID] == nil || c.Providers[storageID].Spaces[spaceID] == nil {
return nil
}
@@ -187,15 +204,20 @@ func (c *Cache) Persist(ctx context.Context, storageID, spaceID string) error {
// Sync updates the in-memory data with the data from the storage if it is outdated
func (c *Cache) Sync(ctx context.Context, storageID, spaceID string) error {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Sync")
+ defer span.End()
+
+ span.SetAttributes(attribute.String("cs3.storageid", storageID), attribute.String("cs3.spaceid", spaceID))
+
log := appctx.GetLogger(ctx).With().Str("storageID", storageID).Str("spaceID", spaceID).Logger()
- log.Debug().Msg("Syncing provider cache...")
var mtime time.Time
if c.Providers[storageID] != nil && c.Providers[storageID].Spaces[spaceID] != nil {
mtime = c.Providers[storageID].Spaces[spaceID].Mtime
if time.Now().Before(c.Providers[storageID].Spaces[spaceID].nextSync) {
- log.Debug().Msg("Skipping provider cache sync, it was just recently synced...")
+ span.AddEvent("skip sync")
+ span.SetStatus(codes.Ok, "")
return nil
}
c.Providers[storageID].Spaces[spaceID].nextSync = time.Now().Add(c.ttl)
@@ -207,28 +229,33 @@ func (c *Cache) Sync(ctx context.Context, storageID, spaceID string) error {
info, err := c.storage.Stat(ctx, jsonPath)
if err != nil {
if _, ok := err.(errtypes.NotFound); ok {
- log.Debug().Msg("no json file, nothing to sync")
+ span.AddEvent("no file")
+ span.SetStatus(codes.Ok, "")
return nil // Nothing to sync against
}
if _, ok := err.(*os.PathError); ok {
- log.Debug().Msg("no storage dir, nothing to sync")
+ span.AddEvent("no dir")
+ span.SetStatus(codes.Ok, "")
return nil // Nothing to sync against
}
+ span.SetStatus(codes.Error, fmt.Sprintf("Failed to stat the provider cache: %s", err.Error()))
log.Error().Err(err).Msg("Failed to stat the provider cache")
return err
}
// check mtime of /users/{userid}/created.json
if utils.TSToTime(info.Mtime).After(mtime) {
- log.Debug().Msg("Updating provider cache...")
+ span.AddEvent("updating cache")
// - update cached list of created shares for the user in memory if changed
createdBlob, err := c.storage.SimpleDownload(ctx, jsonPath)
if err != nil {
+ span.SetStatus(codes.Error, fmt.Sprintf("Failed to download the provider cache: %s", err.Error()))
log.Error().Err(err).Msg("Failed to download the provider cache")
return err
}
newShares := &Shares{}
err = json.Unmarshal(createdBlob, newShares)
if err != nil {
+ span.SetStatus(codes.Error, fmt.Sprintf("Failed to unmarshal the provider cache: %s", err.Error()))
log.Error().Err(err).Msg("Failed to unmarshal the provider cache")
return err
}
@@ -236,7 +263,7 @@ func (c *Cache) Sync(ctx context.Context, storageID, spaceID string) error {
c.initializeIfNeeded(storageID, spaceID)
c.Providers[storageID].Spaces[spaceID] = newShares
}
- log.Debug().Msg("Provider cache is up to date")
+ span.SetStatus(codes.Ok, "")
return nil
}
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/receivedsharecache/receivedsharecache.go b/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/receivedsharecache/receivedsharecache.go
index 0693b802c..c58e761d8 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/receivedsharecache/receivedsharecache.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/receivedsharecache/receivedsharecache.go
@@ -21,6 +21,7 @@ package receivedsharecache
import (
"context"
"encoding/json"
+ "fmt"
"path"
"path/filepath"
"time"
@@ -31,8 +32,13 @@ import (
"github.com/cs3org/reva/v2/pkg/errtypes"
"github.com/cs3org/reva/v2/pkg/storage/utils/metadata"
"github.com/cs3org/reva/v2/pkg/utils"
+ "go.opentelemetry.io/otel/attribute"
+ "go.opentelemetry.io/otel/codes"
)
+// name is the Tracer name used to identify this instrumentation library.
+const tracerName = "receivedsharecache"
+
// Cache stores the list of received shares and their states
// It functions as an in-memory cache with a persistence layer
// The storage is sharded by user
@@ -74,6 +80,10 @@ func New(s metadata.Storage, ttl time.Duration) Cache {
// Add adds a new entry to the cache
func (c *Cache) Add(ctx context.Context, userID, spaceID string, rs *collaboration.ReceivedShare) error {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Add")
+ defer span.End()
+ span.SetAttributes(attribute.String("cs3.userid", userID), attribute.String("cs3.spaceid", spaceID))
+
if c.ReceivedSpaces[userID] == nil {
c.ReceivedSpaces[userID] = &Spaces{
Spaces: map[string]*Space{},
@@ -106,13 +116,17 @@ func (c *Cache) Get(userID, spaceID, shareID string) *State {
// Sync updates the in-memory data with the data from the storage if it is outdated
func (c *Cache) Sync(ctx context.Context, userID string) error {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Sync")
+ defer span.End()
+ span.SetAttributes(attribute.String("cs3.userid", userID))
+
log := appctx.GetLogger(ctx).With().Str("userID", userID).Logger()
- log.Debug().Msg("Syncing received share cache...")
var mtime time.Time
if c.ReceivedSpaces[userID] != nil {
if time.Now().Before(c.ReceivedSpaces[userID].nextSync) {
- log.Debug().Msg("Skipping received share cache sync, it was just recently synced...")
+ span.AddEvent("skip sync")
+ span.SetStatus(codes.Ok, "")
return nil
}
c.ReceivedSpaces[userID].nextSync = time.Now().Add(c.ttl)
@@ -123,38 +137,47 @@ func (c *Cache) Sync(ctx context.Context, userID string) error {
}
jsonPath := userJSONPath(userID)
- info, err := c.storage.Stat(ctx, jsonPath)
+ info, err := c.storage.Stat(ctx, jsonPath) // TODO we only need the mtime ... use fieldmask to make the request cheaper
if err != nil {
if _, ok := err.(errtypes.NotFound); ok {
+ span.AddEvent("no file")
+ span.SetStatus(codes.Ok, "")
return nil // Nothing to sync against
}
+ span.SetStatus(codes.Error, fmt.Sprintf("Failed to stat the received share: %s", err.Error()))
log.Error().Err(err).Msg("Failed to stat the received share")
return err
}
// check mtime of /users/{userid}/created.json
if utils.TSToTime(info.Mtime).After(mtime) {
- log.Debug().Msg("Updating received share cache...")
+ span.AddEvent("updating cache")
// - update cached list of created shares for the user in memory if changed
createdBlob, err := c.storage.SimpleDownload(ctx, jsonPath)
if err != nil {
+ span.SetStatus(codes.Error, fmt.Sprintf("Failed to download the received share: %s", err.Error()))
log.Error().Err(err).Msg("Failed to download the received share")
return err
}
newSpaces := &Spaces{}
err = json.Unmarshal(createdBlob, newSpaces)
if err != nil {
+ span.SetStatus(codes.Error, fmt.Sprintf("Failed to unmarshal the received share: %s", err.Error()))
log.Error().Err(err).Msg("Failed to unmarshal the received share")
return err
}
newSpaces.Mtime = utils.TSToTime(info.Mtime)
c.ReceivedSpaces[userID] = newSpaces
}
- log.Debug().Msg("Received share cache is up to date")
+ span.SetStatus(codes.Ok, "")
return nil
}
// Persist persists the data for one user to the storage
func (c *Cache) Persist(ctx context.Context, userID string) error {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Persist")
+ defer span.End()
+ span.SetAttributes(attribute.String("cs3.userid", userID))
+
if c.ReceivedSpaces[userID] == nil {
return nil
}
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/sharecache/sharecache.go b/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/sharecache/sharecache.go
index 7fdd7e392..78ed5aacc 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/sharecache/sharecache.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/sharecache/sharecache.go
@@ -21,6 +21,7 @@ package sharecache
import (
"context"
"encoding/json"
+ "fmt"
"path"
"path/filepath"
"time"
@@ -30,8 +31,13 @@ import (
"github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/shareid"
"github.com/cs3org/reva/v2/pkg/storage/utils/metadata"
"github.com/cs3org/reva/v2/pkg/utils"
+ "go.opentelemetry.io/otel/attribute"
+ "go.opentelemetry.io/otel/codes"
)
+// name is the Tracer name used to identify this instrumentation library.
+const tracerName = "sharecache"
+
// Cache caches the list of share ids for users/groups
// It functions as an in-memory cache with a persistence layer
// The storage is sharded by user/group
@@ -71,6 +77,10 @@ func New(s metadata.Storage, namespace, filename string, ttl time.Duration) Cach
// Add adds a share to the cache
func (c *Cache) Add(ctx context.Context, userid, shareID string) error {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Add")
+ defer span.End()
+ span.SetAttributes(attribute.String("cs3.userid", userid), attribute.String("cs3.shareid", shareID))
+
storageid, spaceid, _ := shareid.Decode(shareID)
ssid := storageid + shareid.IDDelimiter + spaceid
@@ -94,6 +104,10 @@ func (c *Cache) Add(ctx context.Context, userid, shareID string) error {
// Remove removes a share for the given user
func (c *Cache) Remove(ctx context.Context, userid, shareID string) error {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Remove")
+ defer span.End()
+ span.SetAttributes(attribute.String("cs3.userid", userid), attribute.String("cs3.shareid", shareID))
+
storageid, spaceid, _ := shareid.Decode(shareID)
ssid := storageid + shareid.IDDelimiter + spaceid
@@ -133,14 +147,18 @@ func (c *Cache) List(userid string) map[string]SpaceShareIDs {
// Sync updates the in-memory data with the data from the storage if it is outdated
func (c *Cache) Sync(ctx context.Context, userID string) error {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Sync")
+ defer span.End()
+ span.SetAttributes(attribute.String("cs3.userid", userID))
+
log := appctx.GetLogger(ctx).With().Str("userID", userID).Logger()
- log.Debug().Msg("Syncing share cache...")
var mtime time.Time
// - do we have a cached list of created shares for the user in memory?
if usc := c.UserShares[userID]; usc != nil {
if time.Now().Before(c.UserShares[userID].nextSync) {
- log.Debug().Msg("Skipping share cache sync, it was just recently synced...")
+ span.AddEvent("skip sync")
+ span.SetStatus(codes.Ok, "")
return nil
}
c.UserShares[userID].nextSync = time.Now().Add(c.ttl)
@@ -155,35 +173,44 @@ func (c *Cache) Sync(ctx context.Context, userID string) error {
info, err := c.storage.Stat(ctx, userCreatedPath)
if err != nil {
if _, ok := err.(errtypes.NotFound); ok {
+ span.AddEvent("no file")
+ span.SetStatus(codes.Ok, "")
return nil // Nothing to sync against
}
+ span.SetStatus(codes.Error, fmt.Sprintf("Failed to stat the share cache: %s", err.Error()))
log.Error().Err(err).Msg("Failed to stat the share cache")
return err
}
// check mtime of /users/{userid}/created.json
if utils.TSToTime(info.Mtime).After(mtime) {
- log.Debug().Msg("Updating share cache...")
+ span.AddEvent("updating cache")
// - update cached list of created shares for the user in memory if changed
createdBlob, err := c.storage.SimpleDownload(ctx, userCreatedPath)
if err != nil {
+ span.SetStatus(codes.Error, fmt.Sprintf("Failed to download the share cache: %s", err.Error()))
log.Error().Err(err).Msg("Failed to download the share cache")
return err
}
newShareCache := &UserShareCache{}
err = json.Unmarshal(createdBlob, newShareCache)
if err != nil {
+ span.SetStatus(codes.Error, fmt.Sprintf("Failed to unmarshal the share cache: %s", err.Error()))
log.Error().Err(err).Msg("Failed to unmarshal the share cache")
return err
}
newShareCache.Mtime = utils.TSToTime(info.Mtime)
c.UserShares[userID] = newShareCache
}
- log.Debug().Msg("Share cache is up to date")
+ span.SetStatus(codes.Ok, "")
return nil
}
// Persist persists the data for one user/group to the storage
func (c *Cache) Persist(ctx context.Context, userid string) error {
+ ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Persist")
+ defer span.End()
+ span.SetAttributes(attribute.String("cs3.userid", userid))
+
oldMtime := c.UserShares[userid].Mtime
c.UserShares[userid].Mtime = time.Now()
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/cache/filemetadata.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/cache/filemetadata.go
index 9f8828ccc..41053b4f2 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/storage/cache/filemetadata.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/cache/filemetadata.go
@@ -39,5 +39,5 @@ func NewFileMetadataCache(store string, nodes []string, database, table string,
// RemoveMetadata removes a reference from the metadata cache
func (c *fileMetadataCache) RemoveMetadata(path string) error {
- return c.s.Delete(path)
+ return c.Delete(path)
}
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go
index 80278f183..3065a168a 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go
@@ -127,12 +127,13 @@ func NewDefault(m map[string]interface{}, bs tree.Blobstore, es events.Stream) (
microstore.Database(o.IDCache.Database),
microstore.Table(o.IDCache.Table),
))
- permissionsClient, err := pool.GetPermissionsClient(o.PermissionsSVC, pool.WithTLSMode(o.PermTLSMode))
+
+ permissionsSelector, err := pool.PermissionsSelector(o.PermissionsSVC, pool.WithTLSMode(o.PermTLSMode))
if err != nil {
return nil, err
}
- permissions := NewPermissions(node.NewPermissions(lu), permissionsClient)
+ permissions := NewPermissions(node.NewPermissions(lu), permissionsSelector)
return New(o, lu, permissions, tp, es)
}
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node/node.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node/node.go
index 25a8a8e4a..a2332444a 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node/node.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node/node.go
@@ -1039,7 +1039,6 @@ func (n *Node) ReadUserPermissions(ctx context.Context, u *userpb.User) (ap prov
}
AddPermissions(&ap, g.GetPermissions())
case metadata.IsAttrUnset(err):
- err = nil
appctx.GetLogger(ctx).Error().Interface("node", n).Str("grant", grantees[i]).Interface("grantees", grantees).Msg("grant vanished from node after listing")
// continue with next segment
default:
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/spacepermissions.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/spacepermissions.go
index 31043239a..010484a06 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/spacepermissions.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/spacepermissions.go
@@ -8,6 +8,7 @@ import (
v1beta11 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node"
"github.com/cs3org/reva/v2/pkg/utils"
"google.golang.org/grpc"
@@ -25,13 +26,13 @@ type CS3PermissionsClient interface {
// Permissions manages permissions
type Permissions struct {
- item PermissionsChecker // handles item permissions
- space CS3PermissionsClient // handlers space permissions
+ item PermissionsChecker // handles item permissions
+ permissionsSelector pool.Selectable[cs3permissions.PermissionsAPIClient] // handlers space permissions
}
// NewPermissions returns a new Permissions instance
-func NewPermissions(item PermissionsChecker, space CS3PermissionsClient) Permissions {
- return Permissions{item: item, space: space}
+func NewPermissions(item PermissionsChecker, permissionsSelector pool.Selectable[cs3permissions.PermissionsAPIClient]) Permissions {
+ return Permissions{item: item, permissionsSelector: permissionsSelector}
}
// AssemblePermissions is used to assemble file permissions
@@ -96,8 +97,13 @@ func (p Permissions) DeleteAllHomeSpaces(ctx context.Context) bool {
// checkPermission is used to check a users space permissions
func (p Permissions) checkPermission(ctx context.Context, perm string, ref *provider.Reference) bool {
+ permissionsClient, err := p.permissionsSelector.Next()
+ if err != nil {
+ return false
+ }
+
user := ctxpkg.ContextMustGetUser(ctx)
- checkRes, err := p.space.CheckPermission(ctx, &cs3permissions.CheckPermissionRequest{
+ checkRes, err := permissionsClient.CheckPermission(ctx, &cs3permissions.CheckPermissionRequest{
Permission: perm,
SubjectRef: &cs3permissions.SubjectReference{
Spec: &cs3permissions.SubjectReference_UserId{
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/downloader/downloader.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/downloader/downloader.go
index a3795082e..b38ad80b3 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/downloader/downloader.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/downloader/downloader.go
@@ -29,6 +29,7 @@ import (
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/v2/internal/http/services/datagateway"
"github.com/cs3org/reva/v2/pkg/errtypes"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/rhttp"
)
@@ -39,15 +40,15 @@ type Downloader interface {
}
type revaDownloader struct {
- gtw gateway.GatewayAPIClient
- httpClient *http.Client
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
+ httpClient *http.Client
}
// NewDownloader creates a Downloader from the reva gateway
-func NewDownloader(gtw gateway.GatewayAPIClient, options ...rhttp.Option) Downloader {
+func NewDownloader(gatewaySelector pool.Selectable[gateway.GatewayAPIClient], options ...rhttp.Option) Downloader {
return &revaDownloader{
- gtw: gtw,
- httpClient: rhttp.GetHTTPClient(options...),
+ gatewaySelector: gatewaySelector,
+ httpClient: rhttp.GetHTTPClient(options...),
}
}
@@ -62,7 +63,11 @@ func getDownloadProtocol(protocols []*gateway.FileDownloadProtocol, prot string)
// Download downloads a resource given the path to the dst Writer
func (r *revaDownloader) Download(ctx context.Context, id *provider.ResourceId, dst io.Writer) error {
- downResp, err := r.gtw.InitiateFileDownload(ctx, &provider.InitiateFileDownloadRequest{
+ gatewayClient, err := r.gatewaySelector.Next()
+ if err != nil {
+ return err
+ }
+ downResp, err := gatewayClient.InitiateFileDownload(ctx, &provider.InitiateFileDownloadRequest{
Ref: &provider.Reference{
ResourceId: id,
Path: ".",
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/metadata/cs3.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/metadata/cs3.go
index 76cff96d1..a536f9284 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/metadata/cs3.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/metadata/cs3.go
@@ -37,9 +37,17 @@ import (
"github.com/cs3org/reva/v2/pkg/rgrpc/status"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/utils"
+ "go.opentelemetry.io/otel"
+ "go.opentelemetry.io/otel/trace"
"google.golang.org/grpc/metadata"
)
+var tracer trace.Tracer
+
+func init() {
+ tracer = otel.Tracer("github.com/cs3org/reva/pkg/storage/utils/metadata")
+}
+
// CS3 represents a metadata storage with a cs3 storage backend
type CS3 struct {
providerAddr string
@@ -75,6 +83,9 @@ func (cs3 *CS3) Backend() string {
// Init creates the metadata space
func (cs3 *CS3) Init(ctx context.Context, spaceid string) (err error) {
+ ctx, span := tracer.Start(ctx, "Init")
+ defer span.End()
+
client, err := cs3.providerClient()
if err != nil {
return err
@@ -114,6 +125,9 @@ func (cs3 *CS3) Init(ctx context.Context, spaceid string) (err error) {
// SimpleUpload uploads a file to the metadata storage
func (cs3 *CS3) SimpleUpload(ctx context.Context, uploadpath string, content []byte) error {
+ ctx, span := tracer.Start(ctx, "SimpleUpload")
+ defer span.End()
+
return cs3.Upload(ctx, UploadRequest{
Path: uploadpath,
Content: content,
@@ -122,6 +136,9 @@ func (cs3 *CS3) SimpleUpload(ctx context.Context, uploadpath string, content []b
// Upload uploads a file to the metadata storage
func (cs3 *CS3) Upload(ctx context.Context, req UploadRequest) error {
+ ctx, span := tracer.Start(ctx, "Upload")
+ defer span.End()
+
client, err := cs3.providerClient()
if err != nil {
return err
@@ -185,6 +202,9 @@ func (cs3 *CS3) Upload(ctx context.Context, req UploadRequest) error {
// Stat returns the metadata for the given path
func (cs3 *CS3) Stat(ctx context.Context, path string) (*provider.ResourceInfo, error) {
+ ctx, span := tracer.Start(ctx, "Stat")
+ defer span.End()
+
client, err := cs3.providerClient()
if err != nil {
return nil, err
@@ -214,6 +234,9 @@ func (cs3 *CS3) Stat(ctx context.Context, path string) (*provider.ResourceInfo,
// SimpleDownload reads a file from the metadata storage
func (cs3 *CS3) SimpleDownload(ctx context.Context, downloadpath string) (content []byte, err error) {
+ ctx, span := tracer.Start(ctx, "SimpleDownload")
+ defer span.End()
+
client, err := cs3.providerClient()
if err != nil {
return nil, err
@@ -277,6 +300,9 @@ func (cs3 *CS3) SimpleDownload(ctx context.Context, downloadpath string) (conten
// Delete deletes a path
func (cs3 *CS3) Delete(ctx context.Context, path string) error {
+ ctx, span := tracer.Start(ctx, "Delete")
+ defer span.End()
+
client, err := cs3.providerClient()
if err != nil {
return err
@@ -304,6 +330,9 @@ func (cs3 *CS3) Delete(ctx context.Context, path string) error {
// ReadDir returns the entries in a given directory
func (cs3 *CS3) ReadDir(ctx context.Context, path string) ([]string, error) {
+ ctx, span := tracer.Start(ctx, "ReadDir")
+ defer span.End()
+
infos, err := cs3.ListDir(ctx, path)
if err != nil {
return nil, err
@@ -318,6 +347,9 @@ func (cs3 *CS3) ReadDir(ctx context.Context, path string) ([]string, error) {
// ListDir returns a list of ResourceInfos for the entries in a given directory
func (cs3 *CS3) ListDir(ctx context.Context, path string) ([]*provider.ResourceInfo, error) {
+ ctx, span := tracer.Start(ctx, "ListDir")
+ defer span.End()
+
client, err := cs3.providerClient()
if err != nil {
return nil, err
@@ -347,6 +379,9 @@ func (cs3 *CS3) ListDir(ctx context.Context, path string) ([]*provider.ResourceI
// MakeDirIfNotExist will create a root node in the metadata storage. Requires an authenticated context.
func (cs3 *CS3) MakeDirIfNotExist(ctx context.Context, folder string) error {
+ ctx, span := tracer.Start(ctx, "MakeDirIfNotExist")
+ defer span.End()
+
client, err := cs3.providerClient()
if err != nil {
return err
@@ -395,6 +430,9 @@ func (cs3 *CS3) MakeDirIfNotExist(ctx context.Context, folder string) error {
// CreateSymlink creates a symlink
func (cs3 *CS3) CreateSymlink(ctx context.Context, oldname, newname string) error {
+ ctx, span := tracer.Start(ctx, "CreateSymlink")
+ defer span.End()
+
if _, err := cs3.ResolveSymlink(ctx, newname); err == nil {
return os.ErrExist
}
@@ -404,6 +442,9 @@ func (cs3 *CS3) CreateSymlink(ctx context.Context, oldname, newname string) erro
// ResolveSymlink resolves a symlink
func (cs3 *CS3) ResolveSymlink(ctx context.Context, name string) (string, error) {
+ ctx, span := tracer.Start(ctx, "ResolveSymlink")
+ defer span.End()
+
b, err := cs3.SimpleDownload(ctx, name)
if err != nil {
if errors.Is(err, errtypes.NotFound("")) {
@@ -420,12 +461,17 @@ func (cs3 *CS3) providerClient() (provider.ProviderAPIClient, error) {
}
func (cs3 *CS3) getAuthContext(ctx context.Context) (context.Context, error) {
+ // we need to start a new context to get rid of an existing x-access-token in the outgoing context
+ authCtx := context.Background()
+ authCtx, span := tracer.Start(authCtx, "getAuthContext", trace.WithLinks(trace.LinkFromContext(ctx)))
+ defer span.End()
+
client, err := pool.GetGatewayServiceClient(cs3.gatewayAddr)
if err != nil {
return nil, err
}
- authCtx := ctxpkg.ContextSetUser(context.Background(), cs3.serviceUser)
+ authCtx = ctxpkg.ContextSetUser(authCtx, cs3.serviceUser)
authRes, err := client.Authenticate(authCtx, &gateway.AuthenticateRequest{
Type: "machine",
ClientId: "userid:" + cs3.serviceUser.Id.OpaqueId,
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/walker/walker.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/walker/walker.go
index ab3c4ff59..acca4869e 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/walker/walker.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/walker/walker.go
@@ -27,6 +27,7 @@ import (
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
"github.com/cs3org/reva/v2/pkg/errtypes"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
)
// WalkFunc is the type of function called by Walk to visit each file or directory
@@ -46,12 +47,12 @@ type Walker interface {
}
type revaWalker struct {
- gtw gateway.GatewayAPIClient
+ gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
}
// NewWalker creates a Walker object that uses the reva gateway
-func NewWalker(gtw gateway.GatewayAPIClient) Walker {
- return &revaWalker{gtw: gtw}
+func NewWalker(gatewaySelector pool.Selectable[gateway.GatewayAPIClient]) Walker {
+ return &revaWalker{gatewaySelector: gatewaySelector}
}
// Walk walks the file tree rooted at root, calling fn for each file or folder in the tree, including the root.
@@ -95,7 +96,11 @@ func (r *revaWalker) walkRecursively(ctx context.Context, wd string, info *provi
}
func (r *revaWalker) readDir(ctx context.Context, id *provider.ResourceId) ([]*provider.ResourceInfo, error) {
- resp, err := r.gtw.ListContainer(ctx, &provider.ListContainerRequest{Ref: &provider.Reference{ResourceId: id, Path: "."}})
+ gatewayClient, err := r.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ resp, err := gatewayClient.ListContainer(ctx, &provider.ListContainerRequest{Ref: &provider.Reference{ResourceId: id, Path: "."}})
switch {
case err != nil:
@@ -108,7 +113,11 @@ func (r *revaWalker) readDir(ctx context.Context, id *provider.ResourceId) ([]*p
}
func (r *revaWalker) stat(ctx context.Context, id *provider.ResourceId) (*provider.ResourceInfo, error) {
- resp, err := r.gtw.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{ResourceId: id, Path: "."}})
+ gatewayClient, err := r.gatewaySelector.Next()
+ if err != nil {
+ return nil, err
+ }
+ resp, err := gatewayClient.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{ResourceId: id, Path: "."}})
switch {
case err != nil:
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/utils/utils.go b/vendor/github.com/cs3org/reva/v2/pkg/utils/utils.go
index 8a4fb54be..c67c50dbf 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/utils/utils.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/utils/utils.go
@@ -39,8 +39,6 @@ import (
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
- "github.com/cs3org/reva/v2/pkg/registry"
- "github.com/cs3org/reva/v2/pkg/registry/memory"
"github.com/golang/protobuf/proto"
"google.golang.org/protobuf/encoding/protojson"
)
@@ -49,9 +47,6 @@ var (
matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)")
matchAllCap = regexp.MustCompile("([a-z0-9])([A-Z])")
matchEmail = regexp.MustCompile(`^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$`)
- // GlobalRegistry configures a service registry globally accessible. It defaults to a memory registry. The usage of
- // globals is not encouraged, and this is a workaround until the PR is out of a draft state.
- GlobalRegistry registry.Registry = memory.New(map[string]interface{}{})
// ShareStorageProviderID is the provider id used by the sharestorageprovider
ShareStorageProviderID = "a0ca6a90-a365-4782-871e-d44447bbc668"
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 2102e482d..19438ac00 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -352,8 +352,8 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1
github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1
github.com/cs3org/go-cs3apis/cs3/tx/v1beta1
github.com/cs3org/go-cs3apis/cs3/types/v1beta1
-# github.com/cs3org/reva/v2 v2.14.0
-## explicit; go 1.19
+# github.com/cs3org/reva/v2 v2.14.1-0.20230607220921-238a03c2f795
+## explicit; go 1.20
github.com/cs3org/reva/v2/cmd/revad/internal/grace
github.com/cs3org/reva/v2/cmd/revad/runtime
github.com/cs3org/reva/v2/internal/grpc/interceptors/appctx
@@ -568,7 +568,6 @@ github.com/cs3org/reva/v2/pkg/publicshare/manager/memory
github.com/cs3org/reva/v2/pkg/publicshare/manager/owncloudsql
github.com/cs3org/reva/v2/pkg/publicshare/manager/registry
github.com/cs3org/reva/v2/pkg/registry
-github.com/cs3org/reva/v2/pkg/registry/memory
github.com/cs3org/reva/v2/pkg/rgrpc
github.com/cs3org/reva/v2/pkg/rgrpc/status
github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool