// // A GET of the dealer resource produces a list of existing tables. // void BlackJackDealer::handle_get(http_request message) { ucout << message.to_string() << endl; auto paths = http::uri::split_path(http::uri::decode(message.relative_uri().path())); if (paths.empty()) { message.reply(status_codes::OK, TablesAsJSON(U("Available Tables"), s_tables)); return; } utility::string_t wtable_id = paths[0]; const utility::string_t table_id = wtable_id; // Get information on a specific table. auto found = s_tables.find(table_id); if (found == s_tables.end()) { message.reply(status_codes::NotFound); } else { message.reply(status_codes::OK, found->second->AsJSON()); } };
void MetaCDNReceiver::handle_delete(http_request message) { /* Use cases: 1. when CDN deletes a file from itself to store some other file because of its limited capacity JSON Format Request { "FileName": "a.txt", "CdnId" : 2 } Response: status OK or Forbidden (no json object included) */ try { int result; if(message.headers().content_type()==U("application/json")) { cout << endl << "---------------"<< endl; cout << message.to_string() << endl <<endl; json::value jsonObj = message.extract_json().get(); int cdnId = jsonObj.at(U("CdnId")).as_integer(); string fileName = utility::conversions::to_utf8string(jsonObj.at(U("FileName")).as_string()); result = m_meta->deleteCdnFromMetaEntry(fileName, cdnId); message.reply(status_codes::OK, result==0? U("Deleted successfully") : U("Delete failed")); } else { message.reply(status_codes::Forbidden, U("Json object is required")); } } catch(json::json_exception &e) { message.reply(status_codes::Forbidden, U("Invalid json object")); return; } }
// // A POST of the dealer resource creates a new table and returns a resource for // that table. // void BlackJackDealer::handle_post(http_request message) { ucout << message.to_string() << endl; auto paths = uri::split_path(uri::decode(message.relative_uri().path())); if (paths.empty()) { utility::ostringstream_t nextIdString; nextIdString << nextId; std::shared_ptr<DealerTable> tbl = std::make_shared<DealerTable>(nextId, 8, 6); s_tables[nextIdString.str()] = tbl; nextId += 1; message.reply(status_codes::OK, BJPutResponse(ST_PlaceBet, tbl->AsJSON()).AsJSON()); return; } utility::string_t wtable_id = paths[0]; const utility::string_t table_id = wtable_id; // Join an existing table. auto found = s_tables.find(table_id); if (found == s_tables.end()) { message.reply(status_codes::NotFound); return; } auto table = std::static_pointer_cast<DealerTable>(found->second); if ( table->Players.size() < table->Capacity ) { std::map<utility::string_t, utility::string_t> query = uri::split_query(uri::decode(message.request_uri().query())); auto cntEntry = query.find(QUERY_NAME); if (cntEntry != query.end() && !cntEntry->second.empty()) { table->AddPlayer(Player(cntEntry->second)); message.reply(status_codes::OK, BJPutResponse(ST_PlaceBet, table->AsJSON()).AsJSON()); } else { message.reply(status_codes::Forbidden, U("Player name is required in query")); } } else { utility::ostringstream_t os; os << U("Table ") << table->Id << U(" is full"); message.reply(status_codes::Forbidden, os.str()); } };
// // A PUT to a table resource makes a card request (hit / stay). // void BlackJackDealer::handle_put(http_request message) { ucout << message.to_string() << endl; auto paths = uri::split_path(uri::decode(message.relative_uri().path())); auto query = uri::split_query(uri::decode(message.relative_uri().query())); auto queryItr = query.find(REQUEST); if (paths.empty() || queryItr == query.end()) { message.reply(status_codes::Forbidden, U("TableId and request are required.")); } utility::string_t wtable_id = paths[0]; utility::string_t request = queryItr->second; const utility::string_t table_id = wtable_id; // Get information on a specific table. auto found = s_tables.find(table_id); if ( found == s_tables.end() ) { message.reply(status_codes::NotFound); } auto table = std::static_pointer_cast<DealerTable>(found->second); if ( request == BET ) { table->Bet(message); } else if ( request == DOUBLE ) { table->DoubleDown(message); } else if ( request == INSURE ) { table->Insure(message); } else if ( request == HIT ) { table->Hit(message); } else if ( request == STAY ) { table->Stay(message); } else if ( request == REFRESH ) { table->Wait(message); } else { message.reply(status_codes::Forbidden, U("Unrecognized request")); } };
void MetaCDNReceiver::handle_register(http_request message) { /* -when a new CDN joins, it has to register itself to Meta Server JSON Format Request { "Type": 0, //0=for cdn, 1=for fss "IP": "1.1.1.1:4000", //the sender CDN's IP address + port(listening to incoming requests) "Lat": 23.00, //the sender CDN's location "Lng": 148.12 } Response { "CdnId": 1 //the assigned id for the cdn } */ try { int assignedId = -1; if(message.headers().content_type()==U("application/json")) { cout << endl << "---------------"<< endl; cout << message.to_string() << endl <<endl; json::value jsonObj = message.extract_json().get(); if(jsonObj.at(U("Type")).as_integer() == 0) { string ipAddr = utility::conversions::to_utf8string(jsonObj.at(U("IP")).as_string()); //TODO: validate ip address Address cdnAddr(make_pair(jsonObj.at(U("Lat")).as_double(), jsonObj.at(U("Lng")).as_double()), ipAddr); assignedId = m_meta->registerCdn(cdnAddr); json::value respFinal = json::value::object(); respFinal[U("CdnId")] = json::value::number(assignedId); message.reply(assignedId!=-1? status_codes::OK : status_codes::NotFound, respFinal); } else if(jsonObj.at(U("Type")).as_integer() == 1){ string ipAddr = utility::conversions::to_utf8string(jsonObj.at(U("IP")).as_string()); //TODO: validate ip address Address fssAddr(make_pair(jsonObj.at(U("Lat")).as_double(), jsonObj.at(U("Lng")).as_double()), ipAddr); m_meta->setFssAddr(fssAddr); message.reply(status_codes::OK, "FSS registration complete"); } else { message.reply(status_codes::Forbidden, U("Invalid type")); } } else { message.reply(status_codes::Forbidden, U("Json object is required")); } } catch(json::json_exception &e) { message.reply(status_codes::Forbidden, U("Invalid json object")); return; } }
// // A DELETE of the player resource leaves the table. // void BlackJackDealer::handle_delete(http_request message) { ucout << message.to_string() << endl; auto paths = uri::split_path(uri::decode(message.relative_uri().path())); if (paths.empty()) { message.reply(status_codes::Forbidden, U("TableId is required.")); return; } utility::string_t wtable_id = paths[0]; const utility::string_t table_id = wtable_id; // Get information on a specific table. auto found = s_tables.find(table_id); if (found == s_tables.end()) { message.reply(status_codes::NotFound); return; } auto table = std::static_pointer_cast<DealerTable>(found->second); std::map<utility::string_t, utility::string_t> query = uri::split_query(uri::decode(message.request_uri().query())); auto cntEntry = query.find(QUERY_NAME); if ( cntEntry != query.end() ) { if ( table->RemovePlayer(cntEntry->second) ) { message.reply(status_codes::OK); } else { message.reply(status_codes::NotFound); } } else { message.reply(status_codes::Forbidden, U("Player name is required in query")); } };
void details::http_listener_impl::handle_trace(http_request message) { utility::string_t data = message.to_string(); message.reply(status_codes::OK, data, U("message/http")); }
void MetaCDNReceiver::handle_update(http_request message) { /* Use cases: 0. when CDN pulls a file from FSS (syncdown flow) 1. when CDN updates an existing file (syncup flow; need invalidation process) 2. when CDN creates a new file and stores in FSS and itself JSON Format Request { "Type": 0, // 0=CDN pulls a file from FSS, 1=CDN updates a file (+invalidation process), 2=CDN creates a new file and stores in FSS "FileName": "a.txt", "FileHash": "ahash", //could be empty string when Type=0 //only for type 1,2 "CdnId": 1 "TimeStamp": "12312312312" //REQUIRED for use case 1 and 2 } Response: status OK or Forbidden (no json object included) */ try { if(message.headers().content_type()==U("application/json")) { cout << endl << "---------------"<< endl; cout << message.to_string() << endl <<endl; json::value jsonObj = message.extract_json().get(); int cdnId = jsonObj.at(U("CdnId")).as_integer(); string fileName = utility::conversions::to_utf8string(jsonObj.at(U("FileName")).as_string()); int result; if(jsonObj.at(U("Type")).as_integer() == 0) { result = m_meta->addCdnToMetaEntry(fileName, cdnId); } else if(jsonObj.at(U("Type")).as_integer() == 1) { string fileHash = utility::conversions::to_utf8string(jsonObj.at(U("FileHash")).as_string()); vector<int> newCdnList; newCdnList.push_back(cdnId); result = m_meta->updateMetaEntry(fileName, fileHash, newCdnList); if(result == 0) { result = m_meta->updateTimeStamp(fileName, jsonObj.at(U("TimeStamp")).as_string()); } else { cout<<"MetaCDNReceiver::handle_update() - failed to update meta entry"<<endl; return; } //now, send invalidation msgs to other cdns unordered_map<int, Address>::const_iterator itr = m_meta->getCdnIdToAddrMap().begin(); while(itr != m_meta->getCdnIdToAddrMap().end()) { if(itr->first == cdnId) { ++itr; continue; } http_client cdn_client = http_client("http://" + itr->second.ipAddr); http_response resp = cdn_client.request(methods::DEL, "cdn/cache"+fileName).get(); if (resp.status_code() != status_codes::OK) { cout<<"MetaCDNReceiver::handle_update() - failed to send invalidation message to "+itr->second.ipAddr<<endl; } ++itr; } } else if(jsonObj.at(U("Type")).as_integer() == 2) { string fileHash = utility::conversions::to_utf8string(jsonObj.at(U("FileHash")).as_string()); vector<int> newCdnList; newCdnList.push_back(cdnId); result = m_meta->addNewMetaEntry(fileName, fileHash, newCdnList); if(result == 0) result = m_meta->addNewTimeStamp(fileName, jsonObj.at(U("TimeStamp")).as_string()); } else { message.reply(status_codes::Forbidden, U("Undefined Type")); return; } message.reply(result==0? status_codes::OK : status_codes::NotFound, result==0? U("Updated successfully") : U("Update failed")); } else { message.reply(status_codes::Forbidden, U("Json object is required")); } } catch(json::json_exception &e) { message.reply(status_codes::Forbidden, U("Invalid json object")); return; } }