Skip to content

Commit

Permalink
Prebid Server Bid Adapter: auctionId to $.id UUID to $.source.tid + m…
Browse files Browse the repository at this point in the history
…ergeDeep extPrebid (#7585)

* sourceTid

* revert unique to tid cuz easier

* deep merge extprebid

* add tests for changes

* .length duh

* test was incorrect

* no longer let this val be tid as it is not representitive

* fix test
  • Loading branch information
robertrmartinez committed Nov 2, 2021
1 parent d22b740 commit 4ae7e1b
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 17 deletions.
6 changes: 3 additions & 3 deletions modules/prebidServerBidAdapter/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ const OPEN_RTB_PROTOCOL = {
return;
}
const request = {
id: s2sBidRequest.tid,
id: firstBidRequest.auctionId,
source: {tid: s2sBidRequest.tid},
tmax: s2sConfig.timeout,
imp: imps,
Expand All @@ -751,7 +751,7 @@ const OPEN_RTB_PROTOCOL = {
}
};

// Sets pbjs version, can be overwritten below if channel exists in s2sConfig.extPrebid
// This is no longer overwritten unless name and version explicitly overwritten by extPrebid (mergeDeep)
request.ext.prebid = Object.assign(request.ext.prebid, {channel: {name: 'pbjs', version: $$PREBID_GLOBAL$$.version}})

// set debug flag if in debug mode
Expand All @@ -761,7 +761,7 @@ const OPEN_RTB_PROTOCOL = {

// s2sConfig video.ext.prebid is passed through openrtb to PBS
if (s2sConfig.extPrebid && typeof s2sConfig.extPrebid === 'object') {
request.ext.prebid = Object.assign(request.ext.prebid, s2sConfig.extPrebid);
request.ext.prebid = mergeDeep(request.ext.prebid, s2sConfig.extPrebid);
}

/**
Expand Down
22 changes: 14 additions & 8 deletions src/adapterManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,14 +262,16 @@ adapterManager.makeBidRequests = hook('sync', function (adUnits, auctionStart, a
}

let adUnitsS2SCopy = getAdUnitCopyForPrebidServer(adUnits, s2sConfig);
let tid = generateUUID();

// uniquePbsTid is so we know which server to send which bids to during the callBids function
let uniquePbsTid = generateUUID();
adaptersServerSide.forEach(bidderCode => {
const bidderRequestId = getUniqueIdentifierStr();
const bidderRequest = {
bidderCode,
auctionId,
bidderRequestId,
tid,
uniquePbsTid,
bids: hookedGetBids({bidderCode, auctionId, bidderRequestId, 'adUnits': deepClone(adUnitsS2SCopy), labels, src: CONSTANTS.S2S.SRC}),
auctionStart: auctionStart,
timeout: s2sConfig.timeout,
Expand Down Expand Up @@ -350,7 +352,7 @@ adapterManager.callBids = (adUnits, bidRequests, addBidResponse, doneCb, request
serverBidRequests.forEach(serverBidRequest => {
var index = -1;
for (var i = 0; i < uniqueServerBidRequests.length; ++i) {
if (serverBidRequest.tid === uniqueServerBidRequests[i].tid) {
if (serverBidRequest.uniquePbsTid === uniqueServerBidRequests[i].uniquePbsTid) {
index = i;
break;
}
Expand All @@ -360,7 +362,10 @@ adapterManager.callBids = (adUnits, bidRequests, addBidResponse, doneCb, request
}
});

let counter = 0
let counter = 0;

// $.source.tid MUST be a unique UUID and also THE SAME between all PBS Requests for a given Auction
const sourceTid = generateUUID();
_s2sConfigs.forEach((s2sConfig) => {
if (s2sConfig && uniqueServerBidRequests[counter] && includes(s2sConfig.bidders, uniqueServerBidRequests[counter].bidderCode)) {
// s2s should get the same client side timeout as other client side requests.
Expand All @@ -370,13 +375,13 @@ adapterManager.callBids = (adUnits, bidRequests, addBidResponse, doneCb, request
} : undefined);
let adaptersServerSide = s2sConfig.bidders;
const s2sAdapter = _bidderRegistry[s2sConfig.adapter];
let tid = uniqueServerBidRequests[counter].tid;
let uniquePbsTid = uniqueServerBidRequests[counter].uniquePbsTid;
let adUnitsS2SCopy = uniqueServerBidRequests[counter].adUnitsS2SCopy;

let uniqueServerRequests = serverBidRequests.filter(serverBidRequest => serverBidRequest.tid === tid)
let uniqueServerRequests = serverBidRequests.filter(serverBidRequest => serverBidRequest.uniquePbsTid === uniquePbsTid);

if (s2sAdapter) {
let s2sBidRequest = {tid, 'ad_units': adUnitsS2SCopy, s2sConfig};
let s2sBidRequest = {tid: sourceTid, 'ad_units': adUnitsS2SCopy, s2sConfig};
if (s2sBidRequest.ad_units.length) {
let doneCbs = uniqueServerRequests.map(bidRequest => {
bidRequest.start = timestamp();
Expand All @@ -391,7 +396,8 @@ adapterManager.callBids = (adUnits, bidRequests, addBidResponse, doneCb, request

// fire BID_REQUESTED event for each s2s bidRequest
uniqueServerRequests.forEach(bidRequest => {
events.emit(CONSTANTS.EVENTS.BID_REQUESTED, bidRequest);
// add the new sourceTid
events.emit(CONSTANTS.EVENTS.BID_REQUESTED, {...bidRequest, tid: sourceTid});
});

// make bid requests
Expand Down
21 changes: 19 additions & 2 deletions test/spec/modules/prebidServerBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,17 @@ describe('S2S Adapter', function () {
resetSyncedStatus();
});

it('should set id to auction ID and source.tid to tid', function () {
config.setConfig({ s2sConfig: CONFIG });

adapter.callBids(OUTSTREAM_VIDEO_REQUEST, BID_REQUESTS, addBidResponse, done, ajax);

const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.id).to.equal('173afb6d132ba3');
expect(requestBid.source).to.be.an('object');
expect(requestBid.source.tid).to.equal('437fbbf5-33f5-487a-8e16-a7112903cfe5');
});

it('should block request if config did not define p1Consent URL in endpoint object config', function() {
let badConfig = utils.deepClone(CONFIG);
badConfig.endpoint = { noP1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction' };
Expand Down Expand Up @@ -1705,7 +1716,7 @@ describe('S2S Adapter', function () {
expect(parsedRequestBody.ext.prebid.channel).to.deep.equal({name: 'pbjs', version: 'v$prebid.version$'});
});

it('does not set pbjs version in request if channel does exist in s2sConfig', () => {
it('extPrebid is now mergedDeep -> should include default channel as well', () => {
const s2sBidRequest = utils.deepClone(REQUEST);
const bidRequests = utils.deepClone(BID_REQUESTS);

Expand All @@ -1714,7 +1725,13 @@ describe('S2S Adapter', function () {
adapter.callBids(s2sBidRequest, bidRequests, addBidResponse, done, ajax);

const parsedRequestBody = JSON.parse(server.requests[0].requestBody);
expect(parsedRequestBody.ext.prebid.channel).to.deep.equal({test: 1});

// extPrebid is now deep merged with
expect(parsedRequestBody.ext.prebid.channel).to.deep.equal({
name: 'pbjs',
test: 1,
version: 'v$prebid.version$'
});
});

it('passes first party data in request', () => {
Expand Down
23 changes: 19 additions & 4 deletions test/spec/unit/core/adapterManager_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ describe('adapterManager tests', function () {
'bidderCode': 'appnexus',
'auctionId': '1863e370099523',
'bidderRequestId': '2946b569352ef2',
'tid': '34566b569352ef2',
'uniquePbsTid': '34566b569352ef2',
'bids': [
{
'bidder': 'appnexus',
Expand Down Expand Up @@ -479,7 +479,7 @@ describe('adapterManager tests', function () {
'bidderCode': 'appnexus',
'auctionId': '1863e370099523',
'bidderRequestId': '2946b569352ef2',
'tid': '34566b569352ef2',
'uniquePbsTid': '34566b569352ef2',
'timeout': 1000,
'src': 's2s',
'adUnitsS2SCopy': [
Expand Down Expand Up @@ -708,7 +708,7 @@ describe('adapterManager tests', function () {
'bidderCode': 'appnexus',
'auctionId': '1863e370099523',
'bidderRequestId': '2946b569352ef2',
'tid': '34566b569352ef2',
'uniquePbsTid': '34566b569352ef2',
'timeout': 1000,
'src': 's2s',
'adUnitsS2SCopy': [
Expand Down Expand Up @@ -844,7 +844,7 @@ describe('adapterManager tests', function () {
'bidderCode': 'pubmatic',
'auctionId': '1863e370099523',
'bidderRequestId': '2946b569352ef2',
'tid': '2342342342lfi23',
'uniquePbsTid': '2342342342lfi23',
'timeout': 1000,
'src': 's2s',
'adUnitsS2SCopy': [
Expand Down Expand Up @@ -1041,6 +1041,21 @@ describe('adapterManager tests', function () {
sinon.assert.calledTwice(prebidServerAdapterMock.callBids);
});

it('should have one tid for ALL s2s bidRequests', function () {
let adUnits = utils.deepClone(getAdUnits()).map(adUnit => {
adUnit.bids = adUnit.bids.filter(bid => includes(['appnexus', 'pubmatic'], bid.bidder));
return adUnit;
})
let bidRequests = adapterManager.makeBidRequests(adUnits, 1111, 2222, 1000);
adapterManager.callBids(adUnits, bidRequests, () => {}, () => {});
sinon.assert.calledTwice(prebidServerAdapterMock.callBids);
const firstBid = prebidServerAdapterMock.callBids.firstCall.args[0];
const secondBid = prebidServerAdapterMock.callBids.secondCall.args[0];

// TIDS should be the same
expect(firstBid.tid).to.equal(secondBid.tid);
});

it('should fire for simultaneous s2s and client requests', function () {
adapterManager.bidderRegistry['adequant'] = adequantAdapterMock;
let adUnits = utils.deepClone(getAdUnits()).map(adUnit => {
Expand Down

0 comments on commit 4ae7e1b

Please sign in to comment.