~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cloud_ms.cc

  • Committer: Monty Taylor
  • Date: 2010-07-04 20:02:43 UTC
  • mfrom: (1548.2.40 drizzle_pbms)
  • mto: This revision was merged to the branch mainline in revision 1644.
  • Revision ID: mordred@inaugust.com-20100704200243-2vkq9gi6ysauj2tb
Merge PBMS from Barry.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2009 PrimeBase Technologies GmbH, Germany
 
2
 *
 
3
 * PrimeBase Media Stream for MySQL
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
18
 *
 
19
 *  Created by Barry Leslie on 3/20/09.
 
20
 *
 
21
 */
 
22
 
 
23
#ifdef DRIZZLED
 
24
#include "config.h"
 
25
#include <drizzled/common.h>
 
26
#include <drizzled/session.h>
 
27
#include <drizzled/table.h>
 
28
#include <drizzled/message/table.pb.h>
 
29
#include "drizzled/charset_info.h"
 
30
#include <drizzled/table_proto.h>
 
31
#include <drizzled/session.h>
 
32
#include <drizzled/field.h>
 
33
#endif
 
34
 
 
35
#include "cslib/CSConfig.h"
 
36
 
 
37
#include <stdlib.h>
 
38
#include <ctype.h>
 
39
#include <string.h>
 
40
 
 
41
#include "cslib/CSGlobal.h"
 
42
#include "cslib/CSThread.h"
 
43
#include "cslib/CSLog.h"
 
44
#include "cslib/CSPath.h"
 
45
#include "cslib/CSFile.h"
 
46
#include "cslib/CSString.h"
 
47
#include "cslib/CSStrUtil.h"
 
48
#include "cslib/CSStorage.h"
 
49
#include "cslib/CSEncode.h"
 
50
#include "cslib/CSS3Protocol.h"
 
51
 
 
52
#include "backup_ms.h"
 
53
#include "cloud_ms.h"
 
54
 
 
55
CSSyncSparseArray       *MSCloudInfo::gCloudInfo;
 
56
uint32_t                        MSCloudInfo::gMaxInfoRef;
 
57
 
 
58
uint32_t                        CloudDB::gKeyIndex;
 
59
CSMutex                 CloudDB::gCloudKeyLock;
 
60
 
 
61
//==============================
 
62
MSCloudInfo::MSCloudInfo(uint32_t id,
 
63
                                                const char *server,
 
64
                                                const char *bucket_arg,
 
65
                                                const char *publicKey,
 
66
                                                const char *privateKey
 
67
                                                ):
 
68
        cloudRefId(id),
 
69
        bucket(NULL),
 
70
        s3Prot(NULL)
 
71
{               
 
72
        new_(s3Prot, CSS3Protocol());
 
73
        s3Prot->s3_setServer(server);
 
74
        s3Prot->s3_setPublicKey(publicKey);
 
75
        s3Prot->s3_setPrivateKey(privateKey);
 
76
        
 
77
        bucket = CSString::newString(bucket_arg);               
 
78
}
 
79
                
 
80
//-------------------------------
 
81
MSCloudInfo::~MSCloudInfo()
 
82
{
 
83
        if (bucket)
 
84
                bucket->release();
 
85
                
 
86
        if (s3Prot)
 
87
                s3Prot->release();
 
88
}
 
89
        
 
90
//-------------------------------
 
91
const char *MSCloudInfo::getServer() 
 
92
 
93
        return s3Prot->s3_getServer();
 
94
}
 
95
 
 
96
//-------------------------------
 
97
const char *MSCloudInfo::getBucket() 
 
98
 
99
        return bucket->getCString();
 
100
}
 
101
 
 
102
//-------------------------------
 
103
const char *MSCloudInfo::getPublicKey() 
 
104
 
105
        return s3Prot->s3_getPublicKey();
 
106
}
 
107
 
 
108
//-------------------------------
 
109
const char *MSCloudInfo::getPrivateKey() 
 
110
 
111
        return s3Prot->s3_getPrivateKey();
 
112
}
 
113
 
 
114
//-------------------------------
 
115
CSString *MSCloudInfo::getSignature(const char *key, const char *content_type, uint32_t *s3AuthorizationTime)
 
