Skip to content

Instantly share code, notes, and snippets.

@Gocrazy
Created January 13, 2014 11:37
Show Gist options
  • Select an option

  • Save Gocrazy/8398857 to your computer and use it in GitHub Desktop.

Select an option

Save Gocrazy/8398857 to your computer and use it in GitHub Desktop.
#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