From 24c0df08862d8f9decc568afee8a0c371fabdce6 Mon Sep 17 00:00:00 2001 From: "ashish.shinde" Date: Fri, 12 Apr 2024 10:03:37 +0530 Subject: [PATCH 1/3] capture seatnonbids due to floors --- exchange/exchange.go | 5 + exchange/exchangetest/floors_enforcement.json | 277 ++++++++++-------- exchange/non_bid_reason.go | 2 + 3 files changed, 160 insertions(+), 124 deletions(-) diff --git a/exchange/exchange.go b/exchange/exchange.go index e688b3e0a9b..d68c0668cb1 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -399,6 +399,11 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog errs = append(errs, &errortypes.Warning{ Message: fmt.Sprintf("%s bid id %s rejected - bid price %.4f %s is less than bid floor %.4f %s for imp %s", rejectedBid.Seat, rejectedBid.Bids[0].Bid.ID, rejectedBid.Bids[0].Bid.Price, rejectedBid.Currency, rejectedBid.Bids[0].BidFloors.FloorValue, rejectedBid.Bids[0].BidFloors.FloorCurrency, rejectedBid.Bids[0].Bid.ImpID), WarningCode: errortypes.FloorBidRejectionWarningCode}) + rejectionReason := ResponseRejectedBelowFloor + if rejectedBid.Bids[0].Bid.DealID != "" { + rejectionReason = ResponseRejectedBelowDealFloor + } + seatNonBids.addBid(rejectedBid.Bids[0], int(rejectionReason), rejectedBid.Seat) } } diff --git a/exchange/exchangetest/floors_enforcement.json b/exchange/exchangetest/floors_enforcement.json index 2124bcf2aac..3cf20e51645 100644 --- a/exchange/exchangetest/floors_enforcement.json +++ b/exchange/exchangetest/floors_enforcement.json @@ -1,156 +1,185 @@ { - "floors_enabled": true, - "account_floors_enabled": true, - "incomingRequest": { - "ortbRequest": { - "id": "some-request-id", - "site": { - "page": "test.somepage.com" - }, - "imp": [ - { - "id": "my-imp-id", - "video": { - "mimes": [ - "video/mp4" - ] - }, - "ext": { - "prebid": { - "bidder": { - "appnexus": { - "placementId": 1 - }, - "audienceNetwork": { - "placementId": "some-placement" - } + "floors_enabled": true, + "account_floors_enabled": true, + "incomingRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "my-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "prebid": { + "bidder": { + "appnexus": { + "placementId": 1 + }, + "audienceNetwork": { + "placementId": "some-placement" } } } } - ], - "ext": { - "prebid": { - "floors": { - "data": { - "modelgroups": [ - { - "currency": "USD", - "modelversion": "version1", - "default": 5, - "values": { - "banner|www.website.com": 3, - "video|www.website.com": 7, - "*|*": 11 - }, - "schema": { - "fields": [ - "mediaType", - "domain" - ], - "delimiter": "|" - } + } + ], + "ext": { + "prebid": { + "floors": { + "data": { + "modelgroups": [ + { + "currency": "USD", + "modelversion": "version1", + "default": 5, + "values": { + "banner|www.website.com": 3, + "video|www.website.com": 7, + "*|*": 11 + }, + "schema": { + "fields": [ + "mediaType", + "domain" + ], + "delimiter": "|" } - ] - }, - "enabled": true, - "enforcement": { - "enforcepbs": true, - "floordeals": true, - "enforcerate": 100 - } + } + ] + }, + "enabled": true, + "enforcement": { + "enforcepbs": true, + "floordeals": true, + "enforcerate": 100 } } } } + } + }, + "outgoingRequests": { + "appnexus": { + "mockResponse": { + "pbsSeatBids": [ + { + "pbsBids": [ + { + "ortbBid": { + "id": "winning-bid1", + "impid": "my-imp-id", + "price": 12, + "w": 200, + "h": 250, + "crid": "creative-1", + "cat": [ + "IAB1-1" + ] + } + } + ], + "seat": "appnexus", + "currency": "USD" + } + ] + } }, - "outgoingRequests": { - "appnexus": { - "mockResponse": { - "pbsSeatBids": [ - { - "pbsBids": [ - { - "ortbBid": { - "id": "winning-bid1", - "impid": "my-imp-id", - "price": 12, - "w": 200, - "h": 250, - "crid": "creative-1", - "cat": [ - "IAB1-1" - ] - } + "audienceNetwork": { + "mockResponse": { + "pbsSeatBids": [ + { + "pbsBids": [ + { + "ortbBid": { + "id": "winning-bid2", + "impid": "my-imp-id", + "price": 7, + "w": 200, + "h": 250, + "crid": "creative-1", + "cat": [ + "IAB1-1" + ] } - ], - "seat": "appnexus", - "currency": "USD" - } - ] - } - }, - "audienceNetwork": { - "mockResponse": { - "pbsSeatBids": [ + } + ], + "seat": "audienceNetwork", + "currency": "USD" + } + ] + } + } + }, + "response": { + "bids": { + "id": "some-request-id", + "seatbid": [ + { + "seat": "appnexus", + "bid": [ { - "pbsBids": [ - { - "ortbBid": { - "id": "winning-bid2", - "impid": "my-imp-id", - "price": 7, - "w": 200, - "h": 250, - "crid": "creative-1", - "cat": [ - "IAB1-1" - ] + "id": "winning-bid1", + "impid": "my-imp-id", + "price": 12, + "w": 200, + "h": 250, + "crid": "creative-1", + "cat": [ + "IAB1-1" + ], + "ext": { + "origbidcpm": 12, + "prebid": { + "meta": { + "adaptercode": "appnexus" + }, + "floors": { + "floorCurrency": "USD", + "floorRule": "*|*", + "floorRuleValue": 11, + "floorValue": 11 } } - ], - "seat": "audienceNetwork", - "currency": "USD" + } } ] } - } + ] }, - "response": { - "bids": { - "id": "some-request-id", - "seatbid": [ + "ext": { + "prebid": { + "seatnonbid": [ { - "seat": "appnexus", - "bid": [ + "nonbid": [ { - "id": "winning-bid1", "impid": "my-imp-id", - "price": 12, - "w": 200, - "h": 250, - "crid": "creative-1", - "cat": [ - "IAB1-1" - ], + "statuscode": 301, "ext": { - "origbidcpm": 12, "prebid": { - "meta": { - "adaptercode": "appnexus" - }, - "floors": { - "floorCurrency": "USD", - "floorRule": "*|*", - "floorRuleValue": 11, - "floorValue": 11 + "bid": { + "price": 7, + "w": 200, + "h": 250, + "origbidcpm": 7, + "cat": [ + "IAB1-1" + ] } } } } - ] + ], + "seat": "audienceNetwork", + "ext": null } ] } } - } \ No newline at end of file + } +} \ No newline at end of file diff --git a/exchange/non_bid_reason.go b/exchange/non_bid_reason.go index 2dff2dfbcbf..fe9a8e26c48 100644 --- a/exchange/non_bid_reason.go +++ b/exchange/non_bid_reason.go @@ -8,7 +8,9 @@ type NonBidReason int const ( NoBidUnknownError NonBidReason = 0 // No Bid - General ResponseRejectedGeneral NonBidReason = 300 + ResponseRejectedBelowFloor NonBidReason = 301 // Response Rejected - Below Floor ResponseRejectedCategoryMappingInvalid NonBidReason = 303 // Response Rejected - Category Mapping Invalid + ResponseRejectedBelowDealFloor NonBidReason = 304 // Response Rejected - Bid was Below Deal Floor ResponseRejectedCreativeSizeNotAllowed NonBidReason = 351 // Response Rejected - Invalid Creative (Size Not Allowed) ResponseRejectedCreativeNotSecure NonBidReason = 352 // Response Rejected - Invalid Creative (Not Secure) ) From f4e026b6a5803bad8cf56ea882a1f001d4f48210 Mon Sep 17 00:00:00 2001 From: "ashish.shinde" Date: Fri, 12 Apr 2024 10:53:35 +0530 Subject: [PATCH 2/3] correct json file formating --- exchange/exchangetest/floors_enforcement.json | 278 +++++++++--------- 1 file changed, 139 insertions(+), 139 deletions(-) diff --git a/exchange/exchangetest/floors_enforcement.json b/exchange/exchangetest/floors_enforcement.json index 3cf20e51645..f1495e7c654 100644 --- a/exchange/exchangetest/floors_enforcement.json +++ b/exchange/exchangetest/floors_enforcement.json @@ -1,161 +1,161 @@ { - "floors_enabled": true, - "account_floors_enabled": true, - "incomingRequest": { - "ortbRequest": { - "id": "some-request-id", - "site": { - "page": "test.somepage.com" - }, - "imp": [ - { - "id": "my-imp-id", - "video": { - "mimes": [ - "video/mp4" - ] - }, - "ext": { - "prebid": { - "bidder": { - "appnexus": { - "placementId": 1 - }, - "audienceNetwork": { - "placementId": "some-placement" + "floors_enabled": true, + "account_floors_enabled": true, + "incomingRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "my-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "prebid": { + "bidder": { + "appnexus": { + "placementId": 1 + }, + "audienceNetwork": { + "placementId": "some-placement" + } } } } } - } - ], - "ext": { - "prebid": { - "floors": { - "data": { - "modelgroups": [ - { - "currency": "USD", - "modelversion": "version1", - "default": 5, - "values": { - "banner|www.website.com": 3, - "video|www.website.com": 7, - "*|*": 11 - }, - "schema": { - "fields": [ - "mediaType", - "domain" - ], - "delimiter": "|" + ], + "ext": { + "prebid": { + "floors": { + "data": { + "modelgroups": [ + { + "currency": "USD", + "modelversion": "version1", + "default": 5, + "values": { + "banner|www.website.com": 3, + "video|www.website.com": 7, + "*|*": 11 + }, + "schema": { + "fields": [ + "mediaType", + "domain" + ], + "delimiter": "|" + } } - } - ] - }, - "enabled": true, - "enforcement": { - "enforcepbs": true, - "floordeals": true, - "enforcerate": 100 + ] + }, + "enabled": true, + "enforcement": { + "enforcepbs": true, + "floordeals": true, + "enforcerate": 100 + } } } } } - } - }, - "outgoingRequests": { - "appnexus": { - "mockResponse": { - "pbsSeatBids": [ - { - "pbsBids": [ - { - "ortbBid": { - "id": "winning-bid1", - "impid": "my-imp-id", - "price": 12, - "w": 200, - "h": 250, - "crid": "creative-1", - "cat": [ - "IAB1-1" - ] - } - } - ], - "seat": "appnexus", - "currency": "USD" - } - ] - } }, - "audienceNetwork": { - "mockResponse": { - "pbsSeatBids": [ - { - "pbsBids": [ - { - "ortbBid": { - "id": "winning-bid2", - "impid": "my-imp-id", - "price": 7, - "w": 200, - "h": 250, - "crid": "creative-1", - "cat": [ - "IAB1-1" - ] - } - } - ], - "seat": "audienceNetwork", - "currency": "USD" - } - ] - } - } - }, - "response": { - "bids": { - "id": "some-request-id", - "seatbid": [ - { - "seat": "appnexus", - "bid": [ + "outgoingRequests": { + "appnexus": { + "mockResponse": { + "pbsSeatBids": [ { - "id": "winning-bid1", - "impid": "my-imp-id", - "price": 12, - "w": 200, - "h": 250, - "crid": "creative-1", - "cat": [ - "IAB1-1" + "pbsBids": [ + { + "ortbBid": { + "id": "winning-bid1", + "impid": "my-imp-id", + "price": 12, + "w": 200, + "h": 250, + "crid": "creative-1", + "cat": [ + "IAB1-1" + ] + } + } ], - "ext": { - "origbidcpm": 12, - "prebid": { - "meta": { - "adaptercode": "appnexus" - }, - "floors": { - "floorCurrency": "USD", - "floorRule": "*|*", - "floorRuleValue": 11, - "floorValue": 11 + "seat": "appnexus", + "currency": "USD" + } + ] + } + }, + "audienceNetwork": { + "mockResponse": { + "pbsSeatBids": [ + { + "pbsBids": [ + { + "ortbBid": { + "id": "winning-bid2", + "impid": "my-imp-id", + "price": 7, + "w": 200, + "h": 250, + "crid": "creative-1", + "cat": [ + "IAB1-1" + ] } } - } + ], + "seat": "audienceNetwork", + "currency": "USD" } ] } - ] + } }, - "ext": { - "prebid": { - "seatnonbid": [ + "response": { + "bids": { + "id": "some-request-id", + "seatbid": [ { + "seat": "appnexus", + "bid": [ + { + "id": "winning-bid1", + "impid": "my-imp-id", + "price": 12, + "w": 200, + "h": 250, + "crid": "creative-1", + "cat": [ + "IAB1-1" + ], + "ext": { + "origbidcpm": 12, + "prebid": { + "meta": { + "adaptercode": "appnexus" + }, + "floors": { + "floorCurrency": "USD", + "floorRule": "*|*", + "floorRuleValue": 11, + "floorValue": 11 + } + } + } + } + ] + } + ] + }, + "ext": { + "prebid": { + "seatnonbid": [ + { "nonbid": [ { "impid": "my-imp-id", @@ -180,6 +180,6 @@ } ] } + } } } -} \ No newline at end of file From 345ea63e6b31f416da5157bd487efbf2b2f72421 Mon Sep 17 00:00:00 2001 From: "ashish.shinde" Date: Thu, 18 Apr 2024 20:22:41 +0530 Subject: [PATCH 3/3] add json unit test cases --- exchange/exchange_test.go | 3 +- .../exchangetest/floors_deal_enforcement.json | 147 ++++++++++++++++++ 2 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 exchange/exchangetest/floors_deal_enforcement.json diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index 87c3936f8b2..1e6db356ba7 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -2187,7 +2187,7 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) { Enabled: spec.EventsEnabled, }, DebugAllow: true, - PriceFloors: config.AccountPriceFloors{Enabled: spec.AccountFloorsEnabled}, + PriceFloors: config.AccountPriceFloors{Enabled: spec.AccountFloorsEnabled, EnforceDealFloors: spec.AccountEnforceDealFloors}, Privacy: spec.AccountPrivacy, Validations: spec.AccountConfigBidValidation, }, @@ -5493,6 +5493,7 @@ type exchangeSpec struct { HostConfigBidValidation config.Validations `json:"host_bid_validations"` AccountConfigBidValidation config.Validations `json:"account_bid_validations"` AccountFloorsEnabled bool `json:"account_floors_enabled"` + AccountEnforceDealFloors bool `json:"account_enforce_deal_floors"` FledgeEnabled bool `json:"fledge_enabled,omitempty"` MultiBid *multiBidSpec `json:"multiBid,omitempty"` Server exchangeServer `json:"server,omitempty"` diff --git a/exchange/exchangetest/floors_deal_enforcement.json b/exchange/exchangetest/floors_deal_enforcement.json new file mode 100644 index 00000000000..924fd2f7719 --- /dev/null +++ b/exchange/exchangetest/floors_deal_enforcement.json @@ -0,0 +1,147 @@ +{ + "floors_enabled": true, + "account_floors_enabled": true, + "account_enforce_deal_floors": true, + "incomingRequest": { + "ortbRequest": { + "id": "request-id", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "bidfloor": 20, + "bidfloorcur": "USD", + "ext": { + "prebid": { + "bidder": { + "appnexus": { + "placementId": 1 + }, + "pubmatic": { + "publisherId": "1234" + } + } + } + } + } + ], + "ext": { + "prebid": { + "floors": { + "enabled": true, + "enforcement": { + "floordeals": true, + "enforcerate": 100 + } + } + } + } + } + }, + "outgoingRequests": { + "appnexus": { + "mockResponse": { + "pbsSeatBids": [ + { + "pbsBids": [ + { + "ortbBid": { + "id": "apnx-bid-id", + "dealid": "apnx-deal-id", + "impid": "imp-id", + "price": 5, + "w": 200, + "h": 250, + "crid": "creative-1" + } + } + ], + "seat": "appnexus", + "currency": "USD" + } + ] + } + }, + "pubmatic": { + "mockResponse": { + "pbsSeatBids": [ + { + "pbsBids": [ + { + "ortbBid": { + "id": "pubm-bid-id", + "impid": "imp-id", + "price": 10, + "w": 200, + "h": 250, + "crid": "creative-1" + } + } + ], + "seat": "pubmatic", + "currency": "USD" + } + ] + } + } + }, + "response": { + "bids": {}, + "ext": { + "prebid": { + "seatnonbid": [ + { + "nonbid": [ + { + "impid": "imp-id", + "statuscode": 304, + "ext": { + "prebid": { + "bid": { + "price": 5, + "w": 200, + "h": 250, + "crid": "creative-1", + "origbidcpm": 5, + "dealid": "apnx-deal-id" + } + } + } + } + ], + "seat": "appnexus", + "ext": null + }, + { + "nonbid": [ + { + "impid": "imp-id", + "statuscode": 301, + "ext": { + "prebid": { + "bid": { + "price": 10, + "w": 200, + "h": 250, + "crid": "creative-1", + "origbidcpm": 10 + } + } + } + } + ], + "seat": "pubmatic", + "ext": null + } + ] + } + } + } + }