5 // Created by Mike Mayo on 10/21/10.
6 // The OpenStack project is provided under the Apache 2.0 license.
9 #import "AccountManager.h"
10 #import "OpenStackAccount.h"
11 #import "OpenStackRequest.h"
17 #import "StorageObject.h"
18 #import "GetServersRequest.h"
19 #import "GetContainersRequest.h"
20 #import "GetObjectsRequest.h"
21 #import "GetImagesRequest.h"
22 #import "ASINetworkQueue.h"
23 #import "UpdateCDNContainerRequest.h"
24 #import "GetFlavorsRequest.h"
25 #import "LoadBalancer.h"
26 #import "LoadBalancerRequest.h"
27 #import "APICallback.h"
30 #import "OpenStackAppDelegate.h"
35 @implementation AccountManager
37 @synthesize account, queue, objectDownloadRequests;
39 #pragma mark - Callbacks
41 - (APICallback *)callbackWithRequest:(id)request success:(APIResponseBlock)success failure:(APIResponseBlock)failure {
42 APICallback *callback = [[[APICallback alloc] initWithAccount:self.account request:request] autorelease];
43 ((OpenStackRequest *)request).delegate = self;
44 ((OpenStackRequest *)request).callback = callback;
46 [request setCompletionBlock:^{
47 if ([request isSuccess]) {
55 [request setFailedBlock:^{
59 [request startAsynchronous];
63 - (APICallback *)callbackWithRequest:(id)request success:(APIResponseBlock)success {
64 return [self callbackWithRequest:request success:success failure:^(OpenStackRequest *request){}];
67 - (APICallback *)callbackWithRequest:(id)request {
68 return [self callbackWithRequest:request success:^(OpenStackRequest *request){} failure:^(OpenStackRequest *request){}];
71 #pragma mark - Notification
73 - (NSString *)notificationName:(NSString *)key identifier:(NSString *)identifier {
74 return [NSString stringWithFormat:@"%@-%@-%@", key, self.account.uuid, identifier];
77 - (void)requestFinished:(OpenStackRequest *)request {
78 NSString *notificationName = [request.userInfo objectForKey:@"notificationName"];
79 id notificationObject = [request.userInfo objectForKey:@"notificationObject"];
81 if ([request isSuccess]) {
82 NSNotification *notification = [NSNotification notificationWithName:[NSString stringWithFormat:@"%@Succeeded", notificationName] object:notificationObject];
83 [[NSNotificationCenter defaultCenter] postNotification:notification];
85 NSNotification *notification = [NSNotification notificationWithName:[NSString stringWithFormat:@"%@Failed", notificationName] object:notificationObject userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
86 [[NSNotificationCenter defaultCenter] postNotification:notification];
90 - (void)requestFailed:(OpenStackRequest *)request {
91 NSString *notificationName = [request.userInfo objectForKey:@"notificationName"];
92 id notificationObject = [request.userInfo objectForKey:@"notificationObject"];
93 NSNotification *notification = [NSNotification notificationWithName:[NSString stringWithFormat:@"%@Failed", notificationName] object:notificationObject userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
94 [[NSNotificationCenter defaultCenter] postNotification:notification];
97 - (void)sendRequest:(OpenStackRequest *)request name:(NSString *)name object:(id)notificationObject {
98 request.delegate = self;
99 request.userInfo = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:name, notificationObject, nil] forKeys:[NSArray arrayWithObjects:@"notificationName", @"notificationObject", nil]];
100 [request startAsynchronous];
103 - (void)notify:(NSString *)name request:(OpenStackRequest *)request {
104 NSNotification *notification = [NSNotification notificationWithName:name object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
105 [[NSNotificationCenter defaultCenter] postNotification:notification];
108 - (void)notify:(NSString *)name request:(OpenStackRequest *)request object:(id)object {
109 NSNotification *notification = [NSNotification notificationWithName:name object:object userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
110 [[NSNotificationCenter defaultCenter] postNotification:notification];
113 #pragma mark - API Calls
115 #pragma mark Get Limits
118 __block OpenStackRequest *request = [OpenStackRequest getLimitsRequest:self.account];
119 request.delegate = self;
120 [request setCompletionBlock:^{
121 if ([request isSuccess] && [request limits]) {
122 self.account.rateLimits = [request rateLimits];
123 [self.account persist];
124 [self notify:@"getLimitsSucceeded" request:request object:self.account];
126 [self notify:@"getLimitsFailed" request:request object:self.account];
129 [request setFailedBlock:^{
130 [self notify:@"getLimitsFailed" request:request object:self.account];
132 [request startAsynchronous];
135 #pragma mark Reboot Server
137 - (void)softRebootServer:(Server *)server {
138 TrackEvent(CATEGORY_SERVER, EVENT_REBOOTED);
140 __block OpenStackRequest *request = [OpenStackRequest softRebootServerRequest:self.account server:server];
141 request.delegate = self;
142 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
143 [request setCompletionBlock:^{
144 [self notify:([request isSuccess] ? @"rebootSucceeded" : @"rebootFailed") request:request object:[request.userInfo objectForKey:@"server"]];
146 [request setFailedBlock:^{
147 [self notify:@"rebootFailed" request:request object:[request.userInfo objectForKey:@"server"]];
149 [request startAsynchronous];
152 - (void)hardRebootServer:(Server *)server {
153 TrackEvent(CATEGORY_SERVER, EVENT_REBOOTED);
155 __block OpenStackRequest *request = [OpenStackRequest hardRebootServerRequest:self.account server:server];
156 request.delegate = self;
157 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
158 [request setCompletionBlock:^{
159 [self notify:([request isSuccess] ? @"rebootSucceeded" : @"rebootFailed") request:request object:[request.userInfo objectForKey:@"server"]];
161 [request setFailedBlock:^{
162 [self notify:@"rebootFailed" request:request object:[request.userInfo objectForKey:@"server"]];
164 [request startAsynchronous];
167 #pragma mark Change Admin Password
169 - (void)changeAdminPassword:(Server *)server password:(NSString *)password {
170 TrackEvent(CATEGORY_SERVER, EVENT_PASSWORD_CHANGED);
172 __block OpenStackRequest *request = [OpenStackRequest changeServerAdminPasswordRequest:self.account server:server password:password];
173 request.delegate = self;
174 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
175 [request setCompletionBlock:^{
176 [self notify:([request isSuccess] ? @"changeAdminPasswordSucceeded" : @"changeAdminPasswordFailed") request:request object:[request.userInfo objectForKey:@"server"]];
178 [request setFailedBlock:^{
179 [self notify:@"changeAdminPasswordFailed" request:request object:[request.userInfo objectForKey:@"server"]];
181 [request startAsynchronous];
184 #pragma mark Rename Server
186 - (APICallback *)renameServer:(Server *)server name:(NSString *)name {
187 TrackEvent(CATEGORY_SERVER, EVENT_RENAMED);
189 __block OpenStackRequest *request = [OpenStackRequest renameServerRequest:self.account server:server name:name];
190 return [self callbackWithRequest:request];
193 #pragma mark Delete Server
195 - (void)deleteServer:(Server *)server {
196 TrackEvent(CATEGORY_SERVER, EVENT_DELETED);
198 __block OpenStackRequest *request = [OpenStackRequest deleteServerRequest:self.account server:server];
199 request.delegate = self;
200 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
201 [request setCompletionBlock:^{
202 [self notify:([request isSuccess] ? @"deleteServerSucceeded" : @"deleteServerFailed") request:request object:[request.userInfo objectForKey:@"server"]];
203 [self notify:([request isSuccess] ? @"deleteServerSucceeded" : @"deleteServerFailed") request:request object:self.account];
205 [request setFailedBlock:^{
206 [self notify:@"deleteServerFailed" request:request object:[request.userInfo objectForKey:@"server"]];
209 [self setQueue:(ASINetworkQueue *)[[[NSOperationQueue alloc] init] autorelease]];
211 [queue addOperation:request];
214 #pragma mark Create Server
216 - (void)createServer:(Server *)server {
217 TrackEvent(CATEGORY_SERVER, EVENT_CREATED);
219 __block OpenStackRequest *request = [OpenStackRequest createServerRequest:self.account server:server];
220 request.delegate = self;
221 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
223 // TODO: make these success block and failure block with "response" arg
224 [request setCompletionBlock:^{
225 NSLog(@"create server response: %i - %@", request.responseStatusCode, request.responseStatusMessage);
226 NSLog(@"body: %@", [request responseString]);
227 [self notify:([request isSuccess] ? @"createServerSucceeded" : @"createServerFailed") request:request object:[request.userInfo objectForKey:@"server"]];
228 [self notify:([request isSuccess] ? @"createServerSucceeded" : @"createServerFailed") request:request object:self.account];
230 [request setFailedBlock:^{
231 NSLog(@"create server response: %i - %@", request.responseStatusCode, request.responseStatusMessage);
232 NSLog(@"body: %@", [request responseString]);
233 [self notify:@"createServerFailed" request:request object:[request.userInfo objectForKey:@"server"]];
236 [self setQueue:(ASINetworkQueue *)[[[NSOperationQueue alloc] init] autorelease]];
238 [queue addOperation:request];
241 #pragma mark Resize Server
243 - (void)resizeServer:(Server *)server flavor:(Flavor *)flavor {
244 TrackEvent(CATEGORY_SERVER, EVENT_RESIZED);
246 __block OpenStackRequest *request = [OpenStackRequest resizeServerRequest:self.account server:server flavor:flavor];
247 request.delegate = self;
248 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
249 [request setCompletionBlock:^{
250 NSString *name = [request isSuccess] ? @"resizeServerSucceeded" : @"resizeServerFailed";
251 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:name identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
252 [[NSNotificationCenter defaultCenter] postNotification:notification];
254 [request setFailedBlock:^{
255 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:@"resizeServerFailed" identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
256 [[NSNotificationCenter defaultCenter] postNotification:notification];
258 [request startAsynchronous];
261 - (void)confirmResizeServer:(Server *)server {
262 __block OpenStackRequest *request = [OpenStackRequest confirmResizeServerRequest:self.account server:server];
263 request.delegate = self;
264 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
265 [request setCompletionBlock:^{
266 NSString *name = [request isSuccess] ? @"confirmResizeServerSucceeded" : @"confirmResizeServerFailed";
267 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:name identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
268 [[NSNotificationCenter defaultCenter] postNotification:notification];
270 [request setFailedBlock:^{
271 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:@"confirmResizeServerFailed" identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
272 [[NSNotificationCenter defaultCenter] postNotification:notification];
275 [request startAsynchronous];
278 - (void)revertResizeServer:(Server *)server {
279 __block OpenStackRequest *request = [OpenStackRequest revertResizeServerRequest:self.account server:server];
280 request.delegate = self;
281 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
282 [request setCompletionBlock:^{
283 NSString *name = [request isSuccess] ? @"revertResizeServerSucceeded" : @"revertResizeServerFailed";
284 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:name identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
285 [[NSNotificationCenter defaultCenter] postNotification:notification];
287 [request setFailedBlock:^{
288 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:@"revertResizeServerFailed" identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
289 [[NSNotificationCenter defaultCenter] postNotification:notification];
291 [request startAsynchronous];
294 - (void)rebuildServer:(Server *)server image:(Image *)image {
295 TrackEvent(CATEGORY_SERVER, EVENT_REBUILT);
297 __block OpenStackRequest *request = [OpenStackRequest rebuildServerRequest:self.account server:server image:image];
298 request.delegate = self;
299 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
300 [request setCompletionBlock:^{
301 NSString *name = [request isSuccess] ? @"rebuildServerSucceeded" : @"rebuildServerFailed";
302 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:name identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
303 [[NSNotificationCenter defaultCenter] postNotification:notification];
305 [request setFailedBlock:^{
306 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:@"rebuildServerFailed" identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
307 [[NSNotificationCenter defaultCenter] postNotification:notification];
309 [request startAsynchronous];
312 - (void)getBackupSchedule:(Server *)server {
313 __block OpenStackRequest *request = [OpenStackRequest getBackupScheduleRequest:self.account server:server];
314 request.delegate = self;
315 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
316 [request setCompletionBlock:^{
317 server.backupSchedule = [request backupSchedule];
318 [self notify:([request isSuccess] ? @"getBackupScheduleSucceeded" : @"getBackupScheduleFailed") request:request object:[request.userInfo objectForKey:@"server"]];
320 [request setFailedBlock:^{
321 [self notify:@"getBackupScheduleFailed" request:request object:[request.userInfo objectForKey:@"server"]];
323 [request startAsynchronous];
326 - (void)updateBackupSchedule:(Server *)server {
327 TrackEvent(CATEGORY_SERVER, EVENT_BACKUP_SCHEDULE_CHANGED);
329 __block OpenStackRequest *request = [OpenStackRequest updateBackupScheduleRequest:self.account server:server];
330 request.delegate = self;
331 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
332 [request setCompletionBlock:^{
333 [self notify:([request isSuccess] ? @"updateBackupScheduleSucceeded" : @"updateBackupScheduleFailed") request:request object:[request.userInfo objectForKey:@"server"]];
334 [self notify:([request isSuccess] ? @"updateBackupScheduleSucceeded" : @"updateBackupScheduleFailed") request:request object:self.account];
336 [request setFailedBlock:^{
337 [self notify:@"updateBackupScheduleFailed" request:request object:[request.userInfo objectForKey:@"server"]];
338 [self notify:@"updateBackupScheduleFailed" request:request object:self.account];
340 [request startAsynchronous];
343 #pragma mark Get Image
345 - (void)getImage:(Server *)server {
346 __block OpenStackRequest *request = [OpenStackRequest getImageRequest:self.account imageId:server.imageId];
347 request.delegate = self;
348 request.userInfo = [NSDictionary dictionaryWithObject:server.imageId forKey:@"imageId"];
349 [request setCompletionBlock:^{
350 if ([request isSuccess]) {
351 Image *image = [request image];
352 if ([image isKindOfClass:[Image class]]) {
353 image.canBeLaunched = NO;
354 [self.account.images setObject:image forKey:image.identifier];
355 [self.account persist];
357 [self notify:@"getImageSucceeded" request:request];
359 [self notify:@"getImageFailed" request:request object:[request.userInfo objectForKey:@"imageId"]];
362 [request setFailedBlock:^{
363 [self notify:@"getImageFailed" request:request object:[request.userInfo objectForKey:@"imageId"]];
365 [request startAsynchronous];
368 #pragma mark Get Servers
372 [self setQueue:[[[ASINetworkQueue alloc] init] autorelease]];
374 GetServersRequest *request = [GetServersRequest request:self.account];
375 [queue addOperation:request];
378 - (APICallback *)getServersWithCallback {
379 __block OpenStackRequest *request = [OpenStackRequest serversRequest:self.account method:@"GET" path:@"/servers/detail"];
380 return [self callbackWithRequest:request];
384 #pragma mark Get Flavors
388 [self setQueue:[[[ASINetworkQueue alloc] init] autorelease]];
390 GetFlavorsRequest *request = [GetFlavorsRequest request:self.account];
391 [queue addOperation:request];
394 #pragma mark Get Images
398 [self setQueue:[[[ASINetworkQueue alloc] init] autorelease]];
400 GetImagesRequest *request = [GetImagesRequest request:self.account];
401 [queue addOperation:request];
405 #pragma mark Object Storage
408 - (APICallback *)getStorageAccountInfo {
409 __block OpenStackRequest *request = [OpenStackRequest getStorageAccountInfoRequest:self.account];
410 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
411 self.account.containerCount = [[[request responseHeaders] objectForKey:@"X-Account-Container-Count"] intValue];
412 NSString *numStr = [[request responseHeaders] objectForKey:@"X-Account-Bytes-Used"];
413 self.account.totalBytesUsed = strtoull([numStr UTF8String], NULL, 0);
414 [self.account persist];
415 self.account.containerCount = [self.account.containers count];
419 - (APICallback *)getSharingAccounts {
420 __block OpenStackRequest *request = [OpenStackRequest getSharingAccountsRequest:self.account];
421 return [self callbackWithRequest:request];
424 - (APICallback *)getContainers {
425 __block OpenStackRequest *request = [OpenStackRequest filesRequest:self.account method:@"GET" path:@""];
426 return [self callbackWithRequest:request];
429 - (APICallback *)createContainer:(Container *)container {
430 TrackEvent(CATEGORY_CONTAINERS, EVENT_CREATED);
432 __block OpenStackRequest *request = [OpenStackRequest createContainerRequest:self.account container:container];
433 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
435 [self.account.containers setObject:container forKey:container.name];
436 [self.account persist];
437 self.account.containerCount = [self.account.containers count];
441 - (APICallback *)deleteContainer:(Container *)container {
442 TrackEvent(CATEGORY_CONTAINERS, EVENT_DELETED);
443 __block OpenStackRequest *request = [OpenStackRequest deleteContainerRequest:self.account container:container];
444 return [self callbackWithRequest:request];
448 - (void)getObjects:(Container *)container {
449 [self getObjects:container afterMarker:nil objectsBuffer:nil];
452 - (void)getObjects:(Container *)container
453 afterMarker:(NSString *)marker
454 objectsBuffer:(NSMutableDictionary *)objectsBuffer {
456 [self setQueue:(ASINetworkQueue *)[[[NSOperationQueue alloc] init] autorelease]];
458 GetObjectsRequest *request = [GetObjectsRequest request:self.account container:container marker:marker objectsBuffer:objectsBuffer];
459 [queue addOperation:request];
462 - (void)updateCDNContainer:(Container *)container {
463 TrackEvent(CATEGORY_CONTAINERS, EVENT_UPDATED);
466 [self setQueue:(ASINetworkQueue *)[[[NSOperationQueue alloc] init] autorelease]];
468 UpdateCDNContainerRequest *request = [UpdateCDNContainerRequest request:self.account container:container];
469 [queue addOperation:request];
472 - (void)getObjectsSucceeded:(OpenStackRequest *)request {
473 if ([request isSuccess]) {
474 Container *container = [request.userInfo objectForKey:@"container"];
475 NSMutableDictionary *objects = [request objects];
476 container.rootFolder = [Folder folder];
477 container.rootFolder.objects = objects;
478 [self.account persist];
480 NSNotification *notification = [NSNotification notificationWithName:@"getObjectsSucceeded" object:self.account userInfo:[NSDictionary dictionaryWithObject:container forKey:@"container"]];
481 [[NSNotificationCenter defaultCenter] postNotification:notification];
483 NSNotification *notification = [NSNotification notificationWithName:@"getObjectsFailed" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
484 [[NSNotificationCenter defaultCenter] postNotification:notification];
488 - (void)getObjectsFailed:(OpenStackRequest *)request {
489 NSNotification *notification = [NSNotification notificationWithName:@"getObjectsFailed" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
490 [[NSNotificationCenter defaultCenter] postNotification:notification];
493 - (APICallback *)getContainerInfo:(Container *)container {
494 __block OpenStackRequest *request = [OpenStackRequest getContainerInfoRequest:self.account container:container];
495 return [self callbackWithRequest:request];
498 - (APICallback *)getObjectInfo:(Container *)container object:(StorageObject *)object {
499 __block OpenStackRequest *request = [OpenStackRequest getObjectInfoRequest:self.account container:container object:object];
500 return [self callbackWithRequest:request];
503 - (APICallback *)getObjectInfo:(Container *)container object:(StorageObject *)object version:(NSString *)version {
505 return [self getObjectInfo:container object:object];
507 __block OpenStackRequest *request = [OpenStackRequest getObjectInfoRequest:self.account container:container object:object version:version];
508 return [self callbackWithRequest:request];
511 - (APICallback *)getObjectVersionsList:(Container *)container object:(StorageObject *)object {
512 __block OpenStackRequest *request = [OpenStackRequest getObjectVersionsRequest:account container:container object:object];
513 return [self callbackWithRequest:request];
516 - (APICallback *)getObject:(Container *)container object:(StorageObject *)object downloadProgressDelegate:(id)downloadProgressDelegate {
517 return [self getObject:container object:object downloadProgressDelegate:downloadProgressDelegate requestUserInfo:nil];
520 - (APICallback *)getObject:(Container *)container
521 object:(StorageObject *)object
522 downloadProgressDelegate:(id)downloadProgressDelegate
523 requestUserInfo:(NSDictionary *)requestUserInfo {
525 return [self getObject:container object:object downloadProgressDelegate:downloadProgressDelegate requestUserInfo:requestUserInfo version:nil];
529 - (APICallback *)getObject:(Container *)container
530 object:(StorageObject *)object
531 downloadProgressDelegate:(id)downloadProgressDelegate
532 requestUserInfo:(NSDictionary *)requestUserInfo
533 version:(NSString *)version{
534 __block OpenStackRequest *request = [OpenStackRequest getObjectRequest:self.account container:container object:object version:version];
535 request.delegate = self;
536 request.downloadProgressDelegate = downloadProgressDelegate;
537 request.showAccurateProgress = YES;
538 if (requestUserInfo) {
539 request.userInfo = requestUserInfo;
541 if (!objectDownloadRequests)
542 self.objectDownloadRequests = [NSMutableDictionary dictionary];
543 [objectDownloadRequests setObject:request forKey:object.fullPath];
544 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
545 OpenStackAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
546 NSString *filePath = [appDelegate.cacheDirectoryPath stringByAppendingFormat:@"/%@.%@",object.hash, object.name.pathExtension];
547 [[request responseData] writeToFile:filePath atomically:YES];
548 @synchronized(appDelegate.cachedObjectsDictionary) {
550 object.hash = [request.responseHeaders objectForKey:@"X-Object-Hash"];
551 [appDelegate.cachedObjectsDictionary setObject:filePath forKey:object.hash];
552 [appDelegate saveCacheDictionary];
554 [objectDownloadRequests removeObjectForKey:object.fullPath];
556 failure:^(OpenStackRequest *request) {
557 [objectDownloadRequests removeObjectForKey:object.fullPath];
561 - (APICallback *)writeObject:(Container *)container object:(StorageObject *)object downloadProgressDelegate:(id)downloadProgressDelegate {
562 TrackEvent(CATEGORY_FILES, EVENT_CREATED);
564 __block OpenStackRequest *request = [OpenStackRequest writeObjectRequest:self.account container:container object:object];
565 request.delegate = self;
566 request.uploadProgressDelegate = downloadProgressDelegate;
567 request.showAccurateProgress = YES;
569 return [self callbackWithRequest:request];
572 - (APICallback *)deleteObject:(Container *)container object:(StorageObject *)object {
573 TrackEvent(CATEGORY_FILES, EVENT_DELETED);
575 __block OpenStackRequest *request = [OpenStackRequest deleteObjectRequest:self.account container:container object:object];
576 return [self callbackWithRequest:request];
579 - (APICallback *)writeObjectMetadata:(Container *)container object:(StorageObject *)object {
580 __block OpenStackRequest *request = [OpenStackRequest writeObjectMetadataRequest:self.account container:container object:object];
581 return [self callbackWithRequest:request];
584 - (APICallback *)writeAccountMetadata:(NSDictionary *)accountInfo {
585 __block OpenStackRequest *request = [OpenStackRequest writeAccountMetadataRequest:self.account withAccountInfo:accountInfo];
586 return [self callbackWithRequest:request];
589 - (APICallback *)writeContainerPolicy:(Container *)container {
590 __block OpenStackRequest *request = [OpenStackRequest writeContainerPolicyRequest:self.account container:container];
591 return [self callbackWithRequest:request];
595 #pragma mark Load Balancing
597 - (APICallback *)getLoadBalancers:(NSString *)endpoint {
598 __block LoadBalancerRequest *request = [LoadBalancerRequest getLoadBalancersRequest:self.account endpoint:endpoint];
599 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
600 if (!self.account.loadBalancers) {
601 self.account.loadBalancers = [[[NSMutableDictionary alloc] initWithCapacity:2] autorelease];
604 NSLog(@"%@", self.account.loadBalancers);
605 NSLog(@"%@", [(LoadBalancerRequest *)request loadBalancers:self.account]);
606 NSLog(@"%@", endpoint);
607 NSMutableDictionary *lbs = [(LoadBalancerRequest *)request loadBalancers:self.account];
609 for (NSString *identifier in lbs) {
610 LoadBalancer *lb = [lbs objectForKey:identifier];
611 lb.region = [self.account loadBalancerRegionForEndpoint:endpoint];
612 NSLog(@"lb.region = %@", lb.region);
615 [self.account.loadBalancers setObject:lbs forKey:endpoint];
616 [self.account persist];
620 - (APICallback *)getLoadBalancerDetails:(LoadBalancer *)loadBalancer endpoint:(NSString *)endpoint {
621 __block LoadBalancerRequest *request = [LoadBalancerRequest getLoadBalancerDetailsRequest:self.account loadBalancer:loadBalancer endpoint:endpoint];
622 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
624 LoadBalancer *newLB = [(LoadBalancerRequest *)request loadBalancer:self.account];
625 loadBalancer.status = newLB.status;
626 loadBalancer.nodes = newLB.nodes;
627 loadBalancer.connectionLoggingEnabled = newLB.connectionLoggingEnabled;
629 // if (!self.account.loadBalancers) {
630 // self.account.loadBalancers = [[NSMutableDictionary alloc] initWithCapacity:2];
633 // NSLog(@"%@", self.account.loadBalancers);
634 // NSLog(@"%@", [(LoadBalancerRequest *)request loadBalancers]);
635 // NSLog(@"%@", endpoint);
636 // NSMutableDictionary *lbs = [(LoadBalancerRequest *)request loadBalancers];
638 // for (NSString *identifier in lbs) {
639 // LoadBalancer *lb = [lbs objectForKey:identifier];
640 // lb.region = [self.account loadBalancerRegionForEndpoint:endpoint];
641 // NSLog(@"lb.region = %@", lb.region);
644 // [self.account.loadBalancers setObject:lbs forKey:endpoint];
645 [self.account persist];
649 - (APICallback *)getLoadBalancerProtocols:(NSString *)endpoint {
650 __block LoadBalancerRequest *request = [LoadBalancerRequest getLoadBalancerProtocols:self.account endpoint:endpoint];
651 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
652 self.account.lbProtocols = [(LoadBalancerRequest *)request protocols];
656 - (APICallback *)createLoadBalancer:(LoadBalancer *)loadBalancer {
657 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_CREATED);
659 NSString *endpoint = @"";
661 for (NSString *url in [self.account loadBalancerURLs]) {
662 if ([url hasPrefix:[NSString stringWithFormat:@"https://%@", [loadBalancer.region lowercaseString]]]) {
668 __block LoadBalancerRequest *request = [LoadBalancerRequest createLoadBalancerRequest:self.account loadBalancer:loadBalancer endpoint:endpoint];
669 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
673 - (APICallback *)updateLoadBalancer:(LoadBalancer *)loadBalancer {
674 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_UPDATED);
675 NSString *endpoint = [self.account loadBalancerEndpointForRegion:loadBalancer.region];
676 __block LoadBalancerRequest *request = [LoadBalancerRequest updateLoadBalancerRequest:self.account loadBalancer:loadBalancer endpoint:endpoint];
677 return [self callbackWithRequest:request];
680 - (APICallback *)deleteLoadBalancer:(LoadBalancer *)loadBalancer {
681 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_DELETED);
682 NSString *endpoint = [self.account loadBalancerEndpointForRegion:loadBalancer.region];
683 NSLog(@"endpoint: %@", endpoint);
684 __block LoadBalancerRequest *request = [LoadBalancerRequest deleteLoadBalancerRequest:self.account loadBalancer:loadBalancer endpoint:endpoint];
685 return [self callbackWithRequest:request];
688 - (APICallback *)updateLoadBalancerConnectionLogging:(LoadBalancer *)loadBalancer {
689 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_UPDATED_LB_CONNECTION_LOGGING);
690 __block LoadBalancerRequest *request = [LoadBalancerRequest updateConnectionLoggingRequest:self.account loadBalancer:loadBalancer];
691 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
692 } failure:^(OpenStackRequest *request) {
693 loadBalancer.connectionLoggingEnabled = !loadBalancer.connectionLoggingEnabled;
697 - (APICallback *)getLoadBalancerConnectionThrottling:(LoadBalancer *)loadBalancer {
698 __block LoadBalancerRequest *request = [LoadBalancerRequest getConnectionThrottlingRequest:self.account loadBalancer:loadBalancer];
699 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
700 loadBalancer.connectionThrottle = [(LoadBalancerRequest *)request connectionThrottle];
704 - (APICallback *)updateLoadBalancerConnectionThrottling:(LoadBalancer *)loadBalancer {
705 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_UPDATED_LB_CONNECTION_THROTTLING);
706 __block LoadBalancerRequest *request = [LoadBalancerRequest updateConnectionThrottlingRequest:self.account loadBalancer:loadBalancer];
707 return [self callbackWithRequest:request];
710 - (APICallback *)deleteLoadBalancerConnectionThrottling:(LoadBalancer *)loadBalancer {
711 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_DISABLED_LB_CONNECTION_THROTTLING);
712 __block LoadBalancerRequest *request = [LoadBalancerRequest disableConnectionThrottlingRequest:self.account loadBalancer:loadBalancer];
713 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
714 loadBalancer.connectionThrottle = nil;
718 - (APICallback *)getLoadBalancerUsage:(LoadBalancer *)loadBalancer endpoint:(NSString *)endpoint {
719 __block LoadBalancerRequest *request = [LoadBalancerRequest getLoadBalancerUsageRequest:self.account loadBalancer:loadBalancer endpoint:endpoint];
720 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
721 loadBalancer.usage = [(LoadBalancerRequest *)request usage];
725 - (APICallback *)addLBNodes:(NSArray *)nodes loadBalancer:(LoadBalancer *)loadBalancer endpoint:(NSString *)endpoint {
726 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_ADDED_LB_NODES);
727 __block LoadBalancerRequest *request = [LoadBalancerRequest addLoadBalancerNodesRequest:self.account loadBalancer:loadBalancer nodes:nodes endpoint:endpoint];
728 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
729 for (LoadBalancerNode *node in nodes) {
730 [loadBalancer.nodes addObject:node];
732 [self.account persist];
736 - (APICallback *)updateLBNode:(LoadBalancerNode *)node loadBalancer:(LoadBalancer *)loadBalancer endpoint:(NSString *)endpoint {
737 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_UPDATED_LB_NODE);
738 __block LoadBalancerRequest *request = [LoadBalancerRequest updateLoadBalancerNodeRequest:self.account loadBalancer:loadBalancer node:node endpoint:endpoint];
739 return [self callbackWithRequest:request];
742 - (APICallback *)deleteLBNode:(LoadBalancerNode *)node loadBalancer:(LoadBalancer *)loadBalancer endpoint:(NSString *)endpoint {
743 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_DELETED_LB_NODE);
744 __block LoadBalancerRequest *request = [LoadBalancerRequest deleteLoadBalancerNodeRequest:self.account loadBalancer:loadBalancer node:node endpoint:endpoint];
745 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
746 [loadBalancer.nodes removeObject:node];
750 - (APICallback *)authenticate {
751 __block OpenStackRequest *request = [OpenStackRequest authenticationRequest:self.account];
752 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
753 if ([request isSuccess]) {
754 self.account.authToken = [[request responseHeaders] objectForKey:@"X-Auth-Token"];
755 self.account.serversURL = [NSURL URLWithString:[[request responseHeaders] objectForKey:@"X-Server-Management-Url"]];
757 if (![[request responseHeaders] objectForKey:@"X-Storage-URL"]) {
758 NSString *filesStorageURL = [NSString stringWithFormat:@"%@/v1/%@",
759 [self.account.hostURL absoluteString],
760 [self.account username]];
762 self.account.filesURL = [NSURL URLWithString:filesStorageURL];
765 self.account.filesURL = [NSURL URLWithString:[[request responseHeaders] objectForKey:@"X-Storage-Url"]];
768 self.account.pithosPublicLinkURLPrefix = self.account.hostURL;
769 self.account.pithosLoginURLPrefix = [NSURL URLWithString:
770 [[self.account.hostURL absoluteString]
771 stringByAppendingString:@"/login"]];
772 self.account.cdnURL = [NSURL URLWithString:[[request responseHeaders] objectForKey:@"X-Cdn-Management-Url"]];
774 [self.account persist];
781 #pragma mark Memory Management
784 [objectDownloadRequests release];