github.com/cs3org/reva/v2@v2.27.7/pkg/rgrpc/todo/pool/selector.go (about)

     1  // Copyright 2018-2021 CERN
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  
    19  package pool
    20  
    21  import (
    22  	"fmt"
    23  	"strings"
    24  	"sync"
    25  
    26  	appProvider "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1"
    27  	appRegistry "github.com/cs3org/go-cs3apis/cs3/app/registry/v1beta1"
    28  	authApplication "github.com/cs3org/go-cs3apis/cs3/auth/applications/v1beta1"
    29  	authProvider "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
    30  	authRegistry "github.com/cs3org/go-cs3apis/cs3/auth/registry/v1beta1"
    31  	gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
    32  	identityGroup "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
    33  	identityUser "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
    34  	ocmCore "github.com/cs3org/go-cs3apis/cs3/ocm/core/v1beta1"
    35  	ocmInvite "github.com/cs3org/go-cs3apis/cs3/ocm/invite/v1beta1"
    36  	ocmProvider "github.com/cs3org/go-cs3apis/cs3/ocm/provider/v1beta1"
    37  	permissions "github.com/cs3org/go-cs3apis/cs3/permissions/v1beta1"
    38  	preferences "github.com/cs3org/go-cs3apis/cs3/preferences/v1beta1"
    39  	sharingCollaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
    40  	sharingLink "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
    41  	sharingOCM "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
    42  	storageProvider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
    43  	storageRegistry "github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1"
    44  	tx "github.com/cs3org/go-cs3apis/cs3/tx/v1beta1"
    45  	"github.com/cs3org/reva/v2/pkg/registry"
    46  	"github.com/pkg/errors"
    47  	"github.com/sercand/kuberesolver/v5"
    48  	"google.golang.org/grpc"
    49  )
    50  
    51  func init() {
    52  	// grpc go resolver.Register must only be called during initialization time (i.e. in
    53  	// an init() function), and is not thread-safe.
    54  	kuberesolver.RegisterInCluster()
    55  }
    56  
    57  type Selectable[T any] interface {
    58  	Next(opts ...Option) (T, error)
    59  }
    60  
    61  var selectors sync.Map
    62  
    63  // RemoveSelector removes given id from the selectors map.
    64  func RemoveSelector(id string) {
    65  	selectors.Delete(id)
    66  }
    67  
    68  func GetSelector[T any](k string, id string, f func(cc grpc.ClientConnInterface) T, options ...Option) *Selector[T] {
    69  	existingSelector, ok := selectors.Load(k + id)
    70  	if ok {
    71  		return existingSelector.(*Selector[T])
    72  	}
    73  
    74  	newSelector := &Selector[T]{
    75  		id:            id,
    76  		clientFactory: f,
    77  		options:       options,
    78  	}
    79  
    80  	selectors.Store(k+id, newSelector)
    81  
    82  	return newSelector
    83  }
    84  
    85  type Selector[T any] struct {
    86  	id            string
    87  	clientFactory func(cc grpc.ClientConnInterface) T
    88  	clientMap     sync.Map
    89  	options       []Option
    90  }
    91  
    92  func (s *Selector[T]) Next(opts ...Option) (T, error) {
    93  	options := ClientOptions{
    94  		registry: registry.GetRegistry(),
    95  	}
    96  
    97  	allOpts := append([]Option{}, s.options...)
    98  	allOpts = append(allOpts, opts...)
    99  
   100  	for _, opt := range allOpts {
   101  		opt(&options)
   102  	}
   103  
   104  	target := s.id
   105  	// if the target is given as a recognized gRPC URI, skip registry lookup
   106  	// see https://github.com/grpc/grpc/blob/master/doc/naming.md#name-syntax
   107  	prefix := strings.SplitN(s.id, ":", 2)[0]
   108  	switch {
   109  	case prefix == "dns":
   110  		fallthrough
   111  	case prefix == "unix":
   112  		fallthrough
   113  	case prefix == "kubernetes":
   114  		// use target as is and skip registry lookup
   115  	case options.registry != nil:
   116  		// use service registry to look up address
   117  		services, err := options.registry.GetService(s.id)
   118  		if err != nil {
   119  			return *new(T), fmt.Errorf("%s: %w", s.id, err)
   120  		}
   121  
   122  		nodeAddress, err := registry.GetNodeAddress(services)
   123  		if err != nil {
   124  			return *new(T), fmt.Errorf("%s: %w", s.id, err)
   125  		}
   126  		target = nodeAddress
   127  	default:
   128  		// if no registry is available, use the target as is
   129  	}
   130  
   131  	existingClient, ok := s.clientMap.Load(target)
   132  	if ok {
   133  		return existingClient.(T), nil
   134  	}
   135  
   136  	conn, err := NewConn(target, allOpts...)
   137  	if err != nil {
   138  		return *new(T), errors.Wrap(err, fmt.Sprintf("could not create connection for %s to %s", s.id, target))
   139  	}
   140  
   141  	newClient := s.clientFactory(conn)
   142  	s.clientMap.Store(target, newClient)
   143  
   144  	return newClient, nil
   145  }
   146  
   147  // GatewaySelector returns a Selector[gateway.GatewayAPIClient].
   148  func GatewaySelector(id string, options ...Option) (*Selector[gateway.GatewayAPIClient], error) {
   149  	return GetSelector[gateway.GatewayAPIClient](
   150  		"GatewaySelector",
   151  		id,
   152  		gateway.NewGatewayAPIClient,
   153  		options...,
   154  	), nil
   155  }
   156  
   157  // IdentityUserSelector returns a Selector[identityUser.UserAPIClient].
   158  func IdentityUserSelector(id string, options ...Option) (*Selector[identityUser.UserAPIClient], error) {
   159  	return GetSelector[identityUser.UserAPIClient](
   160  		"IdentityUserSelector",
   161  		id,
   162  		identityUser.NewUserAPIClient,
   163  		options...,
   164  	), nil
   165  }
   166  
   167  // IdentityGroupSelector returns a Selector[identityGroup.GroupAPIClient].
   168  func IdentityGroupSelector(id string, options ...Option) (*Selector[identityGroup.GroupAPIClient], error) {
   169  	return GetSelector[identityGroup.GroupAPIClient](
   170  		"IdentityGroupSelector",
   171  		id,
   172  		identityGroup.NewGroupAPIClient,
   173  		options...,
   174  	), nil
   175  }
   176  
   177  // StorageProviderSelector returns a Selector[storageProvider.ProviderAPIClient].
   178  func StorageProviderSelector(id string, options ...Option) (*Selector[storageProvider.ProviderAPIClient], error) {
   179  	return GetSelector[storageProvider.ProviderAPIClient](
   180  		"StorageProviderSelector",
   181  		id,
   182  		storageProvider.NewProviderAPIClient,
   183  		options...,
   184  	), nil
   185  }
   186  
   187  // SpacesProviderSelector returns a Selector[storageProvider.SpacesAPIClient].
   188  func SpacesProviderSelector(id string, options ...Option) (*Selector[storageProvider.SpacesAPIClient], error) {
   189  	return GetSelector[storageProvider.SpacesAPIClient](
   190  		"SpacesProviderSelector",
   191  		id,
   192  		storageProvider.NewSpacesAPIClient,
   193  		options...,
   194  	), nil
   195  }
   196  
   197  // AuthRegistrySelector returns a Selector[authRegistry.RegistryAPIClient].
   198  func AuthRegistrySelector(id string, options ...Option) (*Selector[authRegistry.RegistryAPIClient], error) {
   199  	return GetSelector[authRegistry.RegistryAPIClient](
   200  		"AuthRegistrySelector",
   201  		id,
   202  		authRegistry.NewRegistryAPIClient,
   203  		options...,
   204  	), nil
   205  }
   206  
   207  // AuthProviderSelector returns a Selector[authProvider.RegistryAPIClient].
   208  func AuthProviderSelector(id string, options ...Option) (*Selector[authProvider.ProviderAPIClient], error) {
   209  	return GetSelector[authProvider.ProviderAPIClient](
   210  		"AuthProviderSelector",
   211  		id,
   212  		authProvider.NewProviderAPIClient,
   213  		options...,
   214  	), nil
   215  }
   216  
   217  // AuthApplicationSelector returns a Selector[authApplication.ApplicationsAPIClient].
   218  func AuthApplicationSelector(id string, options ...Option) (*Selector[authApplication.ApplicationsAPIClient], error) {
   219  	return GetSelector[authApplication.ApplicationsAPIClient](
   220  		"AuthApplicationSelector",
   221  		id,
   222  		authApplication.NewApplicationsAPIClient,
   223  		options...,
   224  	), nil
   225  }
   226  
   227  // SharingCollaborationSelector returns a Selector[sharingCollaboration.ApplicationsAPIClient].
   228  func SharingCollaborationSelector(id string, options ...Option) (*Selector[sharingCollaboration.CollaborationAPIClient], error) {
   229  	return GetSelector[sharingCollaboration.CollaborationAPIClient](
   230  		"SharingCollaborationSelector",
   231  		id,
   232  		sharingCollaboration.NewCollaborationAPIClient,
   233  		options...,
   234  	), nil
   235  }
   236  
   237  // SharingOCMSelector returns a Selector[sharingOCM.OcmAPIClient].
   238  func SharingOCMSelector(id string, options ...Option) (*Selector[sharingOCM.OcmAPIClient], error) {
   239  	return GetSelector[sharingOCM.OcmAPIClient](
   240  		"SharingOCMSelector",
   241  		id,
   242  		sharingOCM.NewOcmAPIClient,
   243  		options...,
   244  	), nil
   245  }
   246  
   247  // SharingLinkSelector returns a Selector[sharingLink.LinkAPIClient].
   248  func SharingLinkSelector(id string, options ...Option) (*Selector[sharingLink.LinkAPIClient], error) {
   249  	return GetSelector[sharingLink.LinkAPIClient](
   250  		"SharingLinkSelector",
   251  		id,
   252  		sharingLink.NewLinkAPIClient,
   253  		options...,
   254  	), nil
   255  }
   256  
   257  // PreferencesSelector returns a Selector[preferences.PreferencesAPIClient].
   258  func PreferencesSelector(id string, options ...Option) (*Selector[preferences.PreferencesAPIClient], error) {
   259  	return GetSelector[preferences.PreferencesAPIClient](
   260  		"PreferencesSelector",
   261  		id,
   262  		preferences.NewPreferencesAPIClient,
   263  		options...,
   264  	), nil
   265  }
   266  
   267  // PermissionsSelector returns a Selector[permissions.PermissionsAPIClient].
   268  func PermissionsSelector(id string, options ...Option) (*Selector[permissions.PermissionsAPIClient], error) {
   269  	return GetSelector[permissions.PermissionsAPIClient](
   270  		"PermissionsSelector",
   271  		id,
   272  		permissions.NewPermissionsAPIClient,
   273  		options...,
   274  	), nil
   275  }
   276  
   277  // AppRegistrySelector returns a Selector[appRegistry.RegistryAPIClient].
   278  func AppRegistrySelector(id string, options ...Option) (*Selector[appRegistry.RegistryAPIClient], error) {
   279  	return GetSelector[appRegistry.RegistryAPIClient](
   280  		"AppRegistrySelector",
   281  		id,
   282  		appRegistry.NewRegistryAPIClient,
   283  		options...,
   284  	), nil
   285  }
   286  
   287  // AppProviderSelector returns a Selector[appProvider.ProviderAPIClient].
   288  func AppProviderSelector(id string, options ...Option) (*Selector[appProvider.ProviderAPIClient], error) {
   289  	return GetSelector[appProvider.ProviderAPIClient](
   290  		"AppProviderSelector",
   291  		id,
   292  		appProvider.NewProviderAPIClient,
   293  		options...,
   294  	), nil
   295  }
   296  
   297  // StorageRegistrySelector returns a Selector[storageRegistry.RegistryAPIClient].
   298  func StorageRegistrySelector(id string, options ...Option) (*Selector[storageRegistry.RegistryAPIClient], error) {
   299  	return GetSelector[storageRegistry.RegistryAPIClient](
   300  		"StorageRegistrySelector",
   301  		id,
   302  		storageRegistry.NewRegistryAPIClient,
   303  		options...,
   304  	), nil
   305  }
   306  
   307  // OCMProviderSelector returns a Selector[storageRegistry.RegistryAPIClient].
   308  func OCMProviderSelector(id string, options ...Option) (*Selector[ocmProvider.ProviderAPIClient], error) {
   309  	return GetSelector[ocmProvider.ProviderAPIClient](
   310  		"OCMProviderSelector",
   311  		id,
   312  		ocmProvider.NewProviderAPIClient,
   313  		options...,
   314  	), nil
   315  }
   316  
   317  // OCMCoreSelector returns a Selector[ocmCore.OcmCoreAPIClient].
   318  func OCMCoreSelector(id string, options ...Option) (*Selector[ocmCore.OcmCoreAPIClient], error) {
   319  	return GetSelector[ocmCore.OcmCoreAPIClient](
   320  		"OCMCoreSelector",
   321  		id,
   322  		ocmCore.NewOcmCoreAPIClient,
   323  		options...,
   324  	), nil
   325  }
   326  
   327  // OCMInviteSelector returns a Selector[ocmInvite.InviteAPIClient].
   328  func OCMInviteSelector(id string, options ...Option) (*Selector[ocmInvite.InviteAPIClient], error) {
   329  	return GetSelector[ocmInvite.InviteAPIClient](
   330  		"OCMInviteSelector",
   331  		id,
   332  		ocmInvite.NewInviteAPIClient,
   333  		options...,
   334  	), nil
   335  }
   336  
   337  // TXSelector returns a Selector[tx.TxAPIClient].
   338  func TXSelector(id string, options ...Option) (*Selector[tx.TxAPIClient], error) {
   339  	return GetSelector[tx.TxAPIClient](
   340  		"TXSelector",
   341  		id,
   342  		tx.NewTxAPIClient,
   343  		options...,
   344  	), nil
   345  }