116
{
 
117
        return s3Prot->s3_getAuthorization(bucket->getCString(), key, content_type, s3AuthorizationTime);
 
118
}
 
119
 
 
120
//-------------------------------
 
121
CSString *MSCloudInfo::getDataURL(const char *key, int keep_alive)
 
122
{
 
123
        return s3Prot->s3_getDataURL(bucket->getCString(), key, keep_alive);
 
124
}
 
125
 
 
126
//-------------------------------
 
127
void MSCloudInfo::send(CSInputStream *input, const char *key, off64_t size)
 
128
{
 
129
        CSVector *headers;
 
130
        headers = s3Prot->s3_send(input, bucket->getCString(), key, size);
 
131
        headers->release();
 
132
}
 
133
 
 
134
//-------------------------------
 
135
CSVector *MSCloudInfo::list(const char *key_prefix, uint32_t max)
 
136
{
 
137
        return s3Prot->s3_list(bucket->getCString(), key_prefix, max);
 
138
}
 
139
 
 
140
//-------------------------------
 
141
void MSCloudInfo::receive(CSOutputStream *output, const char *key)
 
142
{
 
143
        bool found;
 
144
        CSVector *headers;
 
145
        
 
146
        headers = s3Prot->s3_receive(output, bucket->getCString(), key, &found);
 
147
        headers->release();
 
148
        if (!found) {
 
149
                CSStringBuffer *err;
 
150
                enter_();
 
151
                
 
152
                new_(err, CSStringBuffer());
 
153
                push_(err);
 
154
                err->append("S3 object not found: ");
 
155
                err->append(getServer());
 
156
                err->append("/");
 
157
                err->append(bucket->getCString());
 
158
                err->append("/");
 
159
                err->append(key);
 
160
 
 
161
                CSException::throwException(CS_CONTEXT, CS_ERR_GENERIC_ERROR, err->getCString());
 
162
                release_(err);
 
163
                outer_();
 
164
        }
 
165
}
 
166
 
 
167
//-------------------------------
 
168
void MSCloudInfo::cDelete(const char *key)
 
169
{
 
170
        s3Prot->s3_delete(bucket->getCString(), key);
 
171
}
 
172
 
 
173
//-------------------------------
 
174
void MSCloudInfo::copy(MSCloudInfo *dst_cloud, const char *dst_key, const char *src_key)
 
175
{
 
176
        enter_();
 
177
        push_(dst_cloud);
 
178
        
 
179
        s3Prot->s3_copy(dst_cloud->getServer() ,dst_cloud->bucket->getCString(), dst_key, bucket->getCString(), src_key);
 
180
 
 
181
        release_(dst_cloud);
 
182
        exit_();
 
183
}
 
184
 
 
185
//==============================
 
186
CloudDB::CloudDB(uint32_t db_id):
 
187
        dfltCloudRefId(0),
 
188
        keep_alive(5 * 60),// default URL keep alive in seconds.
 
189
        blob_recovery_no(0),
 
190
        blob_db_id(db_id),
 
191
        isBackup(false),
 
192
        backupInfo(NULL),
 
193
        backupCloud(NULL),
 
194
        clObjectKey(NULL)
 
195
{
 
196
        enter_();
 
197
 
 
198
        new_(clObjectKey, CSStringBuffer());
 
199
        clObjectKey->setLength(base_key_size);
 
200
                
 
201
        exit_();
 
202
}
 
203
 
 
204
//-------------------------------
 
205
CloudDB::~CloudDB()
 
206
{
 
207
        
 
208
        if (backupInfo)
 
209
                backupInfo->release();
 
210
                
 
211
        if (backupCloud)
 
212
                backupCloud->release();
 
213
                
 
214
        if (clObjectKey)
 
215
                clObjectKey->release();
 
216
                
 
217
}
 
218
//-------------------------------
 
219
MSBackupInfo *CloudDB::cl_getBackupInfo()
 
220
 
221
        if (backupInfo)
 
222
                backupInfo->retain();
 
223
                
 
224
        return backupInfo;
 
225
}
 
226
 
 
227
//-------------------------------
 
228
void CloudDB::cl_clearBackupInfo(){ backupInfo->release(); backupInfo = NULL;}
 
229
 
 
230
//-------------------------------
 
231
void CloudDB::cl_createDB()
 
232
{
 
233
// This is a no-op. 
 
234
}
 
