@@ -115,37 +115,130 @@ func (s *svc) CreateStorageSpace(ctx context.Context, req *provider.CreateStorag
115
115
116
116
func (s * svc ) ListStorageSpaces (ctx context.Context , req * provider.ListStorageSpacesRequest ) (* provider.ListStorageSpacesResponse , error ) {
117
117
log := appctx .GetLogger (ctx )
118
- // TODO: needs to be fixed
119
118
var id * provider.StorageSpaceId
120
119
for _ , f := range req .Filters {
121
120
if f .Type == provider .ListStorageSpacesRequest_Filter_TYPE_ID {
122
121
id = f .GetId ()
123
122
}
124
123
}
125
- parts := strings .SplitN (id .OpaqueId , "!" , 2 )
126
- if len (parts ) != 2 {
124
+
125
+ var (
126
+ providers []* registry.ProviderInfo
127
+ err error
128
+ )
129
+ c , err := pool .GetStorageRegistryClient (s .c .StorageRegistryEndpoint )
130
+ if err != nil {
131
+ return nil , errors .Wrap (err , "gateway: error getting storage registry client" )
132
+ }
133
+
134
+ if id != nil {
135
+ // query that specific storage provider
136
+ parts := strings .SplitN (id .OpaqueId , "!" , 2 )
137
+ if len (parts ) != 2 {
138
+ return & provider.ListStorageSpacesResponse {
139
+ Status : status .NewInvalidArg (ctx , "space id must be separated by !" ),
140
+ }, nil
141
+ }
142
+ res , err := c .GetStorageProviders (ctx , & registry.GetStorageProvidersRequest {
143
+ Ref : & provider.Reference {ResourceId : & provider.ResourceId {
144
+ StorageId : parts [0 ], // FIXME REFERENCE the StorageSpaceId is a storageid + an opaqueid
145
+ OpaqueId : parts [1 ],
146
+ }},
147
+ })
148
+ if err != nil {
149
+ return & provider.ListStorageSpacesResponse {
150
+ Status : status .NewStatusFromErrType (ctx , "ListStorageSpaces filters: req " + req .String (), err ),
151
+ }, nil
152
+ }
153
+ if res .Status .Code != rpc .Code_CODE_OK {
154
+ return & provider.ListStorageSpacesResponse {
155
+ Status : res .Status ,
156
+ }, nil
157
+ }
158
+ providers = res .Providers
159
+ } else {
160
+ // get list of all storage providers
161
+ res , err := c .ListStorageProviders (ctx , & registry.ListStorageProvidersRequest {})
162
+
163
+ if err != nil {
164
+ return & provider.ListStorageSpacesResponse {
165
+ Status : status .NewStatusFromErrType (ctx , "error listing providers" , err ),
166
+ }, nil
167
+ }
168
+ if res .Status .Code != rpc .Code_CODE_OK {
169
+ return & provider.ListStorageSpacesResponse {
170
+ Status : res .Status ,
171
+ }, nil
172
+ }
173
+
174
+ providers = make ([]* registry.ProviderInfo , 0 , len (res .Providers ))
175
+ // FIXME filter only providers that have an id set ... currently none have?
176
+ // bug? only ProviderPath is set
177
+ for i := range res .Providers {
178
+ // use only providers whose path does not start with a /?
179
+ if strings .HasPrefix (res .Providers [i ].ProviderPath , "/" ) {
180
+ continue
181
+ }
182
+ providers = append (providers , res .Providers [i ])
183
+ }
184
+ }
185
+
186
+ spacesFromProviders := make ([][]* provider.StorageSpace , len (providers ))
187
+ errors := make ([]error , len (providers ))
188
+
189
+ var wg sync.WaitGroup
190
+ for i , p := range providers {
191
+ wg .Add (1 )
192
+ go s .listStorageSpacesOnProvider (ctx , req , & spacesFromProviders [i ], p , & errors [i ], & wg )
193
+ }
194
+ wg .Wait ()
195
+
196
+ uniqueSpaces := map [string ]* provider.StorageSpace {}
197
+ for i := range providers {
198
+ if errors [i ] != nil {
199
+ if len (providers ) > 1 {
200
+ log .Debug ().Err (errors [i ]).Msg ("skipping provider" )
201
+ continue
202
+ }
203
+ return & provider.ListStorageSpacesResponse {
204
+ Status : status .NewStatusFromErrType (ctx , "error listing space" , errors [i ]),
205
+ }, nil
206
+ }
207
+ for j := range spacesFromProviders [i ] {
208
+ uniqueSpaces [spacesFromProviders [i ][j ].Id .OpaqueId ] = spacesFromProviders [i ][j ]
209
+ }
210
+ }
211
+ spaces := make ([]* provider.StorageSpace , 0 , len (uniqueSpaces ))
212
+ for spaceID := range uniqueSpaces {
213
+ spaces = append (spaces , uniqueSpaces [spaceID ])
214
+ }
215
+ if len (spaces ) == 0 {
127
216
return & provider.ListStorageSpacesResponse {
128
- Status : status .NewInvalidArg (ctx , "space id must be separated by ! " ),
217
+ Status : status .NewNotFound (ctx , "space not found " ),
129
218
}, nil
130
219
}
131
- c , err := s .find (ctx , & provider.Reference {ResourceId : & provider.ResourceId {
132
- StorageId : parts [0 ], // FIXME REFERENCE the StorageSpaceId is a storageid + a opaqueid
133
- OpaqueId : parts [1 ],
134
- }})
220
+
221
+ return & provider.ListStorageSpacesResponse {
222
+ Status : status .NewOK (ctx ),
223
+ StorageSpaces : spaces ,
224
+ }, nil
225
+ }
226
+
227
+ func (s * svc ) listStorageSpacesOnProvider (ctx context.Context , req * provider.ListStorageSpacesRequest , res * []* provider.StorageSpace , p * registry.ProviderInfo , e * error , wg * sync.WaitGroup ) {
228
+ defer wg .Done ()
229
+ c , err := s .getStorageProviderClient (ctx , p )
135
230
if err != nil {
136
- return & provider.ListStorageSpacesResponse {
137
- Status : status .NewStatusFromErrType (ctx , "error finding path" , err ),
138
- }, nil
231
+ * e = errors .Wrap (err , "error connecting to storage provider=" + p .Address )
232
+ return
139
233
}
140
234
141
- res , err := c .ListStorageSpaces (ctx , req )
235
+ r , err := c .ListStorageSpaces (ctx , req )
142
236
if err != nil {
143
- log .Err (err ).Msg ("gateway: error listing storage space on storage provider" )
144
- return & provider.ListStorageSpacesResponse {
145
- Status : status .NewInternal (ctx , err , "error calling ListStorageSpaces" ),
146
- }, nil
237
+ * e = errors .Wrap (err , "gateway: error calling ListStorageSpaces" )
238
+ return
147
239
}
148
- return res , nil
240
+
241
+ * res = r .StorageSpaces
149
242
}
150
243
151
244
func (s * svc ) UpdateStorageSpace (ctx context.Context , req * provider.UpdateStorageSpaceRequest ) (* provider.UpdateStorageSpaceResponse , error ) {
0 commit comments