Created
January 13, 2014 11:37
-
-
Save Gocrazy/8398857 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "smaato_exchange_connector.h" | |
| #include "rtbkit/plugins/bid_request/openrtb_bid_request.h" | |
| #include "rtbkit/plugins/exchange/http_auction_handler.h" | |
| #include "rtbkit/core/agent_configuration/agent_config.h" | |
| #include "rtbkit/plugins/bid_request/smaato_parsing.h" | |
| #include "rtbkit/plugins/bid_request/smaato_bid_request.h" | |
| #include "openrtb/openrtb_parsing.h" | |
| #include "soa/types/json_printing.h" | |
| #include <boost/any.hpp> | |
| #include <boost/lexical_cast.hpp> | |
| #include "jml/utils/file_functions.h" | |
| using namespace std; | |
| using namespace Datacratic; | |
| namespace RTBKIT { | |
| SmaatoExchangeConnector::SmaatoExchangeConnector(ServiceBase & owner, const std::string & name) : HttpExchangeConnector(name, owner) { | |
| this->auctionResource = "/auctions"; | |
| this->auctionVerb = "POST"; | |
| } | |
| SmaatoExchangeConnector::SmaatoExchangeConnector(const std::string & name, std::shared_ptr<ServiceProxies> proxies):HttpExchangeConnector(name, proxies) { | |
| this->auctionResource = "/auctions"; | |
| this->auctionVerb = "POST"; | |
| } | |
| ExchangeConnector::ExchangeCompatibility | |
| SmaatoExchangeConnector:: | |
| getCampaignCompatibility(const AgentConfig & config, | |
| bool includeReasons) const { | |
| ExchangeCompatibility result; | |
| result.setCompatible(); | |
| auto cpinfo = std::make_shared<CampaignInfo>(); | |
| const Json::Value & pconf = config.providerConfig["smaato"]; | |
| try { | |
| cpinfo->seat = Id(pconf["seat"].asString()); | |
| if (!cpinfo->seat) | |
| result.setIncompatible("providerConfig.smaato.seat is null", | |
| includeReasons); | |
| } catch (const std::exception & exc) { | |
| result.setIncompatible | |
| (string("providerConfig.smaato.seat parsing error: ") | |
| + exc.what(), includeReasons); | |
| return result; | |
| } | |
| result.info = cpinfo; | |
| return result; | |
| } | |
| namespace { | |
| using Datacratic::jsonDecode; | |
| /** Given a configuration field, convert it to the appropriate JSON */ | |
| template<typename T> | |
| void getAttr(ExchangeConnector::ExchangeCompatibility & result, | |
| const Json::Value & config, | |
| const char * fieldName, | |
| T & field, | |
| bool includeReasons) | |
| { | |
| try { | |
| if (!config.isMember(fieldName)) { | |
| result.setIncompatible | |
| ("creative[].providerConfig.smaato." + string(fieldName) | |
| + " must be specified", includeReasons); | |
| return; | |
| } | |
| const Json::Value & val = config[fieldName]; | |
| jsonDecode(val, field); | |
| } | |
| catch (const std::exception & exc) { | |
| result.setIncompatible("creative[].providerConfig.smaato." | |
| + string(fieldName) + ": error parsing field: " | |
| + exc.what(), includeReasons); | |
| return; | |
| } | |
| } | |
| } // file scope | |
| ExchangeConnector::ExchangeCompatibility | |
| SmaatoExchangeConnector:: | |
| getCreativeCompatibility(const Creative & creative, bool includeReasons) const { | |
| ExchangeCompatibility result; | |
| result.setCompatible(); | |
| auto crinfo = std::make_shared<CreativeInfo>(); | |
| const Json::Value & pconf = creative.providerConfig["smaato"]; | |
| getAttr(result, pconf, "adm", crinfo->adm, includeReasons); | |
| getAttr(result, pconf, "nurl", crinfo->nurl, includeReasons); | |
| result.info = crinfo; | |
| return result; | |
| } | |
| /*double SmaatoExchangeConnector::getTimeAvailableMs(HttpAuctionHandler & connection, | |
| const HttpHeader & header, | |
| const std::string & payload) { | |
| static const string toFind = "\"tmax\":"; | |
| string::size_type pos = payload.find(toFind); | |
| if (pos == string::npos) { | |
| cerr << "tmax not found in request, using default value" << endl; | |
| return 100.0; | |
| } | |
| int tmax = atoi(payload.c_str() + pos + toFind.length()); | |
| return tmax; | |
| }*/ | |
| std::shared_ptr<BidRequest> SmaatoExchangeConnector::parseBidRequest(HttpAuctionHandler & connection, | |
| const HttpHeader & header, | |
| const std::string & payload) { | |
| std::shared_ptr<BidRequest> res; | |
| // Check json content-type | |
| // Check x-openrtb-version header | |
| cerr << "smaato exchange got request" << endl << header << endl << payload << endl; | |
| // Parse bid request | |
| ML::Parse_Context context("Bid Request", payload.c_str(), payload.size()); | |
| res.reset(OpenRtbBidRequestParser::parseBidRequest(context, exchangeName(), exchangeName())); | |
| cerr << res->toJson() << endl; | |
| return res; | |
| } | |
| HttpResponse SmaatoExchangeConnector::getResponse(const HttpAuctionHandler & connection, | |
| const HttpHeader & requestHeader, | |
| const Auction & auction) const | |
| { | |
| const Auction::Data * current = auction.getCurrentData(); | |
| if (current->hasError()) | |
| return getErrorResponse(connection, auction, current->error + ": " + current->details); | |
| // Check Auction Error | |
| cerr << "getResponse..." << endl; | |
| OpenRTB::BidResponse response; | |
| response.id = auction.id; | |
| //set bidid | |
| response.bidid = auction.id; | |
| std::map<Id, int> seatToBid; | |
| string en = exchangeName(); | |
| cerr << "exchangeName:" << en << endl; | |
| static Datacratic::DefaultDescription<OpenRTB::BidResponse> desc; | |
| std::ostringstream stream; | |
| for (unsigned spotNum = 0; spotNum < current->responses.size(); | |
| ++spotNum) { | |
| cerr << "spotNum" << endl; | |
| if (!current->hasValidResponse(spotNum)) | |
| continue; | |
| // Get the winning bid | |
| auto & resp = current->winningResponse(spotNum); | |
| // Find how the agent is configured. We need to copy some of the | |
| // fields into the bid. | |
| const AgentConfig * config | |
| = std::static_pointer_cast<const AgentConfig> | |
| (resp.agentConfig).get(); | |
| // Get the exchange specific data for this campaign (if it exists) | |
| bool cpinfo_ok = false; | |
| Id seat("smaato_seat"); | |
| try { | |
| auto cpinfo = config->getProviderData<CampaignInfo>(en); | |
| seat = cpinfo->seat; | |
| cpinfo_ok = true; | |
| } catch(ML::Exception& ex) {} | |
| // Put in the fixed parts from the creative | |
| int creativeIndex = resp.agentCreativeIndex; | |
| auto & creative = config->creatives.at(creativeIndex); | |
| // Get the exchange specific data for this creative (if it exists) | |
| bool crinfo_ok = false; | |
| Id adid; | |
| std::string adm; | |
| std::string nurl; | |
| try { | |
| auto crinfo = creative.getProviderData<CreativeInfo>(en); | |
| adid = crinfo->adid; | |
| adm = crinfo->adm; | |
| nurl = crinfo->nurl; | |
| crinfo_ok = true; | |
| } catch(ML::Exception& ex) { | |
| } | |
| // Find the index in the seats array | |
| int seatIndex = -1; | |
| { | |
| auto it = seatToBid.find(seat); | |
| if (it == seatToBid.end()) { | |
| seatIndex = seatToBid.size(); | |
| seatToBid[seat] = seatIndex; | |
| response.seatbid.emplace_back(); | |
| if(cpinfo_ok) response.seatbid.back().seat = seat; | |
| } | |
| else seatIndex = it->second; | |
| } | |
| // Get the seatBid object | |
| OpenRTB::SeatBid & seatBid = response.seatbid.at(seatIndex); | |
| // Add a new bid to the array | |
| seatBid.bid.emplace_back(); | |
| auto & b = seatBid.bid.back(); | |
| // Put in the variable parts | |
| b.id = Id(auction.id, auction.request->imp[0].id); | |
| b.impid = auction.request->imp[spotNum].id; | |
| b.price.val = USD_CPM(resp.price.maxPrice); | |
| if(crinfo_ok && adid != Id("")) b.adid = adid; | |
| if(crinfo_ok && !adm.empty()) b.adm = adm; | |
| if(crinfo_ok && !nurl.empty()) b.nurl = nurl; | |
| } | |
| //no bid | |
| if (seatToBid.empty()) | |
| return HttpResponse(204, "none", "{}"); | |
| StreamJsonPrintingContext context(stream); | |
| desc.printJsonTyped(&response, context); | |
| cerr << Json::parse(stream.str()); | |
| return HttpResponse(200, "application/json", stream.str()); | |
| } | |
| void | |
| SmaatoExchangeConnector:: | |
| setSeatBid(Auction const & auction, | |
| int spotNum, | |
| OpenRTB::BidResponse & response) const { | |
| } | |
| } // namespace RTBKIT | |
| namespace { | |
| using namespace RTBKIT; | |
| struct Init { | |
| Init() { | |
| ExchangeConnector::registerFactory<SmaatoExchangeConnector>(); | |
| } | |
| } init; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment