Revision ef74c42f Classes/AccountManager.m
b/Classes/AccountManager.m | ||
---|---|---|
13 | 13 |
#import "Container.h" |
14 | 14 |
#import "Folder.h" |
15 | 15 |
#import "StorageObject.h" |
16 |
#import "GetObjectsRequest.h" |
|
17 | 16 |
#import "ASINetworkQueue.h" |
18 | 17 |
#import "APICallback.h" |
19 | 18 |
#import "JSON.h" |
20 | 19 |
#import "OpenStackAppDelegate.h" |
21 | 20 |
#import "NSString+Conveniences.h" |
22 | 21 |
|
22 |
@interface AccountManager() |
|
23 |
- (void)start:(OpenStackRequest *)request success:(APIResponseBlock)success failure:(APIResponseBlock)failure; |
|
24 |
- (void)retryWithUpdatedURL:(OpenStackRequest *)request success:(APIResponseBlock)success failure:(APIResponseBlock)failure; |
|
25 |
@end |
|
26 |
|
|
23 | 27 |
@implementation AccountManager |
24 | 28 |
|
25 | 29 |
@synthesize account, queue; |
26 | 30 |
|
27 | 31 |
#pragma mark - Callbacks |
28 | 32 |
|
29 |
- (APICallback *)callbackWithRequest:(id)request success:(APIResponseBlock)success failure:(APIResponseBlock)failure { |
|
30 |
APICallback *callback = [[[APICallback alloc] initWithAccount:self.account request:request] autorelease]; |
|
31 |
((OpenStackRequest *)request).delegate = self; |
|
32 |
((OpenStackRequest *)request).callback = callback; |
|
33 |
|
|
33 |
- (void)start:(OpenStackRequest *)request success:(APIResponseBlock)success failure:(APIResponseBlock)failure { |
|
34 | 34 |
[request setCompletionBlock:^{ |
35 | 35 |
if ([request isSuccess]) { |
36 |
if (request.followUpSelectorString) { |
|
37 |
OpenStackRequest *followUpRequest = [self performSelector:NSSelectorFromString(request.followUpSelectorString) |
|
38 |
withObject:request]; |
|
39 |
if (followUpRequest) { |
|
40 |
[self start:followUpRequest success:success failure:failure]; |
|
41 |
return; |
|
42 |
} |
|
43 |
} |
|
36 | 44 |
success(request); |
37 | 45 |
[request notify]; |
46 |
} else if (request.retryWithUpdatedURL && ((request.responseStatusCode == 401) || (request.responseStatusCode == 404))) { |
|
47 |
[self retryWithUpdatedURL:request success:success failure:failure]; |
|
38 | 48 |
} else { |
39 | 49 |
failure(request); |
40 | 50 |
[request notify]; |
41 | 51 |
} |
42 | 52 |
}]; |
43 | 53 |
[request setFailedBlock:^{ |
54 |
if (request.retryWithUpdatedURL && ((request.responseStatusCode == 401) || (request.responseStatusCode == 404))) { |
|
55 |
[self retryWithUpdatedURL:request success:success failure:failure]; |
|
56 |
} else { |
|
57 |
failure(request); |
|
58 |
[request notify]; |
|
59 |
} |
|
60 |
}]; |
|
61 |
[request startAsynchronous]; |
|
62 |
} |
|
63 |
|
|
64 |
- (void)retryWithUpdatedURL:(OpenStackRequest *)request success:(APIResponseBlock)success failure:(APIResponseBlock)failure { |
|
65 |
[[self serviceCatalog] success:^(OpenStackRequest *serviceRequest) { |
|
66 |
OpenStackRequest *newRequest = [[request copy] autorelease]; |
|
67 |
newRequest.retryWithUpdatedURL = NO; |
|
68 |
[self start:newRequest success:success failure:failure]; |
|
69 |
} failure:^(OpenStackRequest *serviceRequest) { |
|
44 | 70 |
failure(request); |
45 | 71 |
[request notify]; |
46 | 72 |
}]; |
47 |
[request startAsynchronous]; |
|
73 |
} |
|
74 |
|
|
75 |
- (APICallback *)callbackWithRequest:(OpenStackRequest *)request success:(APIResponseBlock)success failure:(APIResponseBlock)failure { |
|
76 |
APICallback *callback = [[[APICallback alloc] initWithAccount:self.account request:request] autorelease]; |
|
77 |
request.delegate = self; |
|
78 |
request.callback = callback; |
|
79 |
[self start:request success:success failure:failure]; |
|
48 | 80 |
return callback; |
49 | 81 |
} |
50 | 82 |
|
51 |
- (APICallback *)callbackWithRequest:(id)request success:(APIResponseBlock)success {
|
|
83 |
- (APICallback *)callbackWithRequest:(OpenStackRequest *)request success:(APIResponseBlock)success {
|
|
52 | 84 |
return [self callbackWithRequest:request success:success failure:^(OpenStackRequest *request){}]; |
53 | 85 |
} |
54 | 86 |
|
55 |
- (APICallback *)callbackWithRequest:(id)request {
|
|
87 |
- (APICallback *)callbackWithRequest:(OpenStackRequest *)request {
|
|
56 | 88 |
return [self callbackWithRequest:request success:^(OpenStackRequest *request){} failure:^(OpenStackRequest *request){}]; |
57 | 89 |
} |
58 | 90 |
|
... | ... | |
138 | 170 |
|
139 | 171 |
- (APICallback *)getSharingAccounts { |
140 | 172 |
__block OpenStackRequest *request = [OpenStackRequest getSharingAccountsRequest:self.account]; |
173 |
request.followUpSelectorString = NSStringFromSelector(@selector(followUpGetSharingAccountsRequest:)); |
|
174 |
request.notificationURL = request.url; |
|
141 | 175 |
return [self callbackWithRequest:request]; |
142 | 176 |
} |
143 | 177 |
|
178 |
- (OpenStackRequest *)followUpGetSharingAccountsRequest:(OpenStackRequest *)request { |
|
179 |
NSArray *jsonSharingAccounts = [request jsonSharingAccounts]; |
|
180 |
NSMutableDictionary *sharingAccountsBuffer = [request.userInfo objectForKey:@"sharingAccountsBuffer"]; |
|
181 |
for (NSDictionary *dict in jsonSharingAccounts) { |
|
182 |
[sharingAccountsBuffer setObject:dict forKey:[dict objectForKey:@"name"]]; |
|
183 |
} |
|
184 |
|
|
185 |
if (jsonSharingAccounts.count < 10000) { |
|
186 |
return nil; |
|
187 |
} else { |
|
188 |
__block OpenStackRequest *followUpRequest = [OpenStackRequest getSharingAccountsRequest:self.account |
|
189 |
marker:[[jsonSharingAccounts lastObject] objectForKey:@"name"] |
|
190 |
sharingAccountsBuffer:sharingAccountsBuffer]; |
|
191 |
followUpRequest.callback = request.callback; |
|
192 |
followUpRequest.followUpSelectorString = request.followUpSelectorString; |
|
193 |
followUpRequest.notificationURL = request.notificationURL; |
|
194 |
return followUpRequest; |
|
195 |
} |
|
196 |
} |
|
197 |
|
|
144 | 198 |
#pragma mark Account |
145 | 199 |
|
146 | 200 |
- (APICallback *)getStorageAccountInfo { |
... | ... | |
158 | 212 |
|
159 | 213 |
- (APICallback *)getContainers { |
160 | 214 |
__block OpenStackRequest *request = [OpenStackRequest getContainersRequest:self.account]; |
215 |
request.followUpSelectorString = NSStringFromSelector(@selector(followUpGetContainersRequest:)); |
|
216 |
request.notificationURL = request.url; |
|
161 | 217 |
return [self callbackWithRequest:request success:^(OpenStackRequest *request) { |
162 |
self.account.containers = [request containers]; |
|
218 |
NSMutableDictionary *containersBuffer = [request.userInfo objectForKey:@"containersBuffer"]; |
|
219 |
self.account.containers = (containersBuffer ? containersBuffer : [NSMutableDictionary dictionary]); |
|
163 | 220 |
NSString *bytesUsedString = [request.responseHeaders objectForKey:@"X-Account-Bytes-Used"]; |
164 | 221 |
self.account.bytesUsed = (bytesUsedString ? |
165 | 222 |
[NSNumber numberWithUnsignedLongLong:strtoull([bytesUsedString UTF8String], NULL, 0)] : nil); |
... | ... | |
170 | 227 |
}]; |
171 | 228 |
} |
172 | 229 |
|
230 |
- (OpenStackRequest *)followUpGetContainersRequest:(OpenStackRequest *)request { |
|
231 |
NSArray *jsonContainers = [request jsonContainers]; |
|
232 |
NSMutableDictionary *containersBuffer = [request.userInfo objectForKey:@"containersBuffer"]; |
|
233 |
for (NSDictionary *dict in jsonContainers) { |
|
234 |
Container *container = [Container fromJSON:dict]; |
|
235 |
[containersBuffer setObject:container forKey:container.name]; |
|
236 |
} |
|
237 |
|
|
238 |
if (jsonContainers.count < 10000) { |
|
239 |
return nil; |
|
240 |
} else { |
|
241 |
__block OpenStackRequest *followUpRequest = [OpenStackRequest getContainersRequest:self.account |
|
242 |
marker:[[jsonContainers lastObject] objectForKey:@"name"] |
|
243 |
containersBuffer:containersBuffer]; |
|
244 |
followUpRequest.callback = request.callback; |
|
245 |
followUpRequest.followUpSelectorString = request.followUpSelectorString; |
|
246 |
followUpRequest.notificationURL = request.notificationURL; |
|
247 |
return followUpRequest; |
|
248 |
} |
|
249 |
} |
|
250 |
|
|
173 | 251 |
- (APICallback *)writeAccountMetadata:(NSDictionary *)accountInfo { |
174 | 252 |
__block OpenStackRequest *request = [OpenStackRequest writeAccountMetadataRequest:self.account withAccountInfo:accountInfo]; |
175 | 253 |
return [self callbackWithRequest:request]; |
... | ... | |
204 | 282 |
}]; |
205 | 283 |
} |
206 | 284 |
|
207 |
- (void)getObjects:(Container *)container afterMarker:(NSString *)marker objectsBuffer:(NSMutableDictionary *)objectsBuffer { |
|
208 |
if (!self.queue) { |
|
209 |
self.queue = [ASINetworkQueue queue]; |
|
210 |
self.queue.shouldCancelAllRequestsOnFailure = NO; |
|
211 |
[self.queue go]; |
|
212 |
} |
|
213 |
GetObjectsRequest *request = [GetObjectsRequest request:self.account container:container marker:marker objectsBuffer:objectsBuffer]; |
|
214 |
[queue addOperation:request]; |
|
285 |
- (APICallback *)getObjects:(Container *)container { |
|
286 |
__block OpenStackRequest *request = [OpenStackRequest getObjectsRequest:self.account container:container]; |
|
287 |
request.followUpSelectorString = NSStringFromSelector(@selector(followUpGetObjectsRequest:)); |
|
288 |
request.notificationURL = request.url; |
|
289 |
return [self callbackWithRequest:request success:^(OpenStackRequest *request) { |
|
290 |
NSMutableDictionary *objectsBuffer = [request.userInfo objectForKey:@"objectsBuffer"]; |
|
291 |
container.rootFolder = [Folder folder]; |
|
292 |
container.rootFolder.objects = (objectsBuffer ? objectsBuffer : [NSMutableDictionary dictionary]); |
|
293 |
[self.account persist]; |
|
294 |
}]; |
|
215 | 295 |
} |
216 | 296 |
|
217 |
- (void)getObjects:(Container *)container { |
|
218 |
[self getObjects:container afterMarker:nil objectsBuffer:nil]; |
|
297 |
- (OpenStackRequest *)followUpGetObjectsRequest:(OpenStackRequest *)request { |
|
298 |
NSArray *jsonObjects = [request jsonObjects]; |
|
299 |
NSMutableDictionary *objectsBuffer = [request.userInfo objectForKey:@"objectsBuffer"]; |
|
300 |
for (NSDictionary *dict in jsonObjects) { |
|
301 |
StorageObject *object = [StorageObject fromJSON:dict]; |
|
302 |
[objectsBuffer setObject:object forKey:object.name]; |
|
303 |
} |
|
304 |
|
|
305 |
if (jsonObjects.count < 10000) { |
|
306 |
return nil; |
|
307 |
} else { |
|
308 |
__block OpenStackRequest *followUpRequest = [OpenStackRequest getObjectsRequest:self.account |
|
309 |
container:[request.userInfo objectForKey:@"container"] |
|
310 |
marker:[[jsonObjects lastObject] objectForKey:@"name"] |
|
311 |
objectsBuffer:objectsBuffer]; |
|
312 |
followUpRequest.callback = request.callback; |
|
313 |
followUpRequest.followUpSelectorString = request.followUpSelectorString; |
|
314 |
followUpRequest.notificationURL = request.notificationURL; |
|
315 |
return followUpRequest; |
|
316 |
} |
|
219 | 317 |
} |
220 | 318 |
|
221 | 319 |
- (APICallback *)writeContainerPolicy:(Container *)container { |
... | ... | |
343 | 441 |
[[NSNotificationCenter defaultCenter] postNotification:notification]; |
344 | 442 |
} |
345 | 443 |
|
346 |
#pragma mark - Observers |
|
347 |
|
|
348 |
- (void)getObjectsSucceeded:(OpenStackRequest *)request { |
|
349 |
if ([request isSuccess]) { |
|
350 |
Container *container = [request.userInfo objectForKey:@"container"]; |
|
351 |
NSMutableDictionary *objects = [request objects]; |
|
352 |
container.rootFolder = [Folder folder]; |
|
353 |
container.rootFolder.objects = objects; |
|
354 |
[self.account persist]; |
|
355 |
|
|
356 |
NSNotification *notification = [NSNotification notificationWithName:@"getObjectsSucceeded" object:self.account userInfo:[NSDictionary dictionaryWithObject:container forKey:@"container"]]; |
|
357 |
[[NSNotificationCenter defaultCenter] postNotification:notification]; |
|
358 |
} else { |
|
359 |
NSNotification *notification = [NSNotification notificationWithName:@"getObjectsFailed" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]]; |
|
360 |
[[NSNotificationCenter defaultCenter] postNotification:notification]; |
|
361 |
} |
|
362 |
} |
|
363 |
|
|
364 |
- (void)getObjectsFailed:(OpenStackRequest *)request { |
|
365 |
NSNotification *notification = [NSNotification notificationWithName:@"getObjectsFailed" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]]; |
|
366 |
[[NSNotificationCenter defaultCenter] postNotification:notification]; |
|
367 |
} |
|
368 |
|
|
369 | 444 |
@end |
Also available in: Unified diff