00001 #pragma once
00002 #ifndef __CLOUD_H__
00003 #define __CLOUD_H__
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "cslib/CSMd5.h"
00026 #include <inttypes.h>
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 class CSS3Protocol;
00040 class MSCloudInfo : public CSRefObject {
00041 private:
00042 static uint32_t gMaxInfoRef;
00043 static CSSyncSparseArray *gCloudInfo;
00044
00045 friend class MSCloudTable;
00046 friend class CloudDB;
00047
00048 private:
00049 uint32_t cloudRefId;
00050 CSString *bucket;
00051 CSS3Protocol *s3Prot;
00052
00053 public:
00054
00055 static void startUp()
00056 {
00057 new_(gCloudInfo, CSSyncSparseArray(5));
00058 gMaxInfoRef = 0;
00059 }
00060
00061 static void shutDown()
00062 {
00063 if (gCloudInfo) {
00064 gCloudInfo->clear();
00065 gCloudInfo->release();
00066 gCloudInfo = NULL;
00067 }
00068 }
00069
00070
00071 static MSCloudInfo *getCloudInfo(uint32_t in_cloudRefId)
00072 {
00073 MSCloudInfo *info;
00074 enter_();
00075
00076 lock_(gCloudInfo);
00077
00078 info = (MSCloudInfo *) gCloudInfo->get(in_cloudRefId);
00079 if (!info) {
00080 char msg[80];
00081 snprintf(msg, 80, "Cloud info with reference ID %"PRIu32" not found", in_cloudRefId);
00082 CSException::throwException(CS_CONTEXT, CS_ERR_GENERIC_ERROR, msg);
00083 }
00084 info->retain();
00085 unlock_(gCloudInfo);
00086 return_(info);
00087 }
00088
00089 MSCloudInfo(uint32_t id, const char *server, const char *bucket, const char *publicKey, const char *privateKey );
00090 ~MSCloudInfo();
00091
00092 uint32_t getCloudRefId() { return cloudRefId;}
00093
00094 const char *getServer();
00095
00096 const char *getBucket();
00097
00098 const char *getPublicKey();
00099
00100 const char *getPrivateKey();
00101
00102 CSString *getSignature(const char *key, const char *content_type, uint32_t *s3AuthorizationTime);
00103
00104 CSString *getDataURL(const char *key, int keep_alive);
00105
00106 void send(CSInputStream *input, const char *key, off64_t size);
00107
00108 void receive(CSOutputStream *output, const char *key);
00109
00110 void copy(MSCloudInfo *dst_cloud, const char *dst_key, const char *src_key);
00111
00112 void cDelete(const char *key);
00113
00114 CSVector *list(const char *key_prefix, uint32_t max = 0);
00115 };
00116
00117 typedef struct CloudKey {
00118 uint32_t creation_time;
00119 uint32_t ref_index;
00120 uint32_t cloud_ref;
00121 } CloudKeyRec, *CloudKeyPtr;
00122
00123
00124
00125 class CloudObjectKey : public CSStringBuffer
00126 {
00127 uint32_t default_db_id;
00128
00129 public:
00130 CloudObjectKey(uint32_t id): CSStringBuffer(), default_db_id(id){ }
00131 ~CloudObjectKey(){}
00132
00133 static const uint32_t base_key_size = 64;
00134
00135 void setObjectKey(const char *object_key)
00136 {
00137 setLength(base_key_size + strlen(object_key) +1);
00138
00139 snprintf(getBuffer(0), length(), "%"PRIu32"/0/%s",default_db_id, object_key);
00140 }
00141
00142 void setObjectKey(CloudKeyPtr key = NULL, uint32_t backup_id = 0, uint32_t db_id = 0)
00143 {
00144 if (!db_id) db_id = default_db_id;
00145 setLength(base_key_size);
00146
00147 if (key)
00148 snprintf(getBuffer(0), length(), "%"PRIu32"/%"PRIu32"/%"PRIu32".%"PRIu32".%"PRIu32"", db_id, backup_id, key->cloud_ref, key->creation_time, key->ref_index);
00149 else
00150 snprintf(getBuffer(0), length(), "%"PRIu32"/%"PRIu32"s/", db_id, backup_id);
00151
00152 }
00153
00154 static void parseObjectKey(const char *object_key, CloudKeyPtr key, uint32_t *backup_id = NULL, uint32_t *db_id = NULL)
00155 {
00156 uint32_t v1;
00157
00158 if (!backup_id) backup_id = &v1;
00159 if (!db_id) db_id = &v1;
00160
00161 sscanf(object_key, "%"PRIu32"/%"PRIu32"/%"PRIu32".%"PRIu32".%"PRIu32"", db_id, backup_id, &(key->cloud_ref), &(key->creation_time), &(key->ref_index));
00162 }
00163 };
00164
00165
00166 class MSBackupInfo;
00167 class CloudDB: public CSRefObject {
00168
00169 private:
00170 static uint32_t gKeyIndex;
00171 static CSMutex gCloudKeyLock;
00172
00173 uint32_t dfltCloudRefId;
00174
00175 uint32_t keep_alive;
00176 uint32_t blob_recovery_no;
00177 uint32_t blob_db_id;
00178
00179 bool isBackup;
00180 MSBackupInfo *backupInfo;
00181 MSCloudInfo *backupCloud;
00182
00183 static const uint32_t base_key_size = 64;
00184
00185 public:
00186 CSStringBuffer *clObjectKey;
00187
00188 CloudDB(uint32_t db_id);
00189 ~CloudDB();
00190
00191 void cl_setDefaultCloudRef(uint32_t dflt) { dfltCloudRefId = dflt;}
00192 uint32_t cl_getDefaultCloudRef() { return dfltCloudRefId;}
00193
00194 MSCloudInfo *cl_getCloudInfo(uint32_t cloudRefId = 0)
00195 {
00196 return MSCloudInfo::getCloudInfo((cloudRefId)?cloudRefId:dfltCloudRefId);
00197 }
00198
00199 void cl_getNewKey(CloudKeyPtr key)
00200 {
00201 enter_();
00202 lock_(&gCloudKeyLock);
00203
00204 key->creation_time = time(NULL);
00205 key->ref_index = gKeyIndex++;
00206 key->cloud_ref = dfltCloudRefId;
00207
00208 unlock_(&gCloudKeyLock);
00209 exit_();
00210 }
00211
00212 bool cl_mustRecoverBlobs() { return (blob_recovery_no != 0);}
00213
00214 void cl_setRecoveryNumber(const char *number)
00215 {
00216 blob_recovery_no = atol(number);
00217 }
00218
00219 const char *cl_getRecoveryNumber()
00220 {
00221 static char number[20];
00222
00223 snprintf(number, 20, "%"PRIu32"", blob_recovery_no);
00224 return number;
00225 }
00226
00227 CSString *cl_getObjectKey(CloudKeyPtr key)
00228 {
00229 CloudObjectKey *objectKey;
00230 enter_();
00231
00232 new_(objectKey, CloudObjectKey(blob_db_id));
00233 push_(objectKey);
00234
00235 objectKey->setObjectKey(key);
00236
00237 CSString *str = CSString::newString(objectKey->getCString());
00238 release_(objectKey);
00239
00240 return_(str);
00241 }
00242
00243 void cl_setKeepAlive(uint32_t keep_alive_arg) {keep_alive = keep_alive_arg;}
00244
00245 void cl_createDB();
00246 void cl_dropDB();
00247 void cl_restoreDB();
00248 uint32_t cl_getNextBackupNumber(uint32_t cloud_ref = 0);
00249 bool cl_dbExists();
00250
00251
00252 void cl_setCloudIsBackup(){ isBackup = true;}
00253 void cl_setBackupInfo(MSBackupInfo *info){ backupInfo = info;}
00254 MSBackupInfo *cl_getBackupInfo();
00255 void cl_clearBackupInfo();
00256
00257 void cl_backupBLOB(CloudKeyPtr key);
00258 void cl_restoreBLOB(CloudKeyPtr key, uint32_t backup_db_id);
00259
00260 void cl_putData( CloudKeyPtr key, CSInputStream *stream, off64_t size);
00261 off64_t cl_getData(CloudKeyPtr key, char *data, off64_t size);
00262 CSString *cl_getDataURL(CloudKeyPtr key);
00263 void cl_deleteData(CloudKeyPtr key);
00264 CSString *cl_getSignature(CloudKeyPtr key, CSString *content_type, uint32_t *s3AuthorizationTime);
00265
00266 };
00267
00268 #endif // __CLOUD_H__