235
 
 
236
//-------------------------------
 
237
// Restore all the 
 
238
void CloudDB::cl_restoreDB()
 
239
{
 
240
        CSVector *list = NULL;
 
241
        CSString *key = NULL;
 
242
        CloudObjectKey *src_objectKey = NULL, *dst_objectKey = NULL;
 
243
        CloudKeyRec             cloudKey;
 
244
        uint32_t                src_cloudRef, dst_cloudRef = 0;
 
245
        MSBackupInfo    *backup_info = NULL;
 
246
        MSCloudInfo             *src_cloud = NULL, *dst_cloud = NULL;
 
247
        enter_();
 
248
 
 
249
        if (!blob_recovery_no)
 
250
                exit_(); // nothing to do.
 
251
 
 
252
        backup_info = MSBackupInfo::getBackupInfo(blob_recovery_no);
 
253
        push_(backup_info);
 
254
        
 
255
        src_cloudRef = backup_info->getcloudRef();
 
256
        src_cloud = MSCloudInfo::getCloudInfo(src_cloudRef);
 
257
        push_(src_cloud);
 
258
        
 
259
        new_(dst_objectKey, CloudObjectKey(blob_db_id));
 
260
        push_(dst_objectKey);
 
261
        
 
262
        // Get the key for the backup BLOB
 
263
        new_(src_objectKey, CloudObjectKey(blob_db_id));
 
264
        push_(src_objectKey);
 
265
        src_objectKey->setObjectKey(NULL, backup_info->getcloudBackupNo(), backup_info->getDatabaseId()); 
 
266
 
 
267
        // Get a list of all the BLOBs that were backed up.
 
268
        list = src_cloud->list(src_objectKey->getCString());
 
269
        release_(src_objectKey);
 
270
        push_(list);
 
271
        
 
272
        // Go through the list copying the keys.
 
273
        try_(a) {
 
274
                dst_cloudRef = src_cloudRef;
 
275
                dst_cloud = src_cloud;
 
276
                dst_cloud->retain();
 
277
        
 
278
                while ((key = (CSString*)(list->take(0))) ) {
 
279
                        push_(key);
 
280
 
 
281
                        // The source key name must be parsed to get its
 
282
                        // destination cloud reference. The destination for
 
283
                        // the BLOBs may not all be in the same cloud. 
 
284
                        CloudObjectKey::parseObjectKey(key->getCString(), &cloudKey);
 
285
                        
 
286
                        // Reset the destination cloud if required.
 
287
                        if (cloudKey.cloud_ref != dst_cloudRef) {
 
288
                                if (dst_cloud) {
 
289
                                        dst_cloud->release();
 
290
                                        dst_cloud = NULL;
 
291
                                }
 
292
                                dst_cloudRef =  cloudKey.cloud_ref;
 
293
                                dst_cloud = MSCloudInfo::getCloudInfo(dst_cloudRef);
 
294
                        }
 
295
 
 
296
                        // Copy the BLOB to the recovered database.
 
297
                        dst_objectKey->setObjectKey(&cloudKey);
 
298
                        src_cloud->copy(RETAIN(dst_cloud), dst_objectKey->getCString(), key->getCString());
 
299
                        release_(key);
 
300
                        
 
301
                }
 
302
        }
 
303
        
 
304
        finally_(a) {
 
305
                if (dst_cloud)
 
306
                        dst_cloud->release();
 
307
        }
 
308
        finally_end_block(a);
 
309
        
 
310
        blob_recovery_no = 0;
 
311
        release_(list);
 
312
        release_(dst_objectKey);        
 
313
        release_(src_cloud);
 
314
        release_(backup_info);
 
315
        exit_();        
 
316
}
 
317
 
 
318
//-------------------------------
 
319
uint32_t CloudDB::cl_getNextBackupNumber(uint32_t cloud_ref)
 
