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