Skip to content

Commit

Permalink
AppNexus: Make Ad Pod Id Optional (prebid#1792)
Browse files Browse the repository at this point in the history
  • Loading branch information
VeronikaSolovei9 authored and shunj-nb committed Nov 8, 2022
1 parent 663663d commit e4f81de
Show file tree
Hide file tree
Showing 9 changed files with 319 additions and 17 deletions.
1 change: 1 addition & 0 deletions adapters/adapterstest/test_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ func RunJSONBidderTest(t *testing.T, rootDir string, bidder adapters.Bidder) {
runTests(t, fmt.Sprintf("%s/supplemental", rootDir), bidder, true, false, false)
runTests(t, fmt.Sprintf("%s/amp", rootDir), bidder, true, true, false)
runTests(t, fmt.Sprintf("%s/video", rootDir), bidder, false, false, true)
runTests(t, fmt.Sprintf("%s/videosupplemental", rootDir), bidder, true, false, true)
}

// runTests runs all the *.json files in a directory. If allowErrors is false, and one of the test files
Expand Down
29 changes: 20 additions & 9 deletions adapters/appnexus/appnexus.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"math/rand"
Expand Down Expand Up @@ -301,11 +302,20 @@ func (a *AppNexusAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ad
defaultDisplayManagerVer = fmt.Sprintf("%s-%s", source, version)
}
}
var adPodId *bool

