update20140630

This commit is contained in:
stubbfel
2014-06-30 13:58:10 +02:00
parent 565970632e
commit 1e6cf42df3
877 changed files with 1146249 additions and 0 deletions

View File

@@ -0,0 +1,477 @@
/*
* File: DropBoxProvider.cc
* Author: jgaebler
*
* Created on April 26, 2012, 3:27 PM
*/
#include "DropBoxProvider.h"
#include "Dispatcher.h"
#include "common/container/PeerIDList.h"
#include "common/time/GenericTime.h"
#include "mob/sync/cloud/transfer/TransferContainer.h"
#include "mob/sync/cloud/transfer/TransferMessage.h"
#include "mob/sync/cloud/transfer/TransferSerializer.h"
#include "common/util/StringUtil.h"
#include "common/container/StringList.h"
#if OMNETPP
#include "../../opt/json-c-0.10/include/json/json.h"
#include <oauth.h>
#include <curl/curl.h>
#endif
#include "Moversight.h"
#include <ctime>
#include <stdlib.h>
#undef DEBUG
#define DEBUG(msg) if (module.isPrintDebugDIS()) MOV_DEBUG << "DBP@" << dispatcher.getMembershipService().getLocalID()<< " "<<msg<<endl;
namespace ubeeme {
namespace moversight {
//Dropbox API and OAuth-Keys
const std::string DropBoxProvider::APP_KEY = "bv3uv5q2t9qbqse";
const std::string DropBoxProvider::APP_SECRET = "wbo2ieyzvvejrpz";
// oauth_token and oauth_token_secret created by the scripted gettoken.py
const std::string DropBoxProvider::OAUTH_TOKEN_SECRET = "negr39cwhxsuc4z";
const std::string DropBoxProvider::OAUTH_TOKEN = "jhht95nex1gpapz";
const std::string DropBoxProvider::META_DATA_FILE_NAME_PREFIX = "globalmetadata";
const std::string DropBoxProvider::FILE_TYPE = "dat";
/**
* @brief Constructor
* @param dis A reference to the dispatcher
* @param mov A reference to the moversight module
*/
DropBoxProvider::DropBoxProvider(Dispatcher & dis, Moversight & mov) : CloudProvider(dis, mov), counter(0) {
}
/**
* @brief Destructor
*/
DropBoxProvider::~DropBoxProvider() {
}
/**
* @brief Puts the given data into the cloud.
* @param uploadData The data to upload.
* @param uPID The id of the uploading peer.
* @param fileName The name of the file that stores the data.
*/
void
DropBoxProvider::upload(ByteArray & uploadData, PeerID uPID, std::string fileName) {
#if OMNETPP
if (uploadData.size() > 0) {
//std::cerr<< "upload - file name " << fileName<<endl;
std::string url = buildUploadUrl(uPID, fileName);
//@TOOD find a better solution
const char * postData = reinterpret_cast<const char*> (&uploadData[0]);
char * reply;
reply = oauth_post_data(url.c_str(),
postData,
uploadData.size(),
"Content-Type: application/json");
//@TODO check reply for errors and propaged it
//std::cout << "reply: " << reply << std::endl;
if (reply) free(reply);
}//End if
#endif
}
/**
* @brief Creates the url for the file upload to dropbox
* @param id The id of the peer which has created the first folder in the dropbox.
* @param fileName The name of the file to store
* @return The build url.
*/
std::string
DropBoxProvider::buildUploadUrl(PeerID id, std::string fileName) {
std::string s_time = StringUtil::int2String(std::time(NULL));
std::string folder = StringUtil::int2String(id);
#if OMNETPP
char * nonce = oauth_gen_nonce();
// Building Upload url
std::string url = "https://api-content.dropbox.com/1/files_put/sandbox/" + folder;
url += "/" + fileName + "." + FILE_TYPE;
std::string a(url);
a += "?oauth_nonce=" + std::string(nonce) + "?overwrite=false";
a += "&oauth_timestamp=" + s_time + "&oauth_consumer_key=" + APP_KEY;
a += "&oauth_signature_method=PLAINTEXT&oauth_version=1.0&oauth_token=" + OAUTH_TOKEN;
a += "&oauth_signature=" + APP_SECRET + "%26" + OAUTH_TOKEN_SECRET; // + "&overwrite=False";
if (nonce) free(nonce);
//char* signedUrl = oauth_sign_url2(url.c_str(), //request url
// NULL, //post arguments
// OA_HMAC, //oauth method OA_HMAC
// NULL, //http method (GET or POST), if NULL - auto detection
// APP_KEY.c_str(), //c_key
// APP_SECRET.c_str(), //c_secret
// OAUTH_TOKEN.c_str(), // t_key
// OAUTH_TOKEN_SECRET.c_str()); //t_secret
//std::cout << "UPLOAD URL: " << url << std::endl;
//std::cout << "SIGNED URL: " << signedUrl << std::endl;
//std::cout << "EXPECTED URL: "<< a <<std::endl;
//std::string t(signedUrl);
//free(signedUrl);
return a;
#else
return folder;
#endif
}
TransferContainerList
DropBoxProvider::downloadMessagesFromPeer(PeerID id) {
std::stringstream buf;
buf << "downloadMessagesFromPeer - peer " << id;
DEBUG(buf.str().c_str());
std::string metaDataUrl = buildMetaDataUrl(id);
TransferContainerList tcl;
#if OMNETPP
char * metaReply = oauth_http_get(metaDataUrl.c_str(), NULL);
if (metaReply != NULL) {
//extract the fileList from the reply
StringList filePathList;
StringList fileSizeList;
const std::string pathKey("path");
const std::string sizeKey("bytes");
json_object * jobj = json_tokener_parse(metaReply);
jsonParse(jobj, false, filePathList, pathKey.c_str());
jsonParse(jobj, false, fileSizeList, sizeKey.c_str());
//free the reply
free(metaReply);
//check, if the size of both lists equal
if (filePathList.size() != fileSizeList.size()) {
DEBUG("downloadMessagesFromPeer - error: the size of the retrieved path and file size lists are not consistent");
filePathList.clear();
}//End if
//retrieve the files
//skip paths, which consists only of the peer folder itself (the first entry)
//TODO FIX DOWNLOAD LIMIT (TO AVOID LONG DOWNLOADS)
std::cerr<<"DropBoxProvider: limit download to 4 files"<<endl;
for (size_t i = 1; i < filePathList.size() && i < 5; i++) {
DEBUG("retrieve from cloud: " + filePathList.get(i));
std::string fileUrl = buildDownloadUrl(filePathList.get(i));
struct MemoryStruct ms = performCurlDownload(fileUrl);
if (ms.size > 0) {
ByteArray loadedFile(ms.memory, ms.memory + ms.size);
TransferContainer tc;
tc.setPeerID(id);
if (TransferSerializer::deserialize(loadedFile, tc)) {
tcl.add(tc);
}//End if
else {
DEBUG("downloadMessagesFromPeer - error: de-serialize retrieved data failed.");
}//End else
//clean up
free(ms.memory);
}//End if
else {
DEBUG("downloadMessagesFromPeer - error: download failed.");
}//End else
}//End for
}//End if metaReply
#endif
return tcl;
}
/**
* @brief Determine the peers, which have stored messages in the cloud.
* @return The list of peers that have stored messages in the cloud.
*/
PeerIDList
DropBoxProvider::determineStoringPeers() {
// the dropbox api response with an json array
// the array is parsed with the json parser
// create the url for the metadata download
std::string mdurl = buildMetaDataUrl();
PeerIDList idList;
#if OMNETPP
char * reply = oauth_http_get(mdurl.c_str(), NULL);
if (reply != NULL) {
//list of peers which have stored messages in the cloud, filled by the json parser
StringList peerList;
std::string pathKey("path");
json_object * jobj = json_tokener_parse(reply);
//false
jsonParse(jobj, true, peerList, pathKey.c_str());
//have a peer messages stored in the cloud?
for (size_t i = 0; i < peerList.size(); i++) {
//we have at least one peer, which have stored messages in the cloud
//load the string of the peer ID
std::string client = peerList.get(i);
if (client != "") {
//convert the ID and store it in the list
idList.add(PeerID(atoi(client.c_str())));
}//End if
}//end while
free(jobj);
free(reply);
}//End if
#endif
return idList;
}
/*
* @brief The json array parser
* @note See joysofprogramming.com/json-c-libjson-tutorial/ for the
* source of the original code
*/
void
DropBoxProvider::jsonParseArray(json_object *jobj, char *key, bool parse, StringList & list, const char * param /* = "path" */) {
#if OMNETPP
enum json_type type;
//Simply get the array
json_object *jarray = jobj;
if (key) {
//Getting the array if it is a key value pair
jarray = json_object_object_get(jobj, key);
}
//Getting the length of the array
int arraylen = json_object_array_length(jarray);
int i;
json_object * jvalue;
for (i = 0; i < arraylen; i++) {
//Getting the array element at position i
jvalue = json_object_array_get_idx(jarray, i);
type = json_object_get_type(jvalue);
if (type == json_type_array) {
jsonParseArray(jvalue, NULL, false, list, param);
}
else {
jsonParse(jvalue, parse, list, param);
}
}
#endif
}
/*
* @brief The json object parser
* @note base on joysofprogramming.com/json-c-libjson-tutorial/
*
* @param jobj The object to parse
* @param parse Enable parsing
* @param param The parameter to parse
* @param list The list of the resulting tokens, with match to the key
* "path" within the JSON response
*/
void
DropBoxProvider::jsonParse(json_object * jobj, bool /* parse */, StringList & list, const char * param /* = "path" */) {
#if OMNETPP
enum json_type type;
//Passing through every array element
json_object_object_foreach(jobj, key, val) {
type = json_object_get_type(val);
switch (type) {
case json_type_string:
if (strcmp(key, param) == 0) {
std::string client = json_object_get_string(val);
list.add(client.substr(1));
}
break;
case json_type_array:
if (strcmp(key, "contents") == 0) {
jsonParseArray(jobj, key, true, list, param);
}
break;
case json_type_int:
if (strcmp(key, param) == 0) {
int intVal = json_object_get_int(val);
list.add(StringUtil::int2String(intVal));
}
default:
{
//json_type_boolean
//json_type_double
//json_type_object
}
}
}
#endif
}
/*
* @brief Creates the url for requesting the meta data for the path "path"
* @return The build url.
*/
std::string
DropBoxProvider::buildMetaDataUrl() {
return buildMetaDataUrl(UNDEFINED_PEER_ID);
}
/*
* @brief Creates the url for requesting the meta data for the given peer
* ID. If the id equals to UNDEFINED_PEER_ID, the path is set to empty;
* @param id The id of the uploading peer.
* @return The build url.
*/
std::string
DropBoxProvider::buildMetaDataUrl(PeerID id) {
std::string path;
if (id != UNDEFINED_PEER_ID) {
path = path + StringUtil::int2String(id) + "/";
}
return buildMetaDataUrl(path);
}
/*
* @brief Creates the url for requesting the meta data for the path.
* @param path The path to set
* @return The build url.
*/
std::string
DropBoxProvider::buildMetaDataUrl(std::string path) {
#if OMNETPP
char * nonce = oauth_gen_nonce();
std::string url = "https://api.dropbox.com/1/metadata/sandbox/" + path + "?oauth_nonce="
+ std::string(nonce) + "&oauth_timestamp=" + StringUtil::int2String(std::time(NULL)) + "&file_limit=10000&list=true"
+ "&oauth_consumer_key=" + APP_KEY + "&oauth_signature_method=PLAINTEXT&include_deleted=False&oauth_version=1.0&"
+ "&oauth_token=" + OAUTH_TOKEN + "&oauth_signature=" + APP_SECRET + "%26" + OAUTH_TOKEN_SECRET;
free(nonce);
return url;
#else
return "https://no.url.com";
#endif
}
/**
* @brief Creates the url for the file download from the dropbox.
* @param path The path to the file to download.
* @return The build url.
*/
std::string
DropBoxProvider::buildDownloadUrl(std::string path) {
int random = (rand() % 99999999 + 1) + 10000000;
std::string url = "https://api-content.dropbox.com/1/files/sandbox/" + path + "?oauth_nonce="
+ StringUtil::int2String(random) + "&oauth_timestamp=" + StringUtil::int2String(std::time(NULL))
+ "&oauth_consumer_key=" + APP_KEY + "&oauth_signature_method=PLAINTEXT&oauth_version=1.0&"
+ "&oauth_token=" + OAUTH_TOKEN + "&oauth_signature=" + APP_SECRET + "%26" + OAUTH_TOKEN_SECRET;
return url;
}
/**
* @brief Retrieves a curl fetch operation and returns a chunk of memory,
* which stores the retrieved file.
* @param url The url of the message to fetch
* @return The memory struct, which stores the retrieved file content.
* @note The memory of the MemoryStruct chunk have to be cleaned by the caller
* @see http://curl.haxx.se/libcurl/c/getinmemory.html
*/
struct MemoryStruct
DropBoxProvider::performCurlDownload(std::string url) {
//init the memory area to store the meta data
MemoryStruct chunk;
chunk.memory = (char*) malloc(1);
chunk.size = 0;
#if OMNETPP
//build the curl request for the metadata upload
//and perform the request
CURL* curl_handle;
curl_global_init(CURL_GLOBAL_ALL);
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writeMemoryCallback);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &chunk);
curl_easy_perform(curl_handle);
curl_easy_cleanup(curl_handle);
curl_global_cleanup();
#endif
return chunk;
}
/**
* @brief Callback for the curl library downloads
* @param contents The content to store
* @param size the size of the fetched content
* @param nmemb the size of the allocated memory
* @param userp the destination to store
* @return the value of the allocated memory
* @see http://curl.haxx.se/libcurl/c/getinmemory.html
*/
size_t
DropBoxProvider::writeMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) {
size_t realsize = size * nmemb;
MemoryStruct *mem = (MemoryStruct *) userp;
mem->memory = (char*) realloc(mem->memory, mem->size + realsize + 1);
if (mem->memory == NULL) {
// out of memory!
std::cerr << "not enough memory (realloc returned NULL)" << std::endl;
exit(EXIT_FAILURE);
}
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
}
}