320
{
 
321
        CloudObjectKey *objectKey;
 
322
        CSVector *list;
 
323
        uint32_t backup_no = 0, size = 1;
 
324
        MSCloudInfo *s3Cloud;
 
325
        enter_();
 
326
 
 
327
        s3Cloud = MSCloudInfo::getCloudInfo((cloud_ref)?cloud_ref:dfltCloudRefId);
 
328
        push_(s3Cloud);
 
329
        
 
330
        new_(objectKey, CloudObjectKey(blob_db_id));
 
331
        push_(objectKey);
 
332
 
 
333
        // Find the next available backup number
 
334
        while (size) {
 
335
                backup_no++;
 
336
                objectKey->setObjectKey(NULL, backup_no); // use the key prefix with the backup number for listing.
 
337
                list = s3Cloud->list(objectKey->getCString(), 1);
 
338
                size = list->size();
 
339
                list->release();
 
340
        }
 
341
        
 
342
        release_(objectKey);
 
343
        release_(s3Cloud);
 
344
 
 
345
        return_(backup_no);
 
346
}
 
347
 
 
348
//-------------------------------
 
349
void CloudDB::cl_backupBLOB(CloudKeyPtr key)
 
350
{
 
351
        CloudObjectKey *src_objectKey, *dst_objectKey;
 
352
        uint32_t cloudRef, backupNo;
 
353
        MSCloudInfo *src_cloud = NULL, *dst_cloud = NULL;
 
354
        enter_();
 
355
 
 
356
        ASSERT(backupInfo);
 
357
        
 
358
        if ((cloudRef = backupInfo->getcloudRef()) == 0) {
 
359
                backupInfo->setcloudRef(dfltCloudRefId);
 
360
                cloudRef = dfltCloudRefId;
 
361
        }
 
362
                
 
363
        if ((backupNo = backupInfo->getcloudBackupNo()) == 0) {         
 
364
                backupNo = cl_getNextBackupNumber(cloudRef);
 
365
                backupInfo->setcloudBackupNo(backupNo);
 
366
        }
 
367
        
 
368
        // Set the source object's key
 
369
        new_(src_objectKey, CloudObjectKey(blob_db_id));
 
370
        push_(src_objectKey);
 
371
        src_objectKey->setObjectKey(key);
 
372
 
 
373
        // Set the destination object's key
 
374
        new_(dst_objectKey, CloudObjectKey(blob_db_id));
 
375
        push_(dst_objectKey);
 
376
        dst_objectKey->setObjectKey(key, backupNo);
 
377
 
 
378
        // Get the source cloud
 
379
        src_cloud = MSCloudInfo::getCloudInfo((key->cloud_ref)?key->cloud_ref:dfltCloudRefId);
 
380
        push_(src_cloud);
 
381
        
 
382
        // Copy the object to the destination cloud
 
383
        dst_cloud = MSCloudInfo::getCloudInfo(cloudRef);
 
384
        src_cloud->copy(dst_cloud, dst_objectKey->getCString(), src_objectKey->getCString());
 
385
 
 
386
        release_(src_cloud);
 
387
        release_(dst_objectKey);
 
388
        release_(src_objectKey);
 
389
        exit_();
 
390
}
 
391
 
 
392
//-------------------------------
 
393
void CloudDB::cl_restoreBLOB(CloudKeyPtr key, uint32_t backup_db_id)
 
394
{
 
395
        CloudObjectKey *src_objectKey, *dst_objectKey;
 
396
        uint32_t cloudRef, backupNo;
 
397
        MSCloudInfo *src_cloud = NULL, *dst_cloud = NULL;
 
398
        enter_();
 
399
 
 
400
        ASSERT(backupInfo);
 
401
        
 
402
        if ((cloudRef = backupInfo->getcloudRef()) == 0) {
 
403
                backupInfo->setcloudRef(dfltCloudRefId);
 
404
                cloudRef = dfltCloudRefId;
 
405
        }
 
406
                
 
407
        if ((backupNo = backupInfo->getcloudBackupNo()) == 0) {         
 
408
                backupNo = cl_getNextBackupNumber(cloudRef);
 
409
                backupInfo->setcloudBackupNo(backupNo);
 
410
        }
 
411
        
 
412
        // Set the source object's key
 
413
        new_(src_objectKey, CloudObjectKey(backup_db_id));
 
414
        push_(src_objectKey);
 
415
        src_objectKey->setObjectKey(key, backupNo);
 
416
 
 
417
        // Set the destination object's key
 
418
        new_(dst_objectKey, CloudObjectKey(blob_db_id));
 
419
        push_(dst_objectKey);
 
420
        dst_objectKey->setObjectKey(key);
 
421
 
 
422
        // Get the source cloud
 
423
        src_cloud = MSCloudInfo::getCloudInfo(cloudRef);
 
424
        push_(src_cloud);
 
425
        
 
426
        // Copy the object to the destination cloud
 
427
        dst_cloud = MSCloudInfo::getCloudInfo((key->cloud_ref)?key->cloud_ref:dfltCloudRefId);
 
428
        src_cloud->copy(dst_cloud, dst_objectKey->getCString(), src_objectKey->getCString());
 
429
 
 
430
        release_(src_cloud);
 
431
        release_(dst_objectKey);
 
432
        release_(src_objectKey);
 
433
        exit_();
 
434
}
 