for i := 0; i < len(request.Imp); i++ {
memberId, err := preprocess(&request.Imp[i], defaultDisplayManagerVer)
memberId, impAdPodId, err := preprocess(&request.Imp[i], defaultDisplayManagerVer)
if memberId != "" {
memberIds[memberId] = true
}
if adPodId == nil {
adPodId = &impAdPodId
} else if *adPodId != impAdPodId {
errs = append(errs, errors.New("generate ad pod option should be same for all pods in request"))
return nil, errs
}

// If the preprocessing failed, the server won't be able to bid on this Imp. Delete it, and note the error.
if err != nil {
errs = append(errs, err)
Expand Down Expand Up @@ -362,12 +372,13 @@ func (a *AppNexusAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ad

imps := request.Imp

// For long form requests adpod_id must be sent downstream.
// For long form requests if adpodId feature enabled, adpod_id must be sent downstream.
// Adpod id is a unique identifier for pod
// All impressions in the same pod must have the same pod id in request extension
// For this all impressions in request should belong to the same pod
// If impressions number per pod is more than maxImpsPerReq - divide those imps to several requests but keep pod id the same
if isVIDEO == 1 {
// If adpodId feature disabled and impressions number per pod is more than maxImpsPerReq - divide those imps to several requests but do not include ad pod id
if isVIDEO == 1 && *adPodId {
podImps := groupByPods(imps)

requests := make([]*adapters.RequestData, 0, len(podImps))
Expand Down Expand Up @@ -463,15 +474,15 @@ func keys(m map[string]bool) []string {
// preprocess mutates the imp to get it ready to send to appnexus.
//
// It returns the member param, if it exists, and an error if anything went wrong during the preprocessing.
func preprocess(imp *openrtb2.Imp, defaultDisplayManagerVer string) (string, error) {
func preprocess(imp *openrtb2.Imp, defaultDisplayManagerVer string) (string, bool, error) {
var bidderExt adapters.ExtImpBidder
if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
return "", err
return "", false, err
}

var appnexusExt openrtb_ext.ExtImpAppnexus
if err := json.Unmarshal(bidderExt.Bidder, &appnexusExt); err != nil {
return "", err
return "", false, err
}

// Accept legacy Appnexus parameters if we don't have modern ones
Expand All @@ -487,7 +498,7 @@ func preprocess(imp *openrtb2.Imp, defaultDisplayManagerVer string) (string, err
}

if appnexusExt.PlacementId == 0 && (appnexusExt.InvCode == "" || appnexusExt.Member == "") {
return "", &errortypes.BadInput{
return "", false, &errortypes.BadInput{
Message: "No placement or member+invcode provided",
}
}
Expand Down Expand Up @@ -529,10 +540,10 @@ func preprocess(imp *openrtb2.Imp, defaultDisplayManagerVer string) (string, err
}}
var err error
if imp.Ext, err = json.Marshal(&impExt); err != nil {
return appnexusExt.Member, err
return appnexusExt.Member, appnexusExt.AdPodId, err
}

return appnexusExt.Member, nil
return appnexusExt.Member, appnexusExt.AdPodId, nil
}

func makeKeywordStr(keywords []*openrtb_ext.ExtImpAppnexusKeyVal) string {
Expand Down
14 changes: 6 additions & 8 deletions adapters/appnexus/appnexus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func TestVideoSinglePod(t *testing.T) {
req.ID = "test_id"

reqExt := `{"prebid":{}}`
impExt := `{"bidder":{"placementId":123}}`
impExt := `{"bidder":{"placementId":123, "generate_ad_pod_id":true}}`
req.Ext = []byte(reqExt)

req.Imp = append(req.Imp, openrtb2.Imp{ID: "1_0", Ext: []byte(impExt)})
Expand All @@ -90,7 +90,7 @@ func TestVideoSinglePod(t *testing.T) {
error = json.Unmarshal(reqData.Ext, &reqDataExt)
assert.NoError(t, error, "Response ext unmarshalling error should be nil")

regMatch, matchErr := regexp.Match(`[0-9]19`, []byte(reqDataExt.Appnexus.AdPodId))
regMatch, matchErr := regexp.Match(`^[0-9]+$`, []byte(reqDataExt.Appnexus.AdPodId))
assert.NoError(t, matchErr, "Regex match error should be nil")
assert.True(t, regMatch, "AdPod id doesn't present in Appnexus extension or has incorrect format")
}
Expand Down Expand Up @@ -140,7 +140,7 @@ func TestVideoSinglePodManyImps(t *testing.T) {
error = json.Unmarshal(reqData1.Ext, &reqDataExt1)
assert.NoError(t, error, "Response ext unmarshalling error should be nil")

adPodId1 := reqDataExt1.Appnexus.AdPodId
assert.Equal(t, "", reqDataExt1.Appnexus.AdPodId, "AdPod id should not be present in first request")

var reqData2 *openrtb2.BidRequest
error = json.Unmarshal(res[1].Body, &reqData2)
Expand All @@ -150,9 +150,7 @@ func TestVideoSinglePodManyImps(t *testing.T) {
error = json.Unmarshal(reqData2.Ext, &reqDataExt2)
assert.NoError(t, error, "Response ext unmarshalling error should be nil")

adPodId2 := reqDataExt2.Appnexus.AdPodId

assert.Equal(t, adPodId1, adPodId2, "AdPod id is not the same for the same pod")
assert.Equal(t, "", reqDataExt2.Appnexus.AdPodId, "AdPod id should not be present in second request")
}

func TestVideoTwoPods(t *testing.T) {
Expand All @@ -167,7 +165,7 @@ func TestVideoTwoPods(t *testing.T) {
req.ID = "test_id"

reqExt := `{"prebid":{}}`
impExt := `{"bidder":{"placementId":123}}`
impExt := `{"bidder":{"placementId":123, "generate_ad_pod_id": true}}`
req.Ext = []byte(reqExt)

req.Imp = append(req.Imp, openrtb2.Imp{ID: "1_0", Ext: []byte(impExt)})
Expand Down Expand Up @@ -219,7 +217,7 @@ func TestVideoTwoPodsManyImps(t *testing.T) {
req.ID = "test_id"

reqExt := `{"prebid":{}}`
impExt := `{"bidder":{"placementId":123}}`
impExt := `{"bidder":{"placementId":123, "generate_ad_pod_id":true}}`
req.Ext = []byte(reqExt)

req.Imp = append(req.Imp, openrtb2.Imp{ID: "1_0", Ext: []byte(impExt)})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
"mockBidRequest": {
"id": "test-request-id",
"imp": [
{
"id": "1_1",
"video": {
"mimes": ["video/mp4"],
"minduration": 15,
"maxduration": 30,
"protocols": [2, 3, 5, 6, 7, 8],
"w": 940,
"h": 560
},
"ext": {
"bidder": {
"placement_id": 1
}
}
},
{
"id": "2_1",
"video": {
"mimes": ["video/mp4"],
"minduration": 15,
"maxduration": 30,
"protocols": [2, 3, 5, 6, 7, 8],
"w": 940,
"h": 560
},
"ext": {
"bidder": {
"placement_id": 1
}
}
}
]
},

"httpCalls": [
{
"expectedRequest": {
"uri": "http://ib.adnxs.com/openrtb2",
"body": {
"id": "test-request-id",
"ext": {
"appnexus": {
"hb_source": 6
},
"prebid": {}
},
"imp": [
{
"id": "1_1",
"video": {
"mimes": ["video/mp4"],
"minduration": 15,
"maxduration": 30,
"protocols": [2, 3, 5, 6, 7, 8],
"w": 940,
"h": 560
},
"ext": {
"appnexus": {
"placement_id": 1
}
}
},
{
"id": "2_1",
"video": {
"mimes": ["video/mp4"],
"minduration": 15,
"maxduration": 30,
"protocols": [2, 3, 5, 6, 7, 8],
"w": 940,
"h": 560
},
"ext": {
"appnexus": {
"placement_id": 1
}
}
}
]
}
},
"mockResponse": {
"status": 200,
"body": {}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{
"mockBidRequest": {
"id": "test-request-id",
"imp": [
{
"id": "1_1",
"video": {
"mimes": ["video/mp4"],
"minduration": 15,
"maxduration": 30,
"protocols": [2, 3, 5, 6, 7, 8],
"w": 940,
"h": 560
},
"ext": {
"bidder": {
"placement_id": 1,
"generate_ad_pod_id": true
}
}
},
{
"id": "1_2",
"video": {
"mimes": ["video/mp4"],
"minduration": 15,
"maxduration": 30,
"protocols": [2, 3, 5, 6, 7, 8],
"w": 940,
"h": 560
},
"ext": {
"bidder": {
"placement_id": 1,
"generate_ad_pod_id": true
}
}
}
]
},

"httpCalls": [
{
"expectedRequest": {
"uri": "http://ib.adnxs.com/openrtb2",
"body": {
"id": "test-request-id",
"ext": {
"appnexus": {
"adpod_id": "5577006791947779410",
"hb_source": 6
},
"prebid": {}
},
"imp": [
{
"id": "1_1",
"video": {
"mimes": ["video/mp4"],
"minduration": 15,
"maxduration": 30,
"protocols": [2, 3, 5, 6, 7, 8],
"w": 940,
"h": 560
},
"ext": {
"appnexus": {
"placement_id": 1
}
}
},
{
"id": "1_2",
"video": {
"mimes": ["video/mp4"],
"minduration": 15,
"maxduration": 30,
"protocols": [2, 3, 5, 6, 7, 8],
"w": 940,
"h": 560
},
"ext": {
"appnexus": {
"placement_id": 1
}
}
}
]
}
},
"mockResponse": {
"status": 200,
"body": {}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"mockBidRequest": {
"id": "test-request-id",
"imp": [
{
"id": "1_1",
"video": {
"mimes": ["video/mp4"],
"minduration": 15,
"maxduration": 30,
"protocols": [2, 3, 5, 6, 7, 8],
"w": 940,
"h": 560
},
"ext": {
"bidder": {
"placement_id": 1,
"generate_ad_pod_id": false
}
}
},
{
"id": "2_1",
"video": {
"mimes": ["video/mp4"],
"minduration": 15,
"maxduration": 30,
"protocols": [2, 3, 5, 6, 7, 8],
"w": 940,
"h": 560
},
"ext": {
"bidder": {
"placement_id": 1,
"generate_ad_pod_id": true
}
}
}
]
},

"expectedMakeRequestsErrors": [
{
"value": "generate ad pod option should be same for all pods in request",
"comparison": "literal"
}
]
}
Loading

0 comments on commit e4f81de

Please sign in to comment.