github.com/cs3org/reva/v2@v2.27.7/internal/grpc/services/storageregistry/storageregistry.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 storageregistry 20 21 import ( 22 "context" 23 "encoding/json" 24 "encoding/xml" 25 "fmt" 26 27 "github.com/BurntSushi/toml" 28 provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" 29 registrypb "github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1" 30 typespb "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" 31 "github.com/cs3org/reva/v2/pkg/errtypes" 32 "github.com/cs3org/reva/v2/pkg/rgrpc" 33 "github.com/cs3org/reva/v2/pkg/rgrpc/status" 34 sdk "github.com/cs3org/reva/v2/pkg/sdk/common" 35 "github.com/cs3org/reva/v2/pkg/storage" 36 "github.com/cs3org/reva/v2/pkg/storage/registry/registry" 37 "github.com/mitchellh/mapstructure" 38 "github.com/rs/zerolog" 39 "google.golang.org/grpc" 40 ) 41 42 func init() { 43 rgrpc.Register("storageregistry", New) 44 } 45 46 type service struct { 47 reg storage.Registry 48 } 49 50 func (s *service) Close() error { 51 return nil 52 } 53 54 func (s *service) UnprotectedEndpoints() []string { 55 return []string{} 56 } 57 58 func (s *service) Register(ss *grpc.Server) { 59 registrypb.RegisterRegistryAPIServer(ss, s) 60 } 61 62 type config struct { 63 Driver string `mapstructure:"driver"` 64 Drivers map[string]map[string]interface{} `mapstructure:"drivers"` 65 } 66 67 func (c *config) init() { 68 if c.Driver == "" { 69 c.Driver = "static" 70 } 71 } 72 73 // New creates a new StorageBrokerService 74 func New(m map[string]interface{}, ss *grpc.Server, _ *zerolog.Logger) (rgrpc.Service, error) { 75 c, err := parseConfig(m) 76 if err != nil { 77 return nil, err 78 } 79 80 c.init() 81 82 reg, err := getRegistry(c) 83 if err != nil { 84 return nil, err 85 } 86 87 service := &service{ 88 reg: reg, 89 } 90 91 return service, nil 92 } 93 94 func parseConfig(m map[string]interface{}) (*config, error) { 95 c := &config{} 96 if err := mapstructure.Decode(m, c); err != nil { 97 return nil, err 98 } 99 return c, nil 100 } 101 102 func getRegistry(c *config) (storage.Registry, error) { 103 if f, ok := registry.NewFuncs[c.Driver]; ok { 104 return f(c.Drivers[c.Driver]) 105 } 106 return nil, errtypes.NotFound("driver not found: " + c.Driver) 107 } 108 109 func (s *service) ListStorageProviders(ctx context.Context, req *registrypb.ListStorageProvidersRequest) (*registrypb.ListStorageProvidersResponse, error) { 110 pinfos, err := s.reg.ListProviders(ctx, sdk.DecodeOpaqueMap(req.Opaque)) 111 if err != nil { 112 return ®istrypb.ListStorageProvidersResponse{ 113 Status: status.NewInternal(ctx, "error getting list of storage providers"), 114 }, nil 115 } 116 117 res := ®istrypb.ListStorageProvidersResponse{ 118 Status: status.NewOK(ctx), 119 Providers: pinfos, 120 } 121 return res, nil 122 } 123 124 func (s *service) GetStorageProviders(ctx context.Context, req *registrypb.GetStorageProvidersRequest) (*registrypb.GetStorageProvidersResponse, error) { 125 space, err := decodeSpace(req.Opaque) 126 if err != nil { 127 return ®istrypb.GetStorageProvidersResponse{ 128 Status: status.NewInvalid(ctx, err.Error()), 129 }, nil 130 } 131 p, err := s.reg.GetProvider(ctx, space) 132 if err != nil { 133 switch err.(type) { 134 case errtypes.IsNotFound: 135 return ®istrypb.GetStorageProvidersResponse{ 136 Status: status.NewNotFound(ctx, err.Error()), 137 }, nil 138 default: 139 return ®istrypb.GetStorageProvidersResponse{ 140 Status: status.NewInternal(ctx, "error finding storage provider"), 141 }, nil 142 } 143 } 144 145 res := ®istrypb.GetStorageProvidersResponse{ 146 Status: status.NewOK(ctx), 147 Providers: []*registrypb.ProviderInfo{p}, 148 } 149 return res, nil 150 } 151 152 func decodeSpace(o *typespb.Opaque) (*provider.StorageSpace, error) { 153 if entry, ok := o.Map["space"]; ok { 154 var unmarshal func([]byte, interface{}) error 155 switch entry.Decoder { 156 case "json": 157 unmarshal = json.Unmarshal 158 case "toml": 159 unmarshal = toml.Unmarshal 160 case "xml": 161 unmarshal = xml.Unmarshal 162 } 163 164 space := &provider.StorageSpace{} 165 return space, unmarshal(entry.Value, space) 166 } 167 168 return nil, fmt.Errorf("missing space in opaque property") 169 } 170 171 func (s *service) GetHome(ctx context.Context, req *registrypb.GetHomeRequest) (*registrypb.GetHomeResponse, error) { 172 res := ®istrypb.GetHomeResponse{ 173 Status: status.NewUnimplemented(ctx, nil, "getHome is no longer used. use List"), 174 } 175 return res, nil 176 177 }