435
 
 
436
//-------------------------------
 
437
// Drop database deletes all objects with the database key prefix
 
438
void CloudDB::cl_dropDB()
 
439
{
 
440
        CSVector *list;
 
441
        CSString *key;
 
442
        CloudObjectKey *objectKey;      
 
443
        MSCloudInfo *s3Cloud = NULL;
 
444
        int i;
 
445
        const char *key_str;
 
446
        
 
447
        enter_();
 
448
        new_(objectKey, CloudObjectKey(blob_db_id));
 
449
        push_(objectKey);
 
450
        
 
451
        lock_(MSCloudInfo::gCloudInfo);
 
452
 
 
453
        if (isBackup) {
 
454
                uint32_t backup_no;
 
455
                if (backupInfo && (backup_no = backupInfo->getcloudBackupNo())) {
 
456
                        objectKey->setObjectKey(NULL, backup_no); // use the key prefix for the backup for listing.
 
457
                        if ((s3Cloud = MSCloudInfo::getCloudInfo(backupInfo->getcloudRef())))
 
458
                                push_(s3Cloud);
 
459
                }
 
460
        } else {
 
461
                objectKey->setObjectKey(); // use the key prefix for listing.
 
462
                i = 0;
 
463
                s3Cloud = (MSCloudInfo*)MSCloudInfo::gCloudInfo->itemAt(i++); // <-- unreferenced object 
 
464
        }
 
465
                
 
466
        key_str = objectKey->getCString();
 
467
 
 
468
        // For non backup BLOBs all known clouds must be searched 
 
469
        // for possible BLOBs and deleted. The BLOBs belonging to a backup
 
470
        // will ever only be in one cloud storage location.
 
471
        while (s3Cloud) {
 
472
                list = s3Cloud->list(key_str);
 
473
                push_(list);
 
474
                
 
475
                // Go through the list deleting the keys.
 
476
                while ((key = (CSString*)(list->take(0))) ) {
 
477
                        push_(key);
 
478
                        s3Cloud->cDelete(key->getCString());
 
479
                        release_(key);
 
480
                }
 
481
                
 
482
                release_(list);
 
483
                if (isBackup) {
 
484
                        release_(s3Cloud); // Only the backup s3Cloud needs to be released.
 
485
                        s3Cloud = NULL;
 
486
                } else
 
487
                        s3Cloud = (MSCloudInfo*)MSCloudInfo::gCloudInfo->itemAt(i++);// <-- unreferenced object
 
488
        }
 
489
        
 
490
        unlock_(MSCloudInfo::gCloudInfo);
 
491
        release_(objectKey);
 
492
        exit_();
 
493
}
 
494
 
 
495
//-------------------------------
 
496
void CloudDB::cl_putData(CloudKeyPtr key, CSInputStream *stream, off64_t size)
 
497
{
 
498
        CloudObjectKey *objectKey;
 
499
        MSCloudInfo *s3Cloud;
 
500
        
 
501
        enter_();
 
502
        
 
503
        push_(stream);
 
504
        
 
505
        new_(objectKey, CloudObjectKey(blob_db_id));
 
506
        push_(objectKey);
 
507
        
 
508
        objectKey->setObjectKey(key);
 
509
        
 
510
        s3Cloud = MSCloudInfo::getCloudInfo((key->cloud_ref)?key->cloud_ref:dfltCloudRefId);
 
511
        push_(s3Cloud);
 
512
        s3Cloud->send(RETAIN(stream), objectKey->getCString(), size);
 
513
        release_(s3Cloud);
 
514
        
 
515
        release_(objectKey);
 
516
        release_(stream);
 
517
        
 
518
        exit_();
 
519
}
 
