diff --git a/adapters/appnexus/appnexus.go b/adapters/appnexus/appnexus.go index 96308f026ff..d03d6803533 100644 --- a/adapters/appnexus/appnexus.go +++ b/adapters/appnexus/appnexus.go @@ -3,12 +3,10 @@ package appnexus import ( "bytes" "context" - "crypto/rand" "encoding/json" "fmt" "io/ioutil" - "math" - "math/big" + "math/rand" "net/http" "strconv" "strings" @@ -360,7 +358,6 @@ func (a *AppNexusAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *ada reqExt.Appnexus.HeaderBiddingSource = a.hbSource + isVIDEO imps := request.Imp - var err error // For long form requests adpod_id must be sent downstream. // Adpod id is a unique identifier for pod @@ -368,61 +365,46 @@ func (a *AppNexusAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *ada // 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 { - podImps := make(map[string]([]openrtb.Imp)) - //find how many pods - for _, imp := range imps { - pod := strings.Split(imp.ID, "_")[0] - podImps[pod] = append(podImps[pod], imp) - } - if len(podImps) == 1 { - //if there is only one pod, just add adpod_id to ex and process as usual - reqExt.Appnexus.AdPodId, err = generatePodId() - if err != nil { - errs = append(errs, err) - return nil, errs - } + podImps := groupByPods(imps) - } else { + requests := make([]*adapters.RequestData, 0, 0) + for _, podImps := range podImps { + reqExt.Appnexus.AdPodId = generatePodId() - resArr := make([]*adapters.RequestData, 0, 0) - for _, podImps := range podImps { - reqExt.Appnexus.AdPodId, err = generatePodId() - if err != nil { - errs = append(errs, err) - return nil, errs - } - request.Ext, err = json.Marshal(reqExt) - if err != nil { - errs = append(errs, err) - return nil, errs - } - reqs, errors := splitRequests(podImps, request, thisURI, errs) - resArr = append(resArr, reqs...) - errs = append(errs, errors...) - } - return resArr, errs + reqs, errors := splitRequests(podImps, request, reqExt, thisURI, errs) + requests = append(requests, reqs...) + errs = append(errs, errors...) } - + return requests, errs } - request.Ext, err = json.Marshal(reqExt) - if err != nil { - errs = append(errs, err) - return nil, errs - } + return splitRequests(imps, request, reqExt, thisURI, errs) +} - return splitRequests(imps, request, thisURI, errs) +func generatePodId() string { + val := rand.Int63() + return fmt.Sprint(val) } -func generatePodId() (string, error) { - val, err := rand.Int(rand.Reader, big.NewInt(int64(math.MaxInt64))) +func groupByPods(imps []openrtb.Imp) map[string]([]openrtb.Imp) { + // find number of pods in response + podImps := make(map[string][]openrtb.Imp) + for _, imp := range imps { + pod := strings.Split(imp.ID, "_")[0] + podImps[pod] = append(podImps[pod], imp) + } + return podImps +} + +func requestHelper(request *openrtb.BidRequest, requestExtension appnexusReqExt, errs []error) { + var err error + request.Ext, err = json.Marshal(requestExtension) if err != nil { - return "", err + errs = append(errs, err) } - return fmt.Sprint(val.Int64()), nil } -func splitRequests(imps []openrtb.Imp, request *openrtb.BidRequest, uri string, errs []error) ([]*adapters.RequestData, []error) { +func splitRequests(imps []openrtb.Imp, request *openrtb.BidRequest, requestExtension appnexusReqExt, uri string, errs []error) ([]*adapters.RequestData, []error) { // Initial capacity for future array of requests, memory optimization. // Let's say there are 35 impressions and limit impressions per request equals to 10. @@ -437,6 +419,8 @@ func splitRequests(imps []openrtb.Imp, request *openrtb.BidRequest, uri string, headers.Add("Content-Type", "application/json;charset=utf-8") headers.Add("Accept", "application/json") + requestHelper(request, requestExtension, errs) + for impsLeft { endInd := startInd + maxImpsPerReq diff --git a/adapters/appnexus/appnexus_test.go b/adapters/appnexus/appnexus_test.go index e0979c0b76d..a552acbf66b 100644 --- a/adapters/appnexus/appnexus_test.go +++ b/adapters/appnexus/appnexus_test.go @@ -8,6 +8,7 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "regexp" "testing" "time" @@ -58,21 +59,23 @@ func TestVideoSinglePod(t *testing.T) { req.Imp = append(req.Imp, openrtb.Imp{ID: "1_1", Ext: []byte(impExt)}) req.Imp = append(req.Imp, openrtb.Imp{ID: "1_2", Ext: []byte(impExt)}) - res, err := a.MakeRequests(&req, &reqInfo) + result, err := a.MakeRequests(&req, &reqInfo) assert.Equal(t, len(err), 0, "Errors array should be empty") - assert.Equal(t, len(res), 1, "Only one request should be returned") + assert.Equal(t, len(result), 1, "Only one request should be returned") var error error var reqData *openrtb.BidRequest - error = json.Unmarshal(res[0].Body, &reqData) - assert.Equal(t, error, nil, "Response body unmarshalling error should be nil") + error = json.Unmarshal(result[0].Body, &reqData) + assert.Nil(t, error, "Response body unmarshalling error should be nil") var reqDataExt *appnexusReqExt error = json.Unmarshal(reqData.Ext, &reqDataExt) - assert.Equal(t, error, nil, "Response ext unmarshalling error should be nil") + assert.Nil(t, error, "Response ext unmarshalling error should be nil") - assert.True(t, len(reqDataExt.Appnexus.AdPodId) > 0, "AdPod id doesn't present in Appnexus extension") + regMatch, matchErr := regexp.Match(`[0-9]19`, []byte(reqDataExt.Appnexus.AdPodId)) + assert.Nil(t, matchErr, "Regex match error should be nil") + assert.True(t, regMatch, "AdPod id doesn't present in Appnexus extension or has incorrect format") } func TestVideoSinglePodManyImps(t *testing.T) {