520
 
 
521
//-------------------------------
 
522
off64_t CloudDB::cl_getData(CloudKeyPtr key,  char *buffer, off64_t size)
 
523
{       
 
524
        CloudObjectKey *objectKey;
 
525
        CSStaticMemoryOutputStream *output;
 
526
        MSCloudInfo *s3Cloud;
 
527
        enter_();
 
528
        
 
529
        new_(objectKey, CloudObjectKey(blob_db_id));
 
530
        push_(objectKey);
 
531
        
 
532
        s3Cloud = MSCloudInfo::getCloudInfo(key->cloud_ref);
 
533
        push_(s3Cloud);
 
534
 
 
535
        new_(output, CSStaticMemoryOutputStream((u_char *)buffer, size));
 
536
        push_(output);
 
537
        
 
538
        objectKey->setObjectKey(key);
 
539
        
 
540
        s3Cloud->receive(RETAIN(output), objectKey->getCString());      
 
541
        size = output->getSize();
 
542
        release_(output);
 
543
        
 
544
        release_(s3Cloud);
 
545
        release_(objectKey);
 
546
        return_(size);
 
547
}
 
548
 
 
549
//-------------------------------
 
550
void CloudDB::cl_deleteData(CloudKeyPtr key)
 
551
{
 
552
        MSCloudInfo *s3Cloud;
 
553
        CloudObjectKey *objectKey;
 
554
        enter_();
 
555
        
 
556
        new_(objectKey, CloudObjectKey(blob_db_id));
 
557
        push_(objectKey);
 
558
        
 
559
        s3Cloud = MSCloudInfo::getCloudInfo(key->cloud_ref);
 
560
        push_(s3Cloud);
 
561
 
 
562
        objectKey->setObjectKey(key);
 
563
 
 
564
        s3Cloud->cDelete(objectKey->getCString());      
 
565
        
 
566
        release_(s3Cloud);
 
567
        release_(objectKey);
 
568
 
 
569
        exit_();
 
570
}
 
571
 
 
572
//-------------------------------
 
573
CSString *CloudDB::cl_getDataURL(CloudKeyPtr key)
 
574
{
 
575
        CloudObjectKey *objectKey;
 
576
        CSString *url;
 
577
        MSCloudInfo *s3Cloud;
 
578
        enter_();
 
579
        
 
580
        new_(objectKey, CloudObjectKey(blob_db_id));
 
581
        push_(objectKey);
 
582
        
 
583
        objectKey->setObjectKey(key);
 
584
        
 
585
        s3Cloud = MSCloudInfo::getCloudInfo(key->cloud_ref);  
 
586
        push_(s3Cloud);
 
587
                
 
588
        url = s3Cloud->getDataURL(objectKey->getCString(), keep_alive);
 
589
        
 
590
        release_(s3Cloud);
 
591
        release_(objectKey);
 
592
 
 
593
        return_(url);
 
594
}
 
595
 
 
596
//-------------------------------
 
597
CSString *CloudDB::cl_getSignature(CloudKeyPtr key, CSString *content_type_arg, uint32_t *s3AuthorizationTime)
 
598
{
 
599
        CSString *signature;
 
600
        CloudObjectKey *objectKey;
 
601
        const char *content_type = NULL;
 
602
        MSCloudInfo *s3Cloud;
 
603
        enter_();
 
604
        
 
605
        new_(objectKey, CloudObjectKey(blob_db_id));
 
606
        push_(objectKey);
 
607
        
 
608
        if (content_type_arg) {
 
609
                push_(content_type_arg);
 
610
                content_type = content_type_arg->getCString();
 
611
        }
 
612
        
 
613
        objectKey->setObjectKey(key);
 
614
        s3Cloud = MSCloudInfo::getCloudInfo(key->cloud_ref);  
 
615
        push_(s3Cloud);
 
616
        
 
617
        signature = s3Cloud->getSignature(objectKey->getCString(), content_type, s3AuthorizationTime);
 
618
        
 
619
        if (content_type_arg) 
 
620
                release_(content_type_arg);
 
621
 
 
622
        release_(s3Cloud);
 
623
        release_(objectKey);
 
624
        
 
625
        return_(signature);
 
626
}
 
627
 
 
628
//==============